diff options
Diffstat (limited to 'src/os_win/os_fs.c')
-rw-r--r-- | src/os_win/os_fs.c | 581 |
1 files changed, 222 insertions, 359 deletions
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); } |