summaryrefslogtreecommitdiff
path: root/src/os_posix
diff options
context:
space:
mode:
Diffstat (limited to 'src/os_posix')
-rw-r--r--src/os_posix/os_dir.c89
-rw-r--r--src/os_posix/os_dlopen.c2
-rw-r--r--src/os_posix/os_fallocate.c160
-rw-r--r--src/os_posix/os_fs.c616
-rw-r--r--src/os_posix/os_map.c118
5 files changed, 450 insertions, 535 deletions
diff --git a/src/os_posix/os_dir.c b/src/os_posix/os_dir.c
index 78ae5f8edd4..a23051e5b93 100644
--- a/src/os_posix/os_dir.c
+++ b/src/os_posix/os_dir.c
@@ -15,30 +15,33 @@
* Get a list of files from a directory, POSIX version.
*/
int
-__wt_posix_directory_list(WT_SESSION_IMPL *session, const char *dir,
- const char *prefix, uint32_t flags, char ***dirlist, u_int *countp)
+__wt_posix_directory_list(WT_FILE_SYSTEM *file_system,
+ WT_SESSION *wt_session, const char *directory,
+ const char *prefix, char ***dirlistp, uint32_t *countp)
{
struct dirent *dp;
DIR *dirp;
WT_DECL_RET;
+ WT_SESSION_IMPL *session;
size_t dirallocsz;
- u_int count, dirsz;
- bool match;
- char **entries, *path;
+ uint32_t count;
+ char **entries;
- *dirlist = NULL;
- *countp = 0;
+ WT_UNUSED(file_system);
+
+ session = (WT_SESSION_IMPL *)wt_session;
- WT_RET(__wt_filename(session, dir, &path));
+ *dirlistp = NULL;
+ *countp = 0;
dirp = NULL;
dirallocsz = 0;
- dirsz = 0;
entries = NULL;
- WT_SYSCALL_RETRY(((dirp = opendir(path)) == NULL ? 1 : 0), ret);
+ WT_SYSCALL_RETRY(((dirp = opendir(directory)) == NULL ? 1 : 0), ret);
if (ret != 0)
- WT_ERR_MSG(session, ret, "%s: directory-list: opendir", path);
+ WT_RET_MSG(session, ret,
+ "%s: directory-list: opendir", directory);
for (count = 0; (dp = readdir(dirp)) != NULL;) {
/*
@@ -49,44 +52,50 @@ __wt_posix_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(dp->d_name, prefix)) ||
- (LF_ISSET(WT_DIRLIST_EXCLUDE) &&
- !WT_PREFIX_MATCH(dp->d_name, 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, dp->d_name, &entries[count-1]));
- }
+ if (prefix != NULL && !WT_PREFIX_MATCH(dp->d_name, prefix))
+ continue;
+
+ WT_ERR(__wt_realloc_def(
+ session, &dirallocsz, count + 1, &entries));
+ WT_ERR(__wt_strdup(session, dp->d_name, &entries[count]));
+ ++count;
}
- if (count > 0)
- *dirlist = entries;
+
+ *dirlistp = entries;
*countp = count;
err: if (dirp != NULL)
(void)closedir(dirp);
- __wt_free(session, path);
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_posix_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_posix_directory_list_free --
+ * Free memory returned by __wt_posix_directory_list.
+ */
+int
+__wt_posix_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_posix/os_dlopen.c b/src/os_posix/os_dlopen.c
index 9a74eb4813d..ad1fcc90150 100644
--- a/src/os_posix/os_dlopen.c
+++ b/src/os_posix/os_dlopen.c
@@ -19,7 +19,7 @@ __wt_dlopen(WT_SESSION_IMPL *session, const char *path, WT_DLH **dlhp)
WT_DLH *dlh;
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));
if ((dlh->handle = dlopen(path, RTLD_LAZY)) == NULL)
WT_ERR_MSG(
diff --git a/src/os_posix/os_fallocate.c b/src/os_posix/os_fallocate.c
index 22879d36182..a162dbe01a1 100644
--- a/src/os_posix/os_fallocate.c
+++ b/src/os_posix/os_fallocate.c
@@ -12,47 +12,28 @@
#include <linux/falloc.h>
#include <sys/syscall.h>
#endif
-/*
- * __wt_posix_handle_allocate_configure --
- * Configure POSIX file-extension behavior for a file handle.
- */
-void
-__wt_posix_handle_allocate_configure(WT_SESSION_IMPL *session, WT_FH *fh)
-{
- WT_UNUSED(session);
-
- fh->fallocate_available = WT_FALLOCATE_NOT_AVAILABLE;
- fh->fallocate_requires_locking = false;
-
- /*
- * Check for the availability of some form of fallocate; in all cases,
- * start off requiring locking, we'll relax that requirement once we
- * know which system calls work with the handle's underlying filesystem.
- */
-#if defined(HAVE_FALLOCATE) || defined(HAVE_POSIX_FALLOCATE)
- fh->fallocate_available = WT_FALLOCATE_AVAILABLE;
- fh->fallocate_requires_locking = true;
-#endif
-#if defined(__linux__) && defined(SYS_fallocate)
- fh->fallocate_available = WT_FALLOCATE_AVAILABLE;
- fh->fallocate_requires_locking = true;
-#endif
-}
/*
* __posix_std_fallocate --
* Linux fallocate call.
*/
static int
-__posix_std_fallocate(WT_FH *fh, wt_off_t offset, wt_off_t len)
+__posix_std_fallocate(WT_FILE_HANDLE *file_handle,
+ WT_SESSION *wt_session, wt_off_t offset, wt_off_t len)
{
#if defined(HAVE_FALLOCATE)
WT_DECL_RET;
+ WT_FILE_HANDLE_POSIX *pfh;
- WT_SYSCALL_RETRY(fallocate(fh->fd, 0, offset, len), ret);
+ WT_UNUSED(wt_session);
+
+ pfh = (WT_FILE_HANDLE_POSIX *)file_handle;
+
+ WT_SYSCALL_RETRY(fallocate(pfh->fd, 0, offset, len), ret);
return (ret);
#else
- WT_UNUSED(fh);
+ WT_UNUSED(file_handle);
+ WT_UNUSED(wt_session);
WT_UNUSED(offset);
WT_UNUSED(len);
return (ENOTSUP);
@@ -64,10 +45,16 @@ __posix_std_fallocate(WT_FH *fh, wt_off_t offset, wt_off_t len)
* Linux fallocate call (system call version).
*/
static int
-__posix_sys_fallocate(WT_FH *fh, wt_off_t offset, wt_off_t len)
+__posix_sys_fallocate(WT_FILE_HANDLE *file_handle,
+ WT_SESSION *wt_session, wt_off_t offset, wt_off_t len)
{
#if defined(__linux__) && defined(SYS_fallocate)
WT_DECL_RET;
+ WT_FILE_HANDLE_POSIX *pfh;
+
+ WT_UNUSED(wt_session);
+
+ pfh = (WT_FILE_HANDLE_POSIX *)file_handle;
/*
* Try the system call for fallocate even if the C library wrapper was
@@ -75,10 +62,11 @@ __posix_sys_fallocate(WT_FH *fh, wt_off_t offset, wt_off_t len)
* Linux versions (RHEL 5.5), but not in the version of the C library.
* This allows it to work everywhere the kernel supports it.
*/
- WT_SYSCALL_RETRY(syscall(SYS_fallocate, fh->fd, 0, offset, len), ret);
+ WT_SYSCALL_RETRY(syscall(SYS_fallocate, pfh->fd, 0, offset, len), ret);
return (ret);
#else
- WT_UNUSED(fh);
+ WT_UNUSED(file_handle);
+ WT_UNUSED(wt_session);
WT_UNUSED(offset);
WT_UNUSED(len);
return (ENOTSUP);
@@ -90,15 +78,22 @@ __posix_sys_fallocate(WT_FH *fh, wt_off_t offset, wt_off_t len)
* POSIX fallocate call.
*/
static int
-__posix_posix_fallocate(WT_FH *fh, wt_off_t offset, wt_off_t len)
+__posix_posix_fallocate(WT_FILE_HANDLE *file_handle,
+ WT_SESSION *wt_session, wt_off_t offset, wt_off_t len)
{
#if defined(HAVE_POSIX_FALLOCATE)
WT_DECL_RET;
+ WT_FILE_HANDLE_POSIX *pfh;
+
+ WT_UNUSED(wt_session);
- WT_SYSCALL_RETRY(posix_fallocate(fh->fd, offset, len), ret);
+ pfh = (WT_FILE_HANDLE_POSIX *)file_handle;
+
+ WT_SYSCALL_RETRY(posix_fallocate(pfh->fd, offset, len), ret);
return (ret);
#else
- WT_UNUSED(fh);
+ WT_UNUSED(file_handle);
+ WT_UNUSED(wt_session);
WT_UNUSED(offset);
WT_UNUSED(len);
return (ENOTSUP);
@@ -106,67 +101,52 @@ __posix_posix_fallocate(WT_FH *fh, wt_off_t offset, wt_off_t len)
}
/*
- * __wt_posix_handle_allocate --
+ * __wt_posix_file_fallocate --
* POSIX fallocate.
*/
int
-__wt_posix_handle_allocate(
- WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t offset, wt_off_t len)
+__wt_posix_file_fallocate(WT_FILE_HANDLE *file_handle,
+ WT_SESSION *wt_session, wt_off_t offset, wt_off_t len)
{
- WT_DECL_RET;
-
- switch (fh->fallocate_available) {
- /*
- * Check for already configured handles and make the configured call.
- */
- case WT_FALLOCATE_POSIX:
- if ((ret = __posix_posix_fallocate(fh, offset, len)) == 0)
- return (0);
- WT_RET_MSG(session, ret, "%s: posix_fallocate", fh->name);
- case WT_FALLOCATE_STD:
- if ((ret = __posix_std_fallocate(fh, offset, len)) == 0)
- return (0);
- WT_RET_MSG(session, ret, "%s: fallocate", fh->name);
- case WT_FALLOCATE_SYS:
- if ((ret = __posix_sys_fallocate(fh, offset, len)) == 0)
- return (0);
- WT_RET_MSG(session, ret, "%s: sys_fallocate", fh->name);
-
/*
- * Figure out what allocation call this system/filesystem supports, if
- * any.
+ * The first fallocate call: figure out what fallocate call this system
+ * supports, if any.
+ *
+ * The function is configured as a locking fallocate call, so we know
+ * we're single-threaded through here. Set the nolock function first,
+ * then publish the NULL replacement to ensure the handle functions are
+ * always correct.
+ *
+ * We've seen Linux systems where posix_fallocate has corrupted
+ * existing file data (even though that is explicitly disallowed
+ * by POSIX). FreeBSD and Solaris support posix_fallocate, and
+ * so far we've seen no problems leaving it unlocked. Check for
+ * fallocate (and the system call version of fallocate) first to
+ * avoid locking on Linux if at all possible.
*/
- case WT_FALLOCATE_AVAILABLE:
- /*
- * We've seen Linux systems where posix_fallocate has corrupted
- * existing file data (even though that is explicitly disallowed
- * by POSIX). FreeBSD and Solaris support posix_fallocate, and
- * so far we've seen no problems leaving it unlocked. Check for
- * fallocate (and the system call version of fallocate) first to
- * avoid locking on Linux if at all possible.
- */
- if ((ret = __posix_std_fallocate(fh, offset, len)) == 0) {
- fh->fallocate_available = WT_FALLOCATE_STD;
- fh->fallocate_requires_locking = false;
- return (0);
- }
- if ((ret = __posix_sys_fallocate(fh, offset, len)) == 0) {
- fh->fallocate_available = WT_FALLOCATE_SYS;
- fh->fallocate_requires_locking = false;
- return (0);
- }
- if ((ret = __posix_posix_fallocate(fh, offset, len)) == 0) {
- fh->fallocate_available = WT_FALLOCATE_POSIX;
-#if !defined(__linux__)
- fh->fallocate_requires_locking = false;
+ if (__posix_std_fallocate(file_handle, wt_session, offset, len) == 0) {
+ file_handle->fallocate_nolock = __posix_std_fallocate;
+ WT_PUBLISH(file_handle->fallocate, NULL);
+ return (0);
+ }
+ if (__posix_sys_fallocate(file_handle, wt_session, offset, len) == 0) {
+ file_handle->fallocate_nolock = __posix_sys_fallocate;
+ WT_PUBLISH(file_handle->fallocate, NULL);
+ return (0);
+ }
+ if (__posix_posix_fallocate(
+ file_handle, wt_session, offset, len) == 0) {
+#if defined(__linux__)
+ file_handle->fallocate = __posix_posix_fallocate;
+ WT_WRITE_BARRIER();
+#else
+ file_handle->fallocate_nolock = __posix_posix_fallocate;
+ WT_PUBLISH(file_handle->fallocate, NULL);
#endif
- return (0);
- }
- /* FALLTHROUGH */
- case WT_FALLOCATE_NOT_AVAILABLE:
- default:
- fh->fallocate_available = WT_FALLOCATE_NOT_AVAILABLE;
- return (ENOTSUP);
+ return (0);
}
- /* NOTREACHED */
+
+ file_handle->fallocate = NULL;
+ WT_WRITE_BARRIER();
+ return (ENOTSUP);
}
diff --git a/src/os_posix/os_fs.c b/src/os_posix/os_fs.c
index 86aa8db8f4f..ab9c82613d6 100644
--- a/src/os_posix/os_fs.c
+++ b/src/os_posix/os_fs.c
@@ -13,30 +13,11 @@
* Underlying support function to flush a file handle.
*/
static int
-__posix_sync(WT_SESSION_IMPL *session,
- int fd, const char *name, const char *func, bool block)
+__posix_sync(
+ WT_SESSION_IMPL *session, int fd, const char *name, const char *func)
{
WT_DECL_RET;
- WT_ASSERT(session, !F_ISSET(S2C(session), WT_CONN_READONLY));
-
-#ifdef HAVE_SYNC_FILE_RANGE
- if (!block) {
- WT_SYSCALL_RETRY(sync_file_range(fd,
- (off64_t)0, (off64_t)0, SYNC_FILE_RANGE_WRITE), ret);
- if (ret == 0)
- return (0);
- WT_RET_MSG(session, ret, "%s: %s: sync_file_range", name, func);
- }
-#else
- /*
- * Callers attempting asynchronous flush handle ENOTSUP returns, and
- * won't make further attempts.
- */
- if (!block)
- return (ENOTSUP);
-#endif
-
#if defined(F_FULLFSYNC)
/*
* OS X fsync documentation:
@@ -73,45 +54,29 @@ __posix_sync(WT_SESSION_IMPL *session,
#endif
}
+#ifdef __linux__
/*
* __posix_directory_sync --
* Flush a directory to ensure file creation is durable.
*/
static int
-__posix_directory_sync(WT_SESSION_IMPL *session, const char *path)
+__posix_directory_sync(
+ WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, const char *path)
{
-#ifdef __linux__
WT_DECL_RET;
+ WT_SESSION_IMPL *session;
int fd, tret;
- const char *dir;
- char *copy;
- tret = 0;
- /*
- * POSIX 1003.1 does not require that fsync of a file handle ensures the
- * entry in the directory containing the file has also reached disk (and
- * there are historic Linux filesystems requiring this), do an explicit
- * fsync on a file descriptor for the directory to be sure.
- */
- copy = NULL;
- if (path == NULL || (dir = strrchr(path, '/')) == NULL)
- path = S2C(session)->home;
- else {
- /*
- * Copy the directory name, leaving the trailing slash in place,
- * so a path of "/foo" doesn't result in an empty string.
- */
- WT_RET(__wt_strndup(
- session, path, (size_t)(dir - path) + 1, &copy));
- path = copy;
- }
+ WT_UNUSED(file_system);
+
+ session = (WT_SESSION_IMPL *)wt_session;
WT_SYSCALL_RETRY((
(fd = open(path, O_RDONLY, 0444)) == -1 ? 1 : 0), ret);
if (ret != 0)
- WT_ERR_MSG(session, ret, "%s: directory-sync: open", path);
+ WT_RET_MSG(session, ret, "%s: directory-sync: open", path);
- ret = __posix_sync(session, fd, path, "directory-sync", true);
+ ret = __posix_sync(session, fd, path, "directory-sync");
WT_SYSCALL_RETRY(close(fd), tret);
if (tret != 0) {
@@ -119,232 +84,182 @@ __posix_directory_sync(WT_SESSION_IMPL *session, const char *path)
if (ret == 0)
ret = tret;
}
-err: __wt_free(session, copy);
return (ret);
-#else
- WT_UNUSED(session);
- WT_UNUSED(path);
- return (0);
-#endif
}
+#endif
/*
- * __posix_file_exist --
+ * __posix_fs_exist --
* Return if the file exists.
*/
static int
-__posix_file_exist(WT_SESSION_IMPL *session, const char *name, bool *existp)
+__posix_fs_exist(WT_FILE_SYSTEM *file_system,
+ WT_SESSION *wt_session, const char *name, bool *existp)
{
struct stat sb;
WT_DECL_RET;
- char *path;
+ WT_SESSION_IMPL *session;
- WT_RET(__wt_filename(session, name, &path));
- name = path;
+ WT_UNUSED(file_system);
+
+ session = (WT_SESSION_IMPL *)wt_session;
WT_SYSCALL_RETRY(stat(name, &sb), ret);
- if (ret == 0)
+ if (ret == 0) {
*existp = true;
- else if (ret == ENOENT) {
+ return (0);
+ }
+ if (ret == ENOENT) {
*existp = false;
- ret = 0;
- } else
- __wt_err(session, ret, "%s: file-exist: stat", name);
-
- __wt_free(session, path);
- return (ret);
+ return (0);
+ }
+ WT_RET_MSG(session, ret, "%s: file-exist: stat", name);
}
/*
- * __posix_file_remove --
+ * __posix_fs_remove --
* Remove a file.
*/
static int
-__posix_file_remove(WT_SESSION_IMPL *session, const char *name)
+__posix_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;
WT_SYSCALL_RETRY(remove(name), ret);
- if (ret != 0)
- __wt_err(session, ret, "%s: file-remove: remove", name);
-
- __wt_free(session, path);
- return (ret);
+ if (ret == 0)
+ return (0);
+ WT_RET_MSG(session, ret, "%s: file-remove: remove", name);
}
/*
- * __posix_file_rename --
+ * __posix_fs_rename --
* Rename a file.
*/
static int
-__posix_file_rename(WT_SESSION_IMPL *session, const char *from, const char *to)
+__posix_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;
-
-#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_SESSION_IMPL *session;
- 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;
+ WT_UNUSED(file_system);
- WT_SYSCALL_RETRY(rename(from, to), ret);
- if (ret != 0)
- __wt_err(session, ret,
- "%s to %s: file-rename: rename", from, to);
+ session = (WT_SESSION_IMPL *)wt_session;
-err: __wt_free(session, from_path);
- __wt_free(session, to_path);
- return (ret);
+ WT_SYSCALL_RETRY(rename(from, to), ret);
+ if (ret == 0)
+ return (0);
+ WT_RET_MSG(session, ret, "%s to %s: file-rename: rename", from, to);
}
/*
- * __posix_file_size --
+ * __posix_fs_size --
* Get the size of a file in bytes, by file name.
*/
static int
-__posix_file_size(
- WT_SESSION_IMPL *session, const char *name, bool silent, wt_off_t *sizep)
+__posix_fs_size(WT_FILE_SYSTEM *file_system,
+ WT_SESSION *wt_session, const char *name, wt_off_t *sizep)
{
struct stat sb;
WT_DECL_RET;
- char *path;
+ WT_SESSION_IMPL *session;
- WT_RET(__wt_filename(session, name, &path));
- name = path;
+ WT_UNUSED(file_system);
+
+ session = (WT_SESSION_IMPL *)wt_session;
- /*
- * Optionally don't log errors on ENOENT; some callers of this function
- * expect failure in that case and don't want an error message logged.
- */
WT_SYSCALL_RETRY(stat(name, &sb), ret);
- if (ret == 0)
+ if (ret == 0) {
*sizep = sb.st_size;
- else if (ret != ENOENT || !silent)
- __wt_err(session, ret, "%s: file-size: stat", name);
-
- __wt_free(session, path);
-
- return (ret);
+ return (0);
+ }
+ WT_RET_MSG(session, ret, "%s: file-size: stat", name);
}
+#if defined(HAVE_POSIX_FADVISE)
/*
- * __posix_handle_advise --
+ * __posix_file_advise --
* POSIX fadvise.
*/
static int
-__posix_handle_advise(WT_SESSION_IMPL *session,
- WT_FH *fh, wt_off_t offset, wt_off_t len, int advice)
+__posix_file_advise(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session,
+ wt_off_t offset, wt_off_t len, int advice)
{
-#if defined(HAVE_POSIX_FADVISE)
WT_DECL_RET;
+ WT_FILE_HANDLE_POSIX *pfh;
+ WT_SESSION_IMPL *session;
- /*
- * Refuse pre-load when direct I/O is configured for the file, the
- * kernel cache isn't interesting.
- */
- if (advice == POSIX_MADV_WILLNEED && fh->direct_io)
- return (ENOTSUP);
+ session = (WT_SESSION_IMPL *)wt_session;
+ pfh = (WT_FILE_HANDLE_POSIX *)file_handle;
- WT_SYSCALL_RETRY(posix_fadvise(fh->fd, offset, len, advice), ret);
+ WT_SYSCALL_RETRY(posix_fadvise(pfh->fd, offset, len, advice), ret);
if (ret == 0)
return (0);
/*
* Treat EINVAL as not-supported, some systems don't support some flags.
- * Quietly fail, callers expect not-supported failures.
+ * Quietly fail, callers expect not-supported failures, and reset the
+ * handle method to prevent future calls.
*/
- if (ret == EINVAL)
+ if (ret == EINVAL) {
+ file_handle->fadvise = NULL;
return (ENOTSUP);
+ }
- WT_RET_MSG(session, ret, "%s: handle-advise: posix_fadvise", fh->name);
-#else
- WT_UNUSED(session);
- WT_UNUSED(fh);
- WT_UNUSED(offset);
- WT_UNUSED(len);
- WT_UNUSED(advice);
+ WT_RET_MSG(session, ret,
+ "%s: handle-advise: posix_fadvise", file_handle->name);
- /* Quietly fail, callers expect not-supported failures. */
- return (ENOTSUP);
-#endif
}
+#endif
/*
- * __posix_handle_close --
- * ANSI C close/fclose.
+ * __posix_file_close --
+ * ANSI C close.
*/
static int
-__posix_handle_close(WT_SESSION_IMPL *session, WT_FH *fh)
+__posix_file_close(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session)
{
WT_DECL_RET;
+ WT_FILE_HANDLE_POSIX *pfh;
+ WT_SESSION_IMPL *session;
- if (fh->fp == NULL) {
- WT_SYSCALL_RETRY(close(fh->fd), ret);
- if (ret == 0)
- return (0);
- WT_RET_MSG(session, ret, "%s: handle-close: close", fh->name);
- }
+ session = (WT_SESSION_IMPL *)wt_session;
+ pfh = (WT_FILE_HANDLE_POSIX *)file_handle;
- /* 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 handle. */
+ if (pfh->fd != -1) {
+ WT_SYSCALL_RETRY(close(pfh->fd), ret);
+ if (ret != 0)
+ __wt_err(session, ret,
+ "%s: handle-close: close", file_handle->name);
}
- /* Close the file. */
- if (fclose(fh->fp) != 0) {
- ret = __wt_errno();
- __wt_err(session, ret, "%s: handle-close: fclose", fh->name);
- }
+ __wt_free(session, file_handle->name);
+ __wt_free(session, pfh);
return (ret);
}
/*
- * __posix_handle_getc --
- * ANSI C fgetc.
- */
-static int
-__posix_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);
-}
-
-/*
- * __posix_handle_lock --
+ * __posix_file_lock --
* Lock/unlock a file.
*/
static int
-__posix_handle_lock(WT_SESSION_IMPL *session, WT_FH *fh, bool lock)
+__posix_file_lock(
+ WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, bool lock)
{
struct flock fl;
WT_DECL_RET;
+ WT_FILE_HANDLE_POSIX *pfh;
+ WT_SESSION_IMPL *session;
+
+ session = (WT_SESSION_IMPL *)wt_session;
+ pfh = (WT_FILE_HANDLE_POSIX *)file_handle;
/*
* WiredTiger requires this function be able to acquire locks past
@@ -360,44 +275,32 @@ __posix_handle_lock(WT_SESSION_IMPL *session, WT_FH *fh, bool lock)
fl.l_type = lock ? F_WRLCK : F_UNLCK;
fl.l_whence = SEEK_SET;
- WT_SYSCALL_RETRY(fcntl(fh->fd, F_SETLK, &fl), ret);
+ WT_SYSCALL_RETRY(fcntl(pfh->fd, F_SETLK, &fl), ret);
if (ret == 0)
return (0);
- WT_RET_MSG(session, ret, "%s: handle-lock: fcntl", fh->name);
+ WT_RET_MSG(session, ret, "%s: handle-lock: fcntl", file_handle->name);
}
/*
- * __posix_handle_printf --
- * ANSI C vfprintf.
- */
-static int
-__posix_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);
-}
-
-/*
- * __posix_handle_read --
+ * __posix_file_read --
* POSIX pread.
*/
static int
-__posix_handle_read(
- WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t offset, size_t len, void *buf)
+__posix_file_read(WT_FILE_HANDLE *file_handle,
+ WT_SESSION *wt_session, wt_off_t offset, size_t len, void *buf)
{
+ WT_FILE_HANDLE_POSIX *pfh;
+ WT_SESSION_IMPL *session;
size_t chunk;
ssize_t nr;
uint8_t *addr;
+ session = (WT_SESSION_IMPL *)wt_session;
+ pfh = (WT_FILE_HANDLE_POSIX *)file_handle;
+
/* Assert direct I/O is aligned and a multiple of the alignment. */
WT_ASSERT(session,
- !fh->direct_io ||
+ !pfh->direct_io ||
S2C(session)->buffer_alignment == 0 ||
(!((uintptr_t)buf &
(uintptr_t)(S2C(session)->buffer_alignment - 1)) &&
@@ -407,79 +310,122 @@ __posix_handle_read(
/* Break reads larger than 1GB into 1GB chunks. */
for (addr = buf; len > 0; addr += nr, len -= (size_t)nr, offset += nr) {
chunk = WT_MIN(len, WT_GIGABYTE);
- if ((nr = pread(fh->fd, addr, chunk, offset)) <= 0)
+ if ((nr = pread(pfh->fd, addr, chunk, offset)) <= 0)
WT_RET_MSG(session, nr == 0 ? WT_ERROR : __wt_errno(),
"%s: handle-read: pread: failed to read %"
WT_SIZET_FMT " bytes at offset %" PRIuMAX,
- fh->name, chunk, (uintmax_t)offset);
+ file_handle->name, chunk, (uintmax_t)offset);
}
return (0);
}
/*
- * __posix_handle_size --
+ * __posix_file_size --
* Get the size of a file in bytes, by file handle.
*/
static int
-__posix_handle_size(WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t *sizep)
+__posix_file_size(
+ WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, wt_off_t *sizep)
{
struct stat sb;
WT_DECL_RET;
+ WT_FILE_HANDLE_POSIX *pfh;
+ WT_SESSION_IMPL *session;
- WT_SYSCALL_RETRY(fstat(fh->fd, &sb), ret);
+ session = (WT_SESSION_IMPL *)wt_session;
+ pfh = (WT_FILE_HANDLE_POSIX *)file_handle;
+
+ WT_SYSCALL_RETRY(fstat(pfh->fd, &sb), ret);
if (ret == 0) {
*sizep = sb.st_size;
return (0);
}
- WT_RET_MSG(session, ret, "%s: handle-size: fstat", fh->name);
+ WT_RET_MSG(session, ret, "%s: handle-size: fstat", file_handle->name);
+}
+
+/*
+ * __posix_file_sync --
+ * POSIX fsync.
+ */
+static int
+__posix_file_sync(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session)
+{
+ WT_FILE_HANDLE_POSIX *pfh;
+ WT_SESSION_IMPL *session;
+
+ session = (WT_SESSION_IMPL *)wt_session;
+ pfh = (WT_FILE_HANDLE_POSIX *)file_handle;
+
+ return (
+ __posix_sync(session, pfh->fd, file_handle->name, "handle-sync"));
}
+#ifdef HAVE_SYNC_FILE_RANGE
/*
- * __posix_handle_sync --
- * POSIX fflush/fsync.
+ * __posix_file_sync_nowait --
+ * POSIX fsync.
*/
static int
-__posix_handle_sync(WT_SESSION_IMPL *session, WT_FH *fh, bool block)
+__posix_file_sync_nowait(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session)
{
- if (fh->fp == NULL)
- return (__posix_sync(
- session, fh->fd, fh->name, "handle-sync", block));
+ WT_DECL_RET;
+ WT_FILE_HANDLE_POSIX *pfh;
+ WT_SESSION_IMPL *session;
+
+ session = (WT_SESSION_IMPL *)wt_session;
+ pfh = (WT_FILE_HANDLE_POSIX *)file_handle;
- if (fflush(fh->fp) == 0)
+ WT_SYSCALL_RETRY(sync_file_range(pfh->fd,
+ (off64_t)0, (off64_t)0, SYNC_FILE_RANGE_WRITE), ret);
+ if (ret == 0)
return (0);
- WT_RET_MSG(session, __wt_errno(), "%s: handle-sync: fflush", fh->name);
+ WT_RET_MSG(session, ret,
+ "%s: handle-sync-nowait: sync_file_range", file_handle->name);
}
+#endif
/*
- * __posix_handle_truncate --
+ * __posix_file_truncate --
* POSIX ftruncate.
*/
static int
-__posix_handle_truncate(WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t len)
+__posix_file_truncate(
+ WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session, wt_off_t len)
{
WT_DECL_RET;
+ WT_FILE_HANDLE_POSIX *pfh;
+ WT_SESSION_IMPL *session;
+
+ session = (WT_SESSION_IMPL *)wt_session;
+ pfh = (WT_FILE_HANDLE_POSIX *)file_handle;
- WT_SYSCALL_RETRY(ftruncate(fh->fd, len), ret);
+ WT_SYSCALL_RETRY(ftruncate(pfh->fd, len), ret);
if (ret == 0)
return (0);
- WT_RET_MSG(session, ret, "%s: handle-truncate: ftruncate", fh->name);
+ WT_RET_MSG(session, ret,
+ "%s: handle-truncate: ftruncate", file_handle->name);
}
/*
- * __posix_handle_write --
+ * __posix_file_write --
* POSIX pwrite.
*/
static int
-__posix_handle_write(WT_SESSION_IMPL *session,
- WT_FH *fh, wt_off_t offset, size_t len, const void *buf)
+__posix_file_write(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session,
+ wt_off_t offset, size_t len, const void *buf)
{
+ WT_FILE_HANDLE_POSIX *pfh;
+ WT_SESSION_IMPL *session;
size_t chunk;
ssize_t nw;
const uint8_t *addr;
+ session = (WT_SESSION_IMPL *)wt_session;
+ pfh = (WT_FILE_HANDLE_POSIX *)file_handle;
+
/* Assert direct I/O is aligned and a multiple of the alignment. */
WT_ASSERT(session,
- !fh->direct_io ||
+ !pfh->direct_io ||
S2C(session)->buffer_alignment == 0 ||
(!((uintptr_t)buf &
(uintptr_t)(S2C(session)->buffer_alignment - 1)) &&
@@ -489,21 +435,21 @@ __posix_handle_write(WT_SESSION_IMPL *session,
/* Break writes larger than 1GB into 1GB chunks. */
for (addr = buf; len > 0; addr += nw, len -= (size_t)nw, offset += nw) {
chunk = WT_MIN(len, WT_GIGABYTE);
- if ((nw = pwrite(fh->fd, addr, chunk, offset)) < 0)
+ if ((nw = pwrite(pfh->fd, addr, chunk, offset)) < 0)
WT_RET_MSG(session, __wt_errno(),
"%s: handle-write: pwrite: failed to write %"
WT_SIZET_FMT " bytes at offset %" PRIuMAX,
- fh->name, chunk, (uintmax_t)offset);
+ file_handle->name, chunk, (uintmax_t)offset);
}
return (0);
}
/*
- * __posix_handle_open_cloexec --
+ * __posix_open_file_cloexec --
* Prevent child access to file handles.
*/
static inline int
-__posix_handle_open_cloexec(WT_SESSION_IMPL *session, int fd, const char *name)
+__posix_open_file_cloexec(WT_SESSION_IMPL *session, int fd, const char *name)
{
#if defined(HAVE_FCNTL) && defined(FD_CLOEXEC) && !defined(O_CLOEXEC)
int f;
@@ -528,28 +474,35 @@ __posix_handle_open_cloexec(WT_SESSION_IMPL *session, int fd, const char *name)
}
/*
- * __posix_handle_open --
+ * __posix_open_file --
* Open a file handle.
*/
static int
-__posix_handle_open(WT_SESSION_IMPL *session,
- WT_FH *fh, const char *name, uint32_t file_type, uint32_t flags)
+__posix_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)
{
WT_CONNECTION_IMPL *conn;
WT_DECL_RET;
+ WT_FILE_HANDLE *file_handle;
+ WT_FILE_HANDLE_POSIX *pfh;
+ WT_SESSION_IMPL *session;
mode_t mode;
- int f, fd, tret;
- bool direct_io;
- const char *stream_mode;
+ int f;
+
+ 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, &pfh));
/* Set up error handling. */
- fh->fd = fd = -1;
- fh->fp = NULL;
+ pfh->fd = -1;
- if (file_type == WT_FILE_TYPE_DIRECTORY) {
+ if (file_type == WT_OPEN_FILE_TYPE_DIRECTORY) {
f = O_RDONLY;
#ifdef O_CLOEXEC
/*
@@ -560,10 +513,10 @@ __posix_handle_open(WT_SESSION_IMPL *session,
f |= O_CLOEXEC;
#endif
WT_SYSCALL_RETRY((
- (fd = open(name, f, 0444)) == -1 ? 1 : 0), ret);
+ (pfh->fd = open(name, f, 0444)) == -1 ? 1 : 0), ret);
if (ret != 0)
WT_ERR_MSG(session, ret, "%s: handle-open: open", name);
- WT_ERR(__posix_handle_open_cloexec(session, fd, name));
+ WT_ERR(__posix_open_file_cloexec(session, pfh->fd, name));
goto directory_open;
}
@@ -589,28 +542,20 @@ __posix_handle_open(WT_SESSION_IMPL *session,
f |= O_CLOEXEC;
#endif
#ifdef O_DIRECT
- /*
- * Direct I/O: file-type is a flag from the set of possible flags stored
- * in the connection handle during configuration, check for a match.
- * Also, "direct_io=checkpoint" configures direct I/O for readonly data
- * files.
- */
- 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 |= O_DIRECT;
- direct_io = true;
- }
+ pfh->direct_io = true;
+ } else
+ pfh->direct_io = false;
#endif
- fh->direct_io = direct_io;
#ifdef O_NOATIME
/* Avoid updating metadata for read-only workloads. */
- if (file_type == WT_FILE_TYPE_DATA)
+ if (file_type == WT_OPEN_FILE_TYPE_DATA)
f |= O_NOATIME;
#endif
- if (file_type == WT_FILE_TYPE_LOG &&
+ if (file_type == WT_OPEN_FILE_TYPE_LOG &&
FLD_ISSET(conn->txn_logsync, WT_LOG_DSYNC)) {
#ifdef O_DSYNC
f |= O_DSYNC;
@@ -622,115 +567,122 @@ __posix_handle_open(WT_SESSION_IMPL *session,
#endif
}
- WT_SYSCALL_RETRY(((fd = open(name, f, mode)) == -1 ? 1 : 0), ret);
+ WT_SYSCALL_RETRY(((pfh->fd = open(name, f, mode)) == -1 ? 1 : 0), ret);
if (ret != 0)
WT_ERR_MSG(session, ret,
- direct_io ?
+ pfh->direct_io ?
"%s: handle-open: open: failed with direct I/O configured, "
"some filesystem types do not support direct I/O" :
"%s: handle-open: open", name);
- WT_ERR(__posix_handle_open_cloexec(session, fd, name));
+ WT_ERR(__posix_open_file_cloexec(session, pfh->fd, name));
- /* Disable read-ahead on trees: it slows down random read workloads. */
#if defined(HAVE_POSIX_FADVISE)
- if (file_type == WT_FILE_TYPE_DATA) {
+ /*
+ * Disable read-ahead on trees: it slows down random read workloads.
+ * Ignore fadvise when doing direct I/O, the kernel cache isn't
+ * interesting.
+ */
+ if (!pfh->direct_io && file_type == WT_OPEN_FILE_TYPE_DATA) {
WT_SYSCALL_RETRY(
- posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM), ret);
+ posix_fadvise(pfh->fd, 0, 0, POSIX_FADV_RANDOM), ret);
if (ret != 0)
WT_ERR_MSG(session, ret,
"%s: handle-open: posix_fadvise", name);
}
#endif
- /* Optionally configure a stdio stream API. */
- switch (LF_MASK(WT_STREAM_APPEND | WT_STREAM_READ | WT_STREAM_WRITE)) {
- case WT_STREAM_APPEND:
- stream_mode = "a";
- F_SET(fh, WT_FH_FLUSH_ON_CLOSE);
- break;
- case WT_STREAM_READ:
- stream_mode = "r";
- break;
- case WT_STREAM_WRITE:
- 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 = fdopen(fd, stream_mode)) == NULL)
- WT_ERR_MSG(session, __wt_errno(),
- "%s: handle-open: fdopen", name);
- if (LF_ISSET(WT_STREAM_LINE_BUFFER))
- __wt_stream_set_line_buffer(fh->fp);
- }
-
directory_open:
- fh->fd = fd;
-
- /* Configure fallocate calls. */
- __wt_posix_handle_allocate_configure(session, fh);
-
- fh->fh_advise = __posix_handle_advise;
- fh->fh_allocate = __wt_posix_handle_allocate;
- fh->fh_close = __posix_handle_close;
- fh->fh_getc = __posix_handle_getc;
- fh->fh_lock = __posix_handle_lock;
- fh->fh_map = __wt_posix_map;
- fh->fh_map_discard = __wt_posix_map_discard;
- fh->fh_map_preload = __wt_posix_map_preload;
- fh->fh_map_unmap = __wt_posix_map_unmap;
- fh->fh_printf = __posix_handle_printf;
- fh->fh_read = __posix_handle_read;
- fh->fh_size = __posix_handle_size;
- fh->fh_sync = __posix_handle_sync;
- fh->fh_truncate = __posix_handle_truncate;
- fh->fh_write = __posix_handle_write;
+ /* Initialize public information. */
+ file_handle = (WT_FILE_HANDLE *)pfh;
+ WT_ERR(__wt_strdup(session, name, &file_handle->name));
+
+ file_handle->close = __posix_file_close;
+#if defined(HAVE_POSIX_FADVISE)
+ /*
+ * Ignore fadvise when doing direct I/O, the kernel cache isn't
+ * interesting.
+ */
+ if (!pfh->direct_io)
+ file_handle->fadvise = __posix_file_advise;
+#endif
+ file_handle->fallocate = __wt_posix_file_fallocate;
+ file_handle->lock = __posix_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_posix_map;
+#ifdef HAVE_POSIX_MADVISE
+ file_handle->map_discard = __wt_posix_map_discard;
+ file_handle->map_preload = __wt_posix_map_preload;
+#endif
+ file_handle->unmap = __wt_posix_unmap;
+#endif
+ file_handle->read = __posix_file_read;
+ file_handle->size = __posix_file_size;
+ file_handle->sync = __posix_file_sync;
+#ifdef HAVE_SYNC_FILE_RANGE
+ file_handle->sync_nowait = __posix_file_sync_nowait;
+#endif
+ file_handle->truncate = __posix_file_truncate;
+ file_handle->write = __posix_file_write;
+
+ *file_handlep = file_handle;
return (0);
-err: if (fd != -1) {
- WT_SYSCALL_RETRY(close(fd), tret);
- if (tret != 0)
- __wt_err(session, tret, "%s: handle-open: close", name);
- }
+err: WT_TRET(__posix_file_close((WT_FILE_HANDLE *)pfh, wt_session));
return (ret);
}
/*
- * __wt_os_posix --
- * Initialize a POSIX configuration.
+ * __posix_terminate --
+ * Terminate a POSIX configuration.
*/
-int
-__wt_os_posix(WT_SESSION_IMPL *session)
+static int
+__posix_terminate(WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session)
{
- WT_CONNECTION_IMPL *conn;
+ WT_SESSION_IMPL *session;
- conn = S2C(session);
+ WT_UNUSED(file_system);
- /* Initialize the POSIX jump table. */
- conn->file_directory_list = __wt_posix_directory_list;
- conn->file_directory_sync = __posix_directory_sync;
- conn->file_exist = __posix_file_exist;
- conn->file_remove = __posix_file_remove;
- conn->file_rename = __posix_file_rename;
- conn->file_size = __posix_file_size;
- conn->handle_open = __posix_handle_open;
+ session = (WT_SESSION_IMPL *)wt_session;
+ __wt_free(session, file_system);
return (0);
}
/*
- * __wt_os_posix_cleanup --
- * Discard a POSIX configuration.
+ * __wt_os_posix --
+ * Initialize a POSIX configuration.
*/
int
-__wt_os_posix_cleanup(WT_SESSION_IMPL *session)
+__wt_os_posix(WT_SESSION_IMPL *session)
{
- WT_UNUSED(session);
+ WT_CONNECTION_IMPL *conn;
+ WT_FILE_SYSTEM *file_system;
+
+ conn = S2C(session);
+
+ WT_RET(__wt_calloc_one(session, &file_system));
+
+ /* Initialize the POSIX jump table. */
+ file_system->directory_list = __wt_posix_directory_list;
+ file_system->directory_list_free = __wt_posix_directory_list_free;
+#ifdef __linux__
+ file_system->directory_sync = __posix_directory_sync;
+#endif
+ file_system->exist = __posix_fs_exist;
+ file_system->open_file = __posix_open_file;
+ file_system->remove = __posix_fs_remove;
+ file_system->rename = __posix_fs_rename;
+ file_system->size = __posix_fs_size;
+ file_system->terminate = __posix_terminate;
+
+ /* Switch it into place. */
+ conn->file_system = file_system;
return (0);
}
diff --git a/src/os_posix/os_map.c b/src/os_posix/os_map.c
index de28891ffd1..7fde4037250 100644
--- a/src/os_posix/os_map.c
+++ b/src/os_posix/os_map.c
@@ -13,23 +13,26 @@
* Map a file into memory.
*/
int
-__wt_posix_map(WT_SESSION_IMPL *session,
- WT_FH *fh, void *mapp, size_t *lenp, void **mappingcookie)
+__wt_posix_map(WT_FILE_HANDLE *fh, WT_SESSION *wt_session,
+ void *mapped_regionp, size_t *lenp, void *mapped_cookiep)
{
+ WT_FILE_HANDLE_POSIX *pfh;
+ WT_SESSION_IMPL *session;
size_t len;
wt_off_t file_size;
void *map;
- WT_UNUSED(mappingcookie);
+ WT_UNUSED(mapped_cookiep);
- WT_ASSERT(session, !F_ISSET(S2C(session), WT_CONN_IN_MEMORY));
+ session = (WT_SESSION_IMPL *)wt_session;
+ pfh = (WT_FILE_HANDLE_POSIX *)fh;
/*
* Mapping isn't possible if direct I/O configured for the file, the
* Linux open(2) documentation says applications should avoid mixing
* mmap(2) of files with direct I/O to the same files.
*/
- if (fh->direct_io)
+ if (pfh->direct_io)
return (ENOTSUP);
/*
@@ -37,7 +40,7 @@ __wt_posix_map(WT_SESSION_IMPL *session,
* 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(fh->size(fh, wt_session, &file_size));
len = (size_t)file_size;
(void)__wt_verbose(session, WT_VERB_HANDLEOPS,
@@ -49,43 +52,48 @@ __wt_posix_map(WT_SESSION_IMPL *session,
MAP_NOCORE |
#endif
MAP_PRIVATE,
- fh->fd, (wt_off_t)0)) == MAP_FAILED)
+ pfh->fd, (wt_off_t)0)) == MAP_FAILED)
WT_RET_MSG(session,
__wt_errno(), "%s: memory-map: mmap", fh->name);
- *(void **)mapp = map;
+ *(void **)mapped_regionp = map;
*lenp = len;
return (0);
}
#ifdef HAVE_POSIX_MADVISE
/*
- * __posix_map_preload_madvise --
+ * __wt_posix_map_preload --
* Cause a section of a memory map to be faulted in.
*/
-static int
-__posix_map_preload_madvise(
- WT_SESSION_IMPL *session, WT_FH *fh, const void *p, size_t size)
+int
+__wt_posix_map_preload(WT_FILE_HANDLE *fh,
+ WT_SESSION *wt_session, const void *map, size_t length, void *mapped_cookie)
{
WT_BM *bm;
WT_CONNECTION_IMPL *conn;
WT_DECL_RET;
+ WT_SESSION_IMPL *session;
void *blk;
+ WT_UNUSED(mapped_cookie);
+
+ session = (WT_SESSION_IMPL *)wt_session;
+
conn = S2C(session);
bm = S2BT(session)->bm;
/* Linux requires the address be aligned to a 4KB boundary. */
- blk = (void *)((uintptr_t)p & ~(uintptr_t)(conn->page_size - 1));
- size += WT_PTRDIFF(p, blk);
+ blk = (void *)((uintptr_t)map & ~(uintptr_t)(conn->page_size - 1));
+ length += WT_PTRDIFF(map, blk);
/* XXX proxy for "am I doing a scan?" -- manual read-ahead */
if (F_ISSET(session, WT_SESSION_NO_CACHE)) {
/* Read in 2MB blocks every 1MB of data. */
- if (((uintptr_t)((uint8_t *)blk + size) &
+ if (((uintptr_t)((uint8_t *)blk + length) &
(uintptr_t)((1<<20) - 1)) < (uintptr_t)blk)
return (0);
- size = WT_MIN(WT_MAX(20 * size, 2 << 20),
+ length = WT_MIN(WT_MAX(20 * length, 2 << 20),
WT_PTRDIFF((uint8_t *)bm->map + bm->maplen, blk));
}
@@ -93,10 +101,10 @@ __posix_map_preload_madvise(
* Manual pages aren't clear on whether alignment is required for the
* size, so we will be conservative.
*/
- size &= ~(size_t)(conn->page_size - 1);
+ length &= ~(size_t)(conn->page_size - 1);
- if (size <= (size_t)conn->page_size ||
- (ret = posix_madvise(blk, size, POSIX_MADV_WILLNEED)) == 0)
+ if (length <= (size_t)conn->page_size ||
+ (ret = posix_madvise(blk, length, POSIX_MADV_WILLNEED)) == 0)
return (0);
WT_RET_MSG(session, ret,
"%s: memory-map preload: posix_madvise: POSIX_MADV_WILLNEED",
@@ -104,46 +112,30 @@ __posix_map_preload_madvise(
}
#endif
-/*
- * __wt_posix_map_preload --
- * Cause a section of a memory map to be faulted in.
- */
-int
-__wt_posix_map_preload(
- WT_SESSION_IMPL *session, WT_FH *fh, const void *p, size_t size)
-{
- WT_ASSERT(session, !F_ISSET(S2C(session), WT_CONN_IN_MEMORY));
-
-#ifdef HAVE_POSIX_MADVISE
- return (__posix_map_preload_madvise(session, fh, p, size));
-#else
- WT_UNUSED(fh);
- WT_UNUSED(p);
- WT_UNUSED(size);
- return (ENOTSUP);
-#endif
-}
-
#ifdef HAVE_POSIX_MADVISE
/*
- * __posix_map_discard_madvise --
+ * __wt_posix_map_discard --
* Discard a chunk of the memory map.
*/
-static int
-__posix_map_discard_madvise(
- WT_SESSION_IMPL *session, WT_FH *fh, void *p, size_t size)
+int
+__wt_posix_map_discard(WT_FILE_HANDLE *fh,
+ WT_SESSION *wt_session, void *map, size_t length, void *mapped_cookie)
{
WT_CONNECTION_IMPL *conn;
WT_DECL_RET;
+ WT_SESSION_IMPL *session;
void *blk;
+ WT_UNUSED(mapped_cookie);
+
+ session = (WT_SESSION_IMPL *)wt_session;
conn = S2C(session);
/* Linux requires the address be aligned to a 4KB boundary. */
- blk = (void *)((uintptr_t)p & ~(uintptr_t)(conn->page_size - 1));
- size += WT_PTRDIFF(p, blk);
+ blk = (void *)((uintptr_t)map & ~(uintptr_t)(conn->page_size - 1));
+ length += WT_PTRDIFF(map, blk);
- if ((ret = posix_madvise(blk, size, POSIX_MADV_DONTNEED)) == 0)
+ if ((ret = posix_madvise(blk, length, POSIX_MADV_DONTNEED)) == 0)
return (0);
WT_RET_MSG(session, ret,
"%s: memory-map discard: posix_madvise: POSIX_MADV_DONTNEED",
@@ -152,41 +144,23 @@ __posix_map_discard_madvise(
#endif
/*
- * __wt_posix_map_discard --
- * Discard a chunk of the memory map.
- */
-int
-__wt_posix_map_discard(
- WT_SESSION_IMPL *session, WT_FH *fh, void *p, size_t size)
-{
- WT_ASSERT(session, !F_ISSET(S2C(session), WT_CONN_IN_MEMORY));
-
-#ifdef HAVE_POSIX_MADVISE
- return (__posix_map_discard_madvise(session, fh, p, size));
-#else
- WT_UNUSED(fh);
- WT_UNUSED(p);
- WT_UNUSED(size);
- return (ENOTSUP);
-#endif
-}
-
-/*
- * __wt_posix_map_unmap --
+ * __wt_posix_unmap --
* Remove a memory mapping.
*/
int
-__wt_posix_map_unmap(WT_SESSION_IMPL *session,
- WT_FH *fh, void *map, size_t len, void **mappingcookie)
+__wt_posix_unmap(WT_FILE_HANDLE *fh, WT_SESSION *wt_session,
+ void *mapped_region, size_t len, void *mapped_cookie)
{
- WT_UNUSED(mappingcookie);
+ WT_SESSION_IMPL *session;
+
+ WT_UNUSED(mapped_cookie);
- WT_ASSERT(session, !F_ISSET(S2C(session), WT_CONN_IN_MEMORY));
+ session = (WT_SESSION_IMPL *)wt_session;
(void)__wt_verbose(session, WT_VERB_HANDLEOPS,
"%s: memory-unmap: %" WT_SIZET_FMT " bytes", fh->name, len);
- if (munmap(map, len) == 0)
+ if (munmap(mapped_region, len) == 0)
return (0);
WT_RET_MSG(session, __wt_errno(), "%s: memory-unmap: munmap", fh->name);