diff options
Diffstat (limited to 'src/os_win')
| -rw-r--r-- | src/os_win/os_dir.c | 95 | ||||
| -rw-r--r-- | src/os_win/os_dlopen.c | 1 | ||||
| -rw-r--r-- | src/os_win/os_fs.c | 581 | ||||
| -rw-r--r-- | src/os_win/os_map.c | 91 | ||||
| -rw-r--r-- | src/os_win/os_thread.c | 2 |
5 files changed, 311 insertions, 459 deletions
diff --git a/src/os_win/os_dir.c b/src/os_win/os_dir.c index 64eae60983c..6f796f6ef7d 100644 --- a/src/os_win/os_dir.c +++ b/src/os_win/os_dir.c @@ -13,34 +13,37 @@ * Get a list of files from a directory, MSVC version. */ int -__wt_win_directory_list(WT_SESSION_IMPL *session, const char *dir, - const char *prefix, uint32_t flags, char ***dirlist, u_int *countp) +__wt_win_directory_list(WT_FILE_SYSTEM *file_system, + WT_SESSION *wt_session, const char *directory, + const char *prefix, char ***dirlistp, uint32_t *countp) { HANDLE findhandle; WIN32_FIND_DATA finddata; WT_DECL_ITEM(pathbuf); WT_DECL_RET; + WT_SESSION_IMPL *session; size_t dirallocsz, pathlen; - u_int count, dirsz; - bool match; - char **entries, *path; + uint32_t count; + char *dir_copy, **entries; - *dirlist = NULL; - *countp = 0; + WT_UNUSED(file_system); - WT_RET(__wt_filename(session, dir, &path)); + session = (WT_SESSION_IMPL *)wt_session; - pathlen = strlen(path); - if (path[pathlen - 1] == '\\') - path[pathlen - 1] = '\0'; - WT_ERR(__wt_scr_alloc(session, pathlen + 3, &pathbuf)); - WT_ERR(__wt_buf_fmt(session, pathbuf, "%s\\*", path)); + *dirlistp = NULL; + *countp = 0; findhandle = INVALID_HANDLE_VALUE; dirallocsz = 0; - dirsz = 0; entries = NULL; + WT_ERR(__wt_strdup(session, directory, &dir_copy)); + pathlen = strlen(dir_copy); + if (dir_copy[pathlen - 1] == '\\') + dir_copy[pathlen - 1] = '\0'; + WT_ERR(__wt_scr_alloc(session, pathlen + 3, &pathbuf)); + WT_ERR(__wt_buf_fmt(session, pathbuf, "%s\\*", dir_copy)); + findhandle = FindFirstFileA(pathbuf->data, &finddata); if (findhandle == INVALID_HANDLE_VALUE) WT_ERR_MSG(session, __wt_getlasterror(), @@ -56,46 +59,54 @@ __wt_win_directory_list(WT_SESSION_IMPL *session, const char *dir, continue; /* The list of files is optionally filtered by a prefix. */ - match = false; if (prefix != NULL && - ((LF_ISSET(WT_DIRLIST_INCLUDE) && - WT_PREFIX_MATCH(finddata.cFileName, prefix)) || - (LF_ISSET(WT_DIRLIST_EXCLUDE) && - !WT_PREFIX_MATCH(finddata.cFileName, prefix)))) - match = true; - if (prefix == NULL || match) { - /* - * We have a file name we want to return. - */ - count++; - if (count > dirsz) { - dirsz += WT_DIR_ENTRY; - WT_ERR(__wt_realloc_def(session, - &dirallocsz, dirsz, &entries)); - } - WT_ERR(__wt_strdup(session, - finddata.cFileName, &entries[count - 1])); - } + !WT_PREFIX_MATCH(finddata.cFileName, prefix)) + continue; + + WT_ERR(__wt_realloc_def( + session, &dirallocsz, count + 1, &entries)); + WT_ERR(__wt_strdup( + session, finddata.cFileName, &entries[count])); + ++count; } while (FindNextFileA(findhandle, &finddata) != 0); - if (count > 0) - *dirlist = entries; + + *dirlistp = entries; *countp = count; err: if (findhandle != INVALID_HANDLE_VALUE) (void)FindClose(findhandle); - __wt_free(session, path); + __wt_free(session, dir_copy); __wt_scr_free(session, &pathbuf); if (ret == 0) return (0); - if (*dirlist != NULL) { - for (count = dirsz; count > 0; count--) - __wt_free(session, entries[count]); - __wt_free(session, entries); - } + WT_TRET(__wt_win_directory_list_free( + file_system, wt_session, entries, count)); WT_RET_MSG(session, ret, "%s: directory-list, prefix \"%s\"", - dir, prefix == NULL ? "" : prefix); + directory, prefix == NULL ? "" : prefix); +} + +/* + * __wt_win_directory_list_free -- + * Free memory returned by __wt_win_directory_list, Windows version. + */ +int +__wt_win_directory_list_free(WT_FILE_SYSTEM *file_system, + WT_SESSION *wt_session, char **dirlist, uint32_t count) +{ + WT_SESSION_IMPL *session; + + WT_UNUSED(file_system); + + session = (WT_SESSION_IMPL *)wt_session; + + if (dirlist != NULL) { + while (count > 0) + __wt_free(session, dirlist[--count]); + __wt_free(session, dirlist); + } + return (0); } diff --git a/src/os_win/os_dlopen.c b/src/os_win/os_dlopen.c index ce949e4ea5f..9289c8f6488 100644 --- a/src/os_win/os_dlopen.c +++ b/src/os_win/os_dlopen.c @@ -20,6 +20,7 @@ __wt_dlopen(WT_SESSION_IMPL *session, const char *path, WT_DLH **dlhp) WT_RET(__wt_calloc_one(session, &dlh)); WT_ERR(__wt_strdup(session, path, &dlh->name)); + WT_ERR(__wt_strdup(session, path == NULL ? "local" : path, &dlh->name)); /* NULL means load from the current binary */ if (path == NULL) { diff --git a/src/os_win/os_fs.c b/src/os_win/os_fs.c index 95c0ea40ce6..33e281bf8ae 100644 --- a/src/os_win/os_fs.c +++ b/src/os_win/os_fs.c @@ -9,34 +9,21 @@ #include "wt_internal.h" /* - * __win_directory_sync -- - * Flush a directory to ensure a file creation is durable. - */ -static int -__win_directory_sync(WT_SESSION_IMPL *session, const char *path) -{ - WT_UNUSED(session); - WT_UNUSED(path); - return (0); -} - -/* - * __win_file_exist -- + * __win_fs_exist -- * Return if the file exists. */ static int -__win_file_exist(WT_SESSION_IMPL *session, const char *name, bool *existp) +__win_fs_exist(WT_FILE_SYSTEM *file_system, + WT_SESSION *wt_session, const char *name, bool *existp) { WT_DECL_RET; - char *path; + WT_SESSION_IMPL *session; - WT_RET(__wt_filename(session, name, &path)); + WT_UNUSED(file_system); - ret = GetFileAttributesA(path); + session = (WT_SESSION_IMPL *)wt_session; - __wt_free(session, path); - - if (ret != INVALID_FILE_ATTRIBUTES) + if (GetFileAttributesA(name) != INVALID_FILE_ATTRIBUTES) *existp = true; else *existp = false; @@ -45,242 +32,138 @@ __win_file_exist(WT_SESSION_IMPL *session, const char *name, bool *existp) } /* - * __win_file_remove -- + * __win_fs_remove -- * Remove a file. */ static int -__win_file_remove(WT_SESSION_IMPL *session, const char *name) +__win_fs_remove( + WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, const char *name) { WT_DECL_RET; - char *path; + WT_SESSION_IMPL *session; -#ifdef HAVE_DIAGNOSTIC - if (__wt_handle_search(session, name, false, NULL, NULL)) - WT_RET_MSG(session, EINVAL, - "%s: file-remove: file has open handles", name); -#endif + WT_UNUSED(file_system); - WT_RET(__wt_filename(session, name, &path)); - name = path; + session = (WT_SESSION_IMPL *)wt_session; - if (DeleteFileA(name) == FALSE) { - ret = __wt_getlasterror(); - __wt_err(session, ret, "%s: file-remove: DeleteFileA", name); - } + if (DeleteFileA(name) == FALSE) + WT_RET_MSG(session, __wt_getlasterror(), + "%s: file-remove: DeleteFileA", name); - __wt_free(session, path); - return (ret); + return (0); } /* - * __win_file_rename -- + * __win_fs_rename -- * Rename a file. */ static int -__win_file_rename(WT_SESSION_IMPL *session, const char *from, const char *to) +__win_fs_rename(WT_FILE_SYSTEM *file_system, + WT_SESSION *wt_session, const char *from, const char *to) { WT_DECL_RET; - char *from_path, *to_path; + WT_SESSION_IMPL *session; -#ifdef HAVE_DIAGNOSTIC - if (__wt_handle_search(session, from, false, NULL, NULL)) - WT_RET_MSG(session, EINVAL, - "%s: file-rename: file has open handles", from); - if (__wt_handle_search(session, to, false, NULL, NULL)) - WT_RET_MSG(session, EINVAL, - "%s: file-rename: file has open handles", to); -#endif + WT_UNUSED(file_system); - from_path = to_path = NULL; - WT_ERR(__wt_filename(session, from, &from_path)); - from = from_path; - WT_ERR(__wt_filename(session, to, &to_path)); - to = to_path; + session = (WT_SESSION_IMPL *)wt_session; /* * Check if file exists since Windows does not override the file if * it exists. */ if (GetFileAttributesA(to) != INVALID_FILE_ATTRIBUTES) - if (DeleteFileA(to) == FALSE) { - ret = __wt_getlasterror(); - __wt_err(session, ret, + if (DeleteFileA(to) == FALSE) + WT_RET_MSG(session, __wt_getlasterror(), "%s to %s: file-rename: rename", from, to); - } - if (ret == 0 && MoveFileA(from, to) == FALSE) { - ret = __wt_getlasterror(); - __wt_err(session, ret, + if (MoveFileA(from, to) == FALSE) + WT_RET_MSG(session, __wt_getlasterror(), "%s to %s: file-rename: rename", from, to); - } -err: __wt_free(session, from_path); - __wt_free(session, to_path); - return (ret); + return (0); } /* - * __win_file_size -- + * __wt_win_fs_size -- * Get the size of a file in bytes, by file name. */ -static int -__win_file_size( - WT_SESSION_IMPL *session, const char *name, bool silent, wt_off_t *sizep) +int +__wt_win_fs_size(WT_FILE_SYSTEM *file_system, + WT_SESSION *wt_session, const char *name, wt_off_t *sizep) { WIN32_FILE_ATTRIBUTE_DATA data; - WT_DECL_RET; - char *path; + WT_SESSION_IMPL *session; - WT_RET(__wt_filename(session, name, &path)); + WT_UNUSED(file_system); - ret = GetFileAttributesExA(path, GetFileExInfoStandard, &data); + session = (WT_SESSION_IMPL *)wt_session; - __wt_free(session, path); - - if (ret != 0) { + if (GetFileAttributesExA(name, GetFileExInfoStandard, &data) != 0) { *sizep = ((int64_t)data.nFileSizeHigh << 32) | data.nFileSizeLow; return (0); } - /* - * Some callers of this function expect failure if the file doesn't - * exist, and don't want an error message logged. - */ - ret = __wt_getlasterror(); - if (!silent) - WT_RET_MSG(session, ret, - "%s: file-size: GetFileAttributesEx", name); - return (ret); + WT_RET_MSG(session, __wt_getlasterror(), + "%s: file-size: GetFileAttributesEx", name); } /* - * __win_handle_advise -- - * MSVC fadvise. + * __win_file_close -- + * ANSI C close. */ static int -__win_handle_advise(WT_SESSION_IMPL *session, - WT_FH *fh, wt_off_t offset, wt_off_t len, int advice) +__win_file_close(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session) { - WT_UNUSED(session); - WT_UNUSED(fh); - WT_UNUSED(offset); - WT_UNUSED(len); - WT_UNUSED(advice); - - /* Quietly fail, callers expect not-supported failures. */ - return (ENOTSUP); -} + WT_DECL_RET; + WT_FILE_HANDLE_WIN *win_fh; + WT_SESSION_IMPL *session; -/* - * __win_handle_allocate_configure -- - * Configure fallocate behavior for a file handle. - */ -static void -__win_handle_allocate_configure(WT_SESSION_IMPL *session, WT_FH *fh) -{ - WT_UNUSED(session); + win_fh = (WT_FILE_HANDLE_WIN *)file_handle; + session = (WT_SESSION_IMPL *)wt_session; /* - * fallocate on Windows would be implemented using SetEndOfFile, which - * can also truncate the file. WiredTiger expects fallocate to ignore - * requests to truncate the file which Windows does not do, so we don't - * support the call. + * Close the primary and secondary handles. + * + * We don't open Windows system handles when opening directories for + * flushing, as it's not necessary (or possible) to flush a directory + * on Windows. Confirm the file handle is open before closing it. */ - fh->fallocate_available = WT_FALLOCATE_NOT_AVAILABLE; - fh->fallocate_requires_locking = false; -} - -/* - * __win_handle_allocate -- - * Allocate space for a file handle. - */ -static int -__win_handle_allocate( - WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t offset, wt_off_t len) -{ - WT_UNUSED(session); - WT_UNUSED(fh); - WT_UNUSED(offset); - WT_UNUSED(len); - - WT_RET_MSG(session, ENOTSUP, "%s: handle-allocate", fh->name); - return (ENOTSUP); -} - -/* - * __win_handle_close -- - * Close a file handle. - */ -static int -__win_handle_close(WT_SESSION_IMPL *session, WT_FH *fh) -{ - WT_DECL_RET; - - if (fh->filehandle != INVALID_HANDLE_VALUE) { - /* - * We don't open Windows system handles when opening directories - * for flushing, as it is not necessary (or possible) to flush - * a directory on Windows. Confirm the file handle is set before - * attempting to close it. - */ - if (CloseHandle(fh->filehandle) == 0) { - ret = __wt_getlasterror(); - __wt_err(session, ret, - "%s: handle-close: CloseHandle", fh->name); - } - } - if (fh->fp != NULL) { - /* If the stream was opened for writing, flush the file. */ - if (F_ISSET(fh, WT_FH_FLUSH_ON_CLOSE) && fflush(fh->fp) != 0) { - ret = __wt_errno(); - __wt_err(session, - ret, "%s: handle-close: fflush", fh->name); - } - - /* Close the file, closing all the underlying handles. */ - if (fclose(fh->fp) != 0) { - ret = __wt_errno(); - __wt_err(session, - ret, "%s: handle-close: fclose", fh->name); - } + if (win_fh->filehandle != INVALID_HANDLE_VALUE && + CloseHandle(win_fh->filehandle) == 0) { + ret = __wt_getlasterror(); + __wt_err(session, ret, + "%s: handle-close: CloseHandle", file_handle->name); } - /* Close the secondary handle. */ - if (fh->filehandle_secondary != INVALID_HANDLE_VALUE && - CloseHandle(fh->filehandle_secondary) == 0) { + if (win_fh->filehandle_secondary != INVALID_HANDLE_VALUE && + CloseHandle(win_fh->filehandle_secondary) == 0) { ret = __wt_getlasterror(); __wt_err(session, ret, - "%s: handle-close: secondary: CloseHandle", fh->name); + "%s: handle-close: secondary: CloseHandle", + file_handle->name); } - return (ret); -} -/* - * __win_handle_getc -- - * ANSI C fgetc. - */ -static int -__win_handle_getc(WT_SESSION_IMPL *session, WT_FH *fh, int *chp) -{ - if (fh->fp == NULL) - WT_RET_MSG(session, - ENOTSUP, "%s: handle-getc: no stream configured", fh->name); - - *chp = fgetc(fh->fp); - if (*chp != EOF || !ferror(fh->fp)) - return (0); - WT_RET_MSG(session, __wt_errno(), "%s: handle-getc: fgetc", fh->name); + __wt_free(session, file_handle->name); + __wt_free(session, win_fh); + return (ret); } /* - * __win_handle_lock -- + * __win_file_lock -- * Lock/unlock a file. */ static int -__win_handle_lock(WT_SESSION_IMPL *session, WT_FH *fh, bool lock) +__win_file_lock( + WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, bool lock) { WT_DECL_RET; + WT_FILE_HANDLE_WIN *win_fh; + WT_SESSION_IMPL *session; + + win_fh = (WT_FILE_HANDLE_WIN *)file_handle; + session = (WT_SESSION_IMPL *)wt_session; /* * WiredTiger requires this function be able to acquire locks past @@ -298,54 +181,42 @@ __win_handle_lock(WT_SESSION_IMPL *session, WT_FH *fh, bool lock) * This is useful to coordinate adding records to the end of a file. */ if (lock) { - if (LockFile(fh->filehandle, 0, 0, 1, 0) == FALSE) { + if (LockFile(win_fh->filehandle, 0, 0, 1, 0) == FALSE) { ret = __wt_getlasterror(); __wt_err(session, ret, - "%s: handle-lock: LockFile", fh->name); + "%s: handle-lock: LockFile", file_handle->name); } } else - if (UnlockFile(fh->filehandle, 0, 0, 1, 0) == FALSE) { + if (UnlockFile(win_fh->filehandle, 0, 0, 1, 0) == FALSE) { ret = __wt_getlasterror(); __wt_err(session, ret, - "%s: handle-lock: UnlockFile", fh->name); + "%s: handle-lock: UnlockFile", file_handle->name); } return (ret); } /* - * __win_handle_printf -- - * ANSI C vfprintf. - */ -static int -__win_handle_printf( - WT_SESSION_IMPL *session, WT_FH *fh, const char *fmt, va_list ap) -{ - if (fh->fp == NULL) - WT_RET_MSG(session, ENOTSUP, - "%s: vfprintf: no stream configured", fh->name); - - if (vfprintf(fh->fp, fmt, ap) >= 0) - return (0); - WT_RET_MSG(session, EIO, "%s: handle-printf: vfprintf", fh->name); -} - -/* - * __win_handle_read -- + * __win_file_read -- * Read a chunk. */ static int -__win_handle_read( - WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t offset, size_t len, void *buf) +__win_file_read(WT_FILE_HANDLE *file_handle, + WT_SESSION *wt_session, wt_off_t offset, size_t len, void *buf) { DWORD chunk, nr; uint8_t *addr; OVERLAPPED overlapped = { 0 }; + WT_FILE_HANDLE_WIN *win_fh; + WT_SESSION_IMPL *session; + + win_fh = (WT_FILE_HANDLE_WIN *)file_handle; + session = (WT_SESSION_IMPL *)wt_session; nr = 0; /* Assert direct I/O is aligned and a multiple of the alignment. */ WT_ASSERT(session, - !fh->direct_io || + !win_fh->direct_io || S2C(session)->buffer_alignment == 0 || (!((uintptr_t)buf & (uintptr_t)(S2C(session)->buffer_alignment - 1)) && @@ -358,44 +229,54 @@ __win_handle_read( overlapped.Offset = UINT32_MAX & offset; overlapped.OffsetHigh = UINT32_MAX & (offset >> 32); - if (!ReadFile(fh->filehandle, addr, chunk, &nr, &overlapped)) + if (!ReadFile( + win_fh->filehandle, addr, chunk, &nr, &overlapped)) WT_RET_MSG(session, - nr == 0 ? WT_ERROR : __wt_getlasterror(), + __wt_getlasterror(), "%s: handle-read: ReadFile: failed to read %lu " "bytes at offset %" PRIuMAX, - fh->name, chunk, (uintmax_t)offset); + file_handle->name, chunk, (uintmax_t)offset); } return (0); } /* - * __win_handle_size -- + * __win_file_size -- * Get the size of a file in bytes, by file handle. */ static int -__win_handle_size(WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t *sizep) +__win_file_size( + WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, wt_off_t *sizep) { + WT_FILE_HANDLE_WIN *win_fh; + WT_SESSION_IMPL *session; LARGE_INTEGER size; - if (GetFileSizeEx(fh->filehandle, &size) != 0) { + win_fh = (WT_FILE_HANDLE_WIN *)file_handle; + session = (WT_SESSION_IMPL *)wt_session; + + if (GetFileSizeEx(win_fh->filehandle, &size) != 0) { *sizep = size.QuadPart; return (0); } - WT_RET_MSG(session, - __wt_getlasterror(), "%s: handle-size: GetFileSizeEx", fh->name); + WT_RET_MSG(session, __wt_getlasterror(), + "%s: handle-size: GetFileSizeEx", file_handle->name); } /* - * __win_handle_sync -- - * MSVC fflush/fsync. + * __win_file_sync -- + * MSVC fsync. */ static int -__win_handle_sync(WT_SESSION_IMPL *session, WT_FH *fh, bool block) +__win_file_sync(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session) { WT_DECL_RET; + WT_FILE_HANDLE_WIN *win_fh; + WT_SESSION_IMPL *session; - WT_ASSERT(session, !F_ISSET(S2C(session), WT_CONN_READONLY)); + win_fh = (WT_FILE_HANDLE_WIN *)file_handle; + session = (WT_SESSION_IMPL *)wt_session; /* * We don't open Windows system handles when opening directories @@ -403,76 +284,79 @@ __win_handle_sync(WT_SESSION_IMPL *session, WT_FH *fh, bool block) * a directory on Windows. Confirm the file handle is set before * attempting to sync it. */ - if (fh->fp == NULL && fh->filehandle == INVALID_HANDLE_VALUE) + if (win_fh->filehandle == INVALID_HANDLE_VALUE) return (0); - if (fh->fp == NULL) { - /* - * Callers attempting asynchronous flush handle ENOTSUP returns, - * and won't make further attempts. - */ - if (!block) - return (ENOTSUP); - - if ((ret = FlushFileBuffers(fh->filehandle)) == FALSE) - WT_RET_MSG(session, __wt_getlasterror(), - "%s handle-sync: FlushFileBuffers error", fh->name); - return (0); + if (FlushFileBuffers(win_fh->filehandle) == FALSE) { + ret = __wt_getlasterror(); + WT_RET_MSG(session, ret, + "%s handle-sync: FlushFileBuffers error", + file_handle->name); } - - if (fflush(fh->fp) == 0) - return (0); - WT_RET_MSG(session, __wt_errno(), "%s: handle-sync: fflush", fh->name); + return (0); } /* - * __win_handle_truncate -- + * __win_file_truncate -- * Truncate a file. */ static int -__win_handle_truncate(WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t len) +__win_file_truncate( + WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, wt_off_t len) { WT_DECL_RET; + WT_FILE_HANDLE_WIN *win_fh; + WT_SESSION_IMPL *session; LARGE_INTEGER largeint; + win_fh = (WT_FILE_HANDLE_WIN *)file_handle; + session = (WT_SESSION_IMPL *)wt_session; + largeint.QuadPart = len; - if (fh->filehandle_secondary == INVALID_HANDLE_VALUE) + if (win_fh->filehandle_secondary == INVALID_HANDLE_VALUE) WT_RET_MSG(session, EINVAL, - "%s: handle-truncate: read-only", fh->name); + "%s: handle-truncate: read-only", file_handle->name); if (SetFilePointerEx( - fh->filehandle_secondary, largeint, NULL, FILE_BEGIN) == FALSE) + win_fh->filehandle_secondary, largeint, NULL, FILE_BEGIN) == FALSE) WT_RET_MSG(session, __wt_getlasterror(), - "%s: handle-truncate: SetFilePointerEx", fh->name); + "%s: handle-truncate: SetFilePointerEx", + file_handle->name); - if (SetEndOfFile(fh->filehandle_secondary) == FALSE) { + if (SetEndOfFile(win_fh->filehandle_secondary) == FALSE) { if (GetLastError() == ERROR_USER_MAPPED_FILE) return (EBUSY); WT_RET_MSG(session, __wt_getlasterror(), - "%s: handle-truncate: SetEndOfFile error", fh->name); + "%s: handle-truncate: SetEndOfFile error", + file_handle->name); } return (0); } /* - * __win_handle_write -- + * __win_file_write -- * Write a chunk. */ static int -__win_handle_write(WT_SESSION_IMPL *session, - WT_FH *fh, wt_off_t offset, size_t len, const void *buf) +__win_file_write(WT_FILE_HANDLE *file_handle, + WT_SESSION *wt_session, wt_off_t offset, size_t len, const void *buf) { DWORD chunk; DWORD nw; const uint8_t *addr; OVERLAPPED overlapped = { 0 }; + WT_FILE_HANDLE_WIN *win_fh; + WT_SESSION_IMPL *session; + + win_fh = (WT_FILE_HANDLE_WIN *)file_handle; + session = (WT_SESSION_IMPL *)wt_session; nw = 0; /* Assert direct I/O is aligned and a multiple of the alignment. */ WT_ASSERT(session, - !fh->direct_io || + !win_fh->direct_io || S2C(session)->buffer_alignment == 0 || (!((uintptr_t)buf & (uintptr_t)(S2C(session)->buffer_alignment - 1)) && @@ -485,38 +369,47 @@ __win_handle_write(WT_SESSION_IMPL *session, overlapped.Offset = UINT32_MAX & offset; overlapped.OffsetHigh = UINT32_MAX & (offset >> 32); - if (!WriteFile(fh->filehandle, addr, chunk, &nw, &overlapped)) + if (!WriteFile( + win_fh->filehandle, addr, chunk, &nw, &overlapped)) WT_RET_MSG(session, __wt_getlasterror(), "%s: handle-write: WriteFile: failed to write %lu " "bytes at offset %" PRIuMAX, - fh->name, chunk, (uintmax_t)offset); + file_handle->name, chunk, (uintmax_t)offset); } return (0); } /* - * __win_handle_open -- + * __win_open_file -- * Open a file handle. */ static int -__win_handle_open(WT_SESSION_IMPL *session, - WT_FH *fh, const char *name, uint32_t file_type, uint32_t flags) +__win_open_file(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, + const char *name, WT_OPEN_FILE_TYPE file_type, uint32_t flags, + WT_FILE_HANDLE **file_handlep) { DWORD dwCreationDisposition; - HANDLE filehandle, filehandle_secondary; WT_CONNECTION_IMPL *conn; WT_DECL_RET; + WT_FILE_HANDLE *file_handle; + WT_FILE_HANDLE_WIN *win_fh; + WT_SESSION_IMPL *session; int desired_access, f; - bool direct_io; - const char *stream_mode; + WT_UNUSED(file_system); + + *file_handlep = NULL; + + session = (WT_SESSION_IMPL *)wt_session; conn = S2C(session); - direct_io = false; + + WT_RET(__wt_calloc_one(session, &win_fh)); + + win_fh->direct_io = false; /* Set up error handling. */ - fh->filehandle = fh->filehandle_secondary = - filehandle = filehandle_secondary = INVALID_HANDLE_VALUE; - fh->fp = NULL; + win_fh->filehandle = + win_fh->filehandle_secondary = INVALID_HANDLE_VALUE; /* * Opening a file handle on a directory is only to support filesystems @@ -524,7 +417,7 @@ __win_handle_open(WT_SESSION_IMPL *session, * require that functionality: create an empty WT_FH structure with * invalid handles. */ - if (file_type == WT_FILE_TYPE_DIRECTORY) + if (file_type == WT_OPEN_FILE_TYPE_DIRECTORY) goto directory_open; desired_access = GENERIC_READ; @@ -549,43 +442,36 @@ __win_handle_open(WT_SESSION_IMPL *session, } else dwCreationDisposition = OPEN_EXISTING; - /* - * direct_io means no OS file caching. This requires aligned buffer - * allocations like O_DIRECT. - */ - if (FLD_ISSET(conn->direct_io, file_type) || - (LF_ISSET(WT_OPEN_READONLY) && - file_type == WT_FILE_TYPE_DATA && - FLD_ISSET(conn->direct_io, WT_FILE_TYPE_CHECKPOINT))) { + /* Direct I/O. */ + if (LF_ISSET(WT_OPEN_DIRECTIO)) { f |= FILE_FLAG_NO_BUFFERING; - direct_io = true; + win_fh->direct_io = true; } - fh->direct_io = direct_io; /* FILE_FLAG_WRITE_THROUGH does not require aligned buffers */ if (FLD_ISSET(conn->write_through, file_type)) f |= FILE_FLAG_WRITE_THROUGH; - if (file_type == WT_FILE_TYPE_LOG && + if (file_type == WT_OPEN_FILE_TYPE_LOG && FLD_ISSET(conn->txn_logsync, WT_LOG_DSYNC)) f |= FILE_FLAG_WRITE_THROUGH; /* Disable read-ahead on trees: it slows down random read workloads. */ - if (file_type == WT_FILE_TYPE_DATA) + if (file_type == WT_OPEN_FILE_TYPE_DATA) f |= FILE_FLAG_RANDOM_ACCESS; - filehandle = CreateFileA(name, desired_access, + win_fh->filehandle = CreateFileA(name, desired_access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, dwCreationDisposition, f, NULL); - if (filehandle == INVALID_HANDLE_VALUE) { + if (win_fh->filehandle == INVALID_HANDLE_VALUE) { if (LF_ISSET(WT_OPEN_CREATE) && GetLastError() == ERROR_FILE_EXISTS) - filehandle = CreateFileA(name, desired_access, + win_fh->filehandle = CreateFileA(name, desired_access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, f, NULL); - if (filehandle == INVALID_HANDLE_VALUE) + if (win_fh->filehandle == INVALID_HANDLE_VALUE) WT_ERR_MSG(session, __wt_getlasterror(), - direct_io ? + win_fh->direct_io ? "%s: handle-open: CreateFileA: failed with direct " "I/O configured, some filesystem types do not " "support direct I/O" : @@ -598,78 +484,60 @@ __win_handle_open(WT_SESSION_IMPL *session, * pointer. */ if (!LF_ISSET(WT_OPEN_READONLY)) { - filehandle_secondary = CreateFileA(name, desired_access, + win_fh->filehandle_secondary = CreateFileA(name, desired_access, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, f, NULL); - if (filehandle_secondary == INVALID_HANDLE_VALUE) + if (win_fh->filehandle_secondary == INVALID_HANDLE_VALUE) WT_ERR_MSG(session, __wt_getlasterror(), "%s: handle-open: CreateFileA: secondary", name); } - /* Optionally configure a stdio stream API. */ - switch (LF_MASK(WT_STREAM_APPEND | WT_STREAM_READ | WT_STREAM_WRITE)) { - case WT_STREAM_APPEND: - f = _O_APPEND | _O_TEXT; - stream_mode = "a"; - F_SET(fh, WT_FH_FLUSH_ON_CLOSE); - break; - case WT_STREAM_READ: - f = _O_RDONLY | _O_TEXT; - stream_mode = "r"; - break; - case WT_STREAM_WRITE: - f = _O_TEXT; - stream_mode = "w"; - F_SET(fh, WT_FH_FLUSH_ON_CLOSE); - break; - case 0: - default: - stream_mode = NULL; - break; - } - if (stream_mode != NULL) { - if ((fh->fp = fopen(name, stream_mode)) == NULL) - WT_ERR_MSG(session, __wt_errno(), - "%s: handle-open: fopen", name); - - if (LF_ISSET(WT_STREAM_LINE_BUFFER)) - __wt_stream_set_line_buffer(fh->fp); - } +directory_open: + /* Initialize public information. */ + file_handle = (WT_FILE_HANDLE *)win_fh; + WT_ERR(__wt_strdup(session, name, &file_handle->name)); - /* Configure fallocate/posix_fallocate calls. */ - __win_handle_allocate_configure(session, fh); + file_handle->close = __win_file_close; + file_handle->lock = __win_file_lock; +#ifdef WORDS_BIGENDIAN + /* + * The underlying objects are little-endian, mapping objects isn't + * currently supported on big-endian systems. + */ +#else + file_handle->map = __wt_win_map; + file_handle->unmap = __wt_win_unmap; +#endif + file_handle->read = __win_file_read; + file_handle->size = __win_file_size; + file_handle->sync = __win_file_sync; + file_handle->truncate = __win_file_truncate; + file_handle->write = __win_file_write; -directory_open: - fh->filehandle = filehandle; - fh->filehandle_secondary = filehandle_secondary; - - fh->fh_advise = __win_handle_advise; - fh->fh_allocate = __win_handle_allocate; - fh->fh_close = __win_handle_close; - fh->fh_getc = __win_handle_getc; - fh->fh_lock = __win_handle_lock; - fh->fh_map = __wt_win_map; - fh->fh_map_discard = __wt_win_map_discard; - fh->fh_map_preload = __wt_win_map_preload; - fh->fh_map_unmap = __wt_win_map_unmap; - fh->fh_printf = __win_handle_printf; - fh->fh_read = __win_handle_read; - fh->fh_size = __win_handle_size; - fh->fh_sync = __win_handle_sync; - fh->fh_truncate = __win_handle_truncate; - fh->fh_write = __win_handle_write; + *file_handlep = file_handle; return (0); -err: if (filehandle != INVALID_HANDLE_VALUE) - (void)CloseHandle(filehandle); - if (filehandle_secondary != INVALID_HANDLE_VALUE) - (void)CloseHandle(filehandle_secondary); - +err: WT_TRET(__win_file_close((WT_FILE_HANDLE *)win_fh, wt_session)); return (ret); } /* + * __win_terminate -- + * Discard a Windows configuration. + */ +static int +__win_terminate(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session) +{ + WT_SESSION_IMPL *session; + + session = (WT_SESSION_IMPL *)wt_session; + + __wt_free(session, file_system); + return (0); +} + +/* * __wt_os_win -- * Initialize a MSVC configuration. */ @@ -677,29 +545,24 @@ int __wt_os_win(WT_SESSION_IMPL *session) { WT_CONNECTION_IMPL *conn; + WT_FILE_SYSTEM *file_system; conn = S2C(session); - /* Initialize the POSIX jump table. */ - conn->file_directory_list = __wt_win_directory_list; - conn->file_directory_sync = __win_directory_sync; - conn->file_exist = __win_file_exist; - conn->file_remove = __win_file_remove; - conn->file_rename = __win_file_rename; - conn->file_size = __win_file_size; - conn->handle_open = __win_handle_open; + WT_RET(__wt_calloc_one(session, &file_system)); - return (0); -} + /* Initialize the Windows jump table. */ + file_system->directory_list = __wt_win_directory_list; + file_system->directory_list_free = __wt_win_directory_list_free; + file_system->exist = __win_fs_exist; + file_system->open_file = __win_open_file; + file_system->remove = __win_fs_remove; + file_system->rename = __win_fs_rename; + file_system->size = __wt_win_fs_size; + file_system->terminate = __win_terminate; -/* - * __wt_os_win_cleanup -- - * Discard a POSIX configuration. - */ -int -__wt_os_win_cleanup(WT_SESSION_IMPL *session) -{ - WT_UNUSED(session); + /* Switch it into place. */ + conn->file_system = file_system; return (0); } diff --git a/src/os_win/os_map.c b/src/os_win/os_map.c index b043f9c9923..488cbfb2ceb 100644 --- a/src/os_win/os_map.c +++ b/src/os_win/os_map.c @@ -13,106 +13,83 @@ * Map a file into memory. */ int -__wt_win_map(WT_SESSION_IMPL *session, - WT_FH *fh, void *mapp, size_t *lenp, void **mappingcookie) +__wt_win_map(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, + void *mapped_regionp, size_t *lenp, void *mapped_cookiep) { WT_DECL_RET; + WT_FILE_HANDLE_WIN *win_fh; + WT_SESSION_IMPL *session; size_t len; wt_off_t file_size; - void *map; + void *map, *mapped_cookie; + + win_fh = (WT_FILE_HANDLE_WIN *)file_handle; + session = (WT_SESSION_IMPL *)wt_session; /* * There's no locking here to prevent the underlying file from changing * underneath us, our caller needs to ensure consistency of the mapped * region vs. any other file activity. */ - WT_RET(__wt_filesize(session, fh, &file_size)); + WT_RET(__wt_win_fs_size(file_handle->file_system, + wt_session, file_handle->name, &file_size)); len = (size_t)file_size; (void)__wt_verbose(session, WT_VERB_HANDLEOPS, - "%s: memory-map: %" WT_SIZET_FMT " bytes", fh->name, len); + "%s: memory-map: %" WT_SIZET_FMT " bytes", file_handle->name, len); - *mappingcookie = - CreateFileMappingA(fh->filehandle, NULL, PAGE_READONLY, 0, 0, NULL); - if (*mappingcookie == NULL) + mapped_cookie = CreateFileMappingA( + win_fh->filehandle, NULL, PAGE_READONLY, 0, 0, NULL); + if (mapped_cookie == NULL) WT_RET_MSG(session, __wt_getlasterror(), - "%s: memory-map: CreateFileMappingA", fh->name); + "%s: memory-map: CreateFileMappingA", file_handle->name); if ((map = - MapViewOfFile(*mappingcookie, FILE_MAP_READ, 0, 0, len)) == NULL) { + MapViewOfFile(mapped_cookie, FILE_MAP_READ, 0, 0, len)) == NULL) { /* Retrieve the error before cleaning up. */ ret = __wt_getlasterror(); - CloseHandle(*mappingcookie); - *mappingcookie = NULL; + CloseHandle(mapped_cookie); WT_RET_MSG(session, ret, - "%s: memory-map: MapViewOfFile", fh->name); + "%s: memory-map: MapViewOfFile", file_handle->name); } - *(void **)mapp = map; + *(void **)mapped_cookiep = mapped_cookie; + *(void **)mapped_regionp = map; *lenp = len; return (0); } /* - * __wt_win_map_preload -- - * Cause a section of a memory map to be faulted in. - */ -int -__wt_win_map_preload( - WT_SESSION_IMPL *session, WT_FH *fh, const void *p, size_t size) -{ - WT_UNUSED(session); - WT_UNUSED(fh); - WT_UNUSED(p); - WT_UNUSED(size); - - return (ENOTSUP); -} - -/* - * __wt_win_map_discard -- - * Discard a chunk of the memory map. - */ -int -__wt_win_map_discard(WT_SESSION_IMPL *session, WT_FH *fh, void *p, size_t size) -{ - WT_UNUSED(session); - WT_UNUSED(fh); - WT_UNUSED(p); - WT_UNUSED(size); - - return (ENOTSUP); -} - -/* - * __wt_win_map_unmap -- + * __wt_win_unmap -- * Remove a memory mapping. */ int -__wt_win_map_unmap(WT_SESSION_IMPL *session, - WT_FH *fh, void *map, size_t len, void **mappingcookie) +__wt_win_unmap(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, + void *mapped_region, size_t length, void *mapped_cookie) { WT_DECL_RET; + WT_FILE_HANDLE_WIN *win_fh; + WT_SESSION_IMPL *session; - (void)__wt_verbose(session, WT_VERB_HANDLEOPS, - "%s: memory-unmap: %" WT_SIZET_FMT " bytes", fh->name, len); + win_fh = (WT_FILE_HANDLE_WIN *)file_handle; + session = (WT_SESSION_IMPL *)wt_session; - WT_ASSERT(session, *mappingcookie != NULL); + (void)__wt_verbose(session, WT_VERB_HANDLEOPS, + "%s: memory-unmap: %" WT_SIZET_FMT " bytes", + file_handle->name, length); - if (UnmapViewOfFile(map) == 0) { + if (UnmapViewOfFile(mapped_region) == 0) { ret = __wt_getlasterror(); __wt_err(session, ret, - "%s: memory-unmap: UnmapViewOfFile", fh->name); + "%s: memory-unmap: UnmapViewOfFile", file_handle->name); } - if (CloseHandle(*mappingcookie) == 0) { + if (CloseHandle(*(void **)mapped_cookie) == 0) { ret = __wt_getlasterror(); __wt_err(session, ret, - "%s: memory-unmap: CloseHandle", fh->name); + "%s: memory-unmap: CloseHandle", file_handle->name); } - *mappingcookie = NULL; - return (ret); } diff --git a/src/os_win/os_thread.c b/src/os_win/os_thread.c index 94c5a8b0ab2..2b846216442 100644 --- a/src/os_win/os_thread.c +++ b/src/os_win/os_thread.c @@ -21,7 +21,7 @@ __wt_thread_create(WT_SESSION_IMPL *session, if (*tidret != 0) return (0); - WT_RET_MSG(session, __wt_errno, "thread create: _beginthreadex"); + WT_RET_MSG(session, __wt_errno(), "thread create: _beginthreadex"); } /* |
