summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/os_posix
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/wiredtiger/src/os_posix')
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_abort.c26
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_alloc.c238
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_dir.c94
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_dlopen.c83
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_errno.c22
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_exist.c37
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_fallocate.c97
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_filesize.c55
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_flock.c37
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_fsync.c54
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_ftruncate.c26
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_getline.c48
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_getopt.c150
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_map.c136
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_mtx_cond.c157
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_mtx_rw.c227
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_once.c20
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_open.c253
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_path.c28
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_priv.c19
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_remove.c66
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_rename.c38
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_rw.c86
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_sleep.c23
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_strtouq.c24
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_thread.c59
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_time.c53
-rw-r--r--src/third_party/wiredtiger/src/os_posix/os_yield.c18
28 files changed, 2174 insertions, 0 deletions
diff --git a/src/third_party/wiredtiger/src/os_posix/os_abort.c b/src/third_party/wiredtiger/src/os_posix/os_abort.c
new file mode 100644
index 00000000000..3d99ffe20b2
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_abort.c
@@ -0,0 +1,26 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_abort --
+ * Abort the process, dropping core.
+ */
+void
+__wt_abort(WT_SESSION_IMPL *session)
+ WT_GCC_FUNC_ATTRIBUTE((noreturn))
+{
+ __wt_errx(session, "aborting WiredTiger library");
+
+#ifdef HAVE_DIAGNOSTIC
+ __wt_attach(session);
+#endif
+
+ abort();
+ /* NOTREACHED */
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_alloc.c b/src/third_party/wiredtiger/src/os_posix/os_alloc.c
new file mode 100644
index 00000000000..f7344032a15
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_alloc.c
@@ -0,0 +1,238 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * There's no malloc interface, WiredTiger never calls malloc.
+ *
+ * The problem is an application might allocate memory, write secret stuff in
+ * it, free the memory, then WiredTiger allocates the memory and uses it for a
+ * file page or log record, then writes it to disk, without having overwritten
+ * it fully. That results in the secret stuff being protected by WiredTiger's
+ * permission mechanisms, potentially inappropriate for the secret stuff.
+ */
+
+/*
+ * __wt_calloc --
+ * ANSI calloc function.
+ */
+int
+__wt_calloc(WT_SESSION_IMPL *session, size_t number, size_t size, void *retp)
+{
+ void *p;
+
+ /*
+ * !!!
+ * This function MUST handle a NULL WT_SESSION_IMPL handle.
+ */
+ WT_ASSERT(session, number != 0 && size != 0);
+
+ if (session != NULL)
+ WT_STAT_FAST_CONN_INCR(session, memory_allocation);
+
+ if ((p = calloc(number, size)) == NULL)
+ WT_RET_MSG(session, __wt_errno(), "memory allocation");
+
+ *(void **)retp = p;
+ return (0);
+}
+
+/*
+ * __wt_realloc --
+ * ANSI realloc function.
+ */
+int
+__wt_realloc(WT_SESSION_IMPL *session,
+ size_t *bytes_allocated_ret, size_t bytes_to_allocate, void *retp)
+{
+ void *p;
+ size_t bytes_allocated;
+
+ /*
+ * !!!
+ * This function MUST handle a NULL WT_SESSION_IMPL handle.
+ *
+ * Sometimes we're allocating memory and we don't care about the
+ * final length -- bytes_allocated_ret may be NULL.
+ */
+ p = *(void **)retp;
+ bytes_allocated =
+ (bytes_allocated_ret == NULL) ? 0 : *bytes_allocated_ret;
+ WT_ASSERT(session,
+ (p == NULL && bytes_allocated == 0) ||
+ (p != NULL &&
+ (bytes_allocated_ret == NULL || bytes_allocated != 0)));
+ WT_ASSERT(session, bytes_to_allocate != 0);
+ WT_ASSERT(session, bytes_allocated < bytes_to_allocate);
+
+ if (session != NULL) {
+ if (p == NULL)
+ WT_STAT_FAST_CONN_INCR(session, memory_allocation);
+ else
+ WT_STAT_FAST_CONN_INCR(session, memory_grow);
+ }
+
+ if ((p = realloc(p, bytes_to_allocate)) == NULL)
+ WT_RET_MSG(session, __wt_errno(), "memory allocation");
+
+ /*
+ * Clear the allocated memory -- an application might: allocate memory,
+ * write secret stuff into it, free the memory, then we re-allocate the
+ * memory and use it for a file page or log record, and then write it to
+ * disk. That would result in the secret stuff being protected by the
+ * WiredTiger permission mechanisms, potentially inappropriate for the
+ * secret stuff.
+ */
+ memset((uint8_t *)
+ p + bytes_allocated, 0, bytes_to_allocate - bytes_allocated);
+
+ /* Update caller's bytes allocated value. */
+ if (bytes_allocated_ret != NULL)
+ *bytes_allocated_ret = bytes_to_allocate;
+
+ *(void **)retp = p;
+ return (0);
+}
+
+/*
+ * __wt_realloc_aligned --
+ * ANSI realloc function that aligns to buffer boundaries, configured with
+ * the "buffer_alignment" key to wiredtiger_open.
+ */
+int
+__wt_realloc_aligned(WT_SESSION_IMPL *session,
+ size_t *bytes_allocated_ret, size_t bytes_to_allocate, void *retp)
+{
+#if defined(HAVE_POSIX_MEMALIGN)
+ WT_DECL_RET;
+
+ /*
+ * !!!
+ * This function MUST handle a NULL WT_SESSION_IMPL handle.
+ */
+ if (session != NULL && S2C(session)->buffer_alignment > 0) {
+ void *p, *newp;
+ size_t bytes_allocated;
+
+ /*
+ * Sometimes we're allocating memory and we don't care about the
+ * final length -- bytes_allocated_ret may be NULL.
+ */
+ p = *(void **)retp;
+ bytes_allocated =
+ (bytes_allocated_ret == NULL) ? 0 : *bytes_allocated_ret;
+ WT_ASSERT(session,
+ (p == NULL && bytes_allocated == 0) ||
+ (p != NULL &&
+ (bytes_allocated_ret == NULL || bytes_allocated != 0)));
+ WT_ASSERT(session, bytes_to_allocate != 0);
+ WT_ASSERT(session, bytes_allocated < bytes_to_allocate);
+
+ if (session != NULL)
+ WT_STAT_FAST_CONN_INCR(session, memory_allocation);
+
+ if ((ret = posix_memalign(&newp,
+ S2C(session)->buffer_alignment,
+ bytes_to_allocate)) != 0)
+ WT_RET_MSG(session, ret, "memory allocation");
+
+ if (p != NULL)
+ memcpy(newp, p, bytes_allocated);
+ __wt_free(session, p);
+ p = newp;
+
+ /* Clear the allocated memory (see above). */
+ memset((uint8_t *)p + bytes_allocated, 0,
+ bytes_to_allocate - bytes_allocated);
+
+ /* Update caller's bytes allocated value. */
+ if (bytes_allocated_ret != NULL)
+ *bytes_allocated_ret = bytes_to_allocate;
+
+ *(void **)retp = p;
+ return (0);
+ }
+#endif
+ /*
+ * If there is no posix_memalign function, or no alignment configured,
+ * fall back to realloc.
+ *
+ * Windows note: Visual C CRT memalign does not match Posix behavior
+ * and would also double each allocation so it is bad for memory use
+ */
+ return (__wt_realloc(
+ session, bytes_allocated_ret, bytes_to_allocate, retp));
+}
+
+/*
+ * __wt_strndup --
+ * Duplicate a byte string of a given length (and NUL-terminate).
+ */
+int
+__wt_strndup(WT_SESSION_IMPL *session, const void *str, size_t len, void *retp)
+{
+ void *p;
+
+ if (str == NULL) {
+ *(void **)retp = NULL;
+ return (0);
+ }
+
+ WT_RET(__wt_calloc(session, len + 1, 1, &p));
+
+ /*
+ * Don't change this to strncpy, we rely on this function to duplicate
+ * "strings" that contain nul bytes.
+ */
+ memcpy(p, str, len);
+
+ *(void **)retp = p;
+ return (0);
+}
+
+/*
+ * __wt_strdup --
+ * ANSI strdup function.
+ */
+int
+__wt_strdup(WT_SESSION_IMPL *session, const char *str, void *retp)
+{
+ return (__wt_strndup(
+ session, str, (str == NULL) ? 0 : strlen(str), retp));
+}
+
+/*
+ * __wt_free_int --
+ * ANSI free function.
+ */
+void
+__wt_free_int(WT_SESSION_IMPL *session, const void *p_arg)
+{
+ void *p;
+
+ p = *(void **)p_arg;
+ if (p == NULL) /* ANSI C free semantics */
+ return;
+
+ /*
+ * If there's a serialization bug we might race with another thread.
+ * We can't avoid the race (and we aren't willing to flush memory),
+ * but we minimize the window by clearing the free address, hoping a
+ * racing thread will see, and won't free, a NULL pointer.
+ */
+ *(void **)p_arg = NULL;
+
+ /*
+ * !!!
+ * This function MUST handle a NULL WT_SESSION_IMPL handle.
+ */
+ if (session != NULL)
+ WT_STAT_FAST_CONN_INCR(session, memory_free);
+
+ free(p);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_dir.c b/src/third_party/wiredtiger/src/os_posix/os_dir.c
new file mode 100644
index 00000000000..98b2d4926cd
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_dir.c
@@ -0,0 +1,94 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+/* I'm sure we need to config this */
+#include <dirent.h>
+
+/*
+ * __wt_dirlist --
+ * Get a list of files from a directory, optionally filtered by
+ * a given prefix.
+ */
+int
+__wt_dirlist(WT_SESSION_IMPL *session, const char *dir, const char *prefix,
+ uint32_t flags, char ***dirlist, u_int *countp)
+{
+ struct dirent *dp;
+ DIR *dirp;
+ WT_DECL_RET;
+ size_t dirallocsz;
+ u_int count, dirsz;
+ int match;
+ char **entries, *path;
+
+ *dirlist = NULL;
+ *countp = 0;
+
+ WT_RET(__wt_filename(session, dir, &path));
+
+ dirp = NULL;
+ dirallocsz = 0;
+ dirsz = 0;
+ entries = NULL;
+ if (flags == 0)
+ LF_SET(WT_DIRLIST_INCLUDE);
+
+ WT_ERR(__wt_verbose(session, WT_VERB_FILEOPS,
+ "wt_dirlist of %s %s prefix %s",
+ path, LF_ISSET(WT_DIRLIST_INCLUDE) ? "include" : "exclude",
+ prefix == NULL ? "all" : prefix));
+
+ WT_SYSCALL_RETRY(((dirp = opendir(path)) == NULL ? 1 : 0), ret);
+ if (ret != 0)
+ WT_ERR_MSG(session, ret, "%s: opendir", path);
+ for (dirsz = 0, count = 0; (dp = readdir(dirp)) != NULL;) {
+ /*
+ * Skip . and ..
+ */
+ if (strcmp(dp->d_name, ".") == 0 ||
+ strcmp(dp->d_name, "..") == 0)
+ continue;
+ match = 0;
+ 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 = 1;
+ 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 (count > 0)
+ *dirlist = 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_RET_MSG(session, ret, "dirlist %s prefix %s", dir, prefix);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_dlopen.c b/src/third_party/wiredtiger/src/os_posix/os_dlopen.c
new file mode 100644
index 00000000000..91410c54c04
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_dlopen.c
@@ -0,0 +1,83 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_dlopen --
+ * Open a dynamic library.
+ */
+int
+__wt_dlopen(WT_SESSION_IMPL *session, const char *path, WT_DLH **dlhp)
+{
+ WT_DECL_RET;
+ WT_DLH *dlh;
+
+ WT_RET(__wt_calloc_def(session, 1, &dlh));
+ WT_ERR(__wt_strdup(session, path, &dlh->name));
+
+ if ((dlh->handle = dlopen(path, RTLD_LAZY)) == NULL)
+ WT_ERR_MSG(
+ session, __wt_errno(), "dlopen(%s): %s", path, dlerror());
+
+ *dlhp = dlh;
+ if (0) {
+err: __wt_free(session, dlh->name);
+ __wt_free(session, dlh);
+ }
+ return (ret);
+}
+
+/*
+ * __wt_dlsym --
+ * Lookup a symbol in a dynamic library.
+ */
+int
+__wt_dlsym(WT_SESSION_IMPL *session,
+ WT_DLH *dlh, const char *name, int fail, void *sym_ret)
+{
+ void *sym;
+
+ *(void **)sym_ret = NULL;
+ if ((sym = dlsym(dlh->handle, name)) == NULL) {
+ if (fail)
+ WT_RET_MSG(session, __wt_errno(),
+ "dlsym(%s in %s): %s", name, dlh->name, dlerror());
+ return (0);
+ }
+
+ *(void **)sym_ret = sym;
+ return (0);
+}
+
+/*
+ * __wt_dlclose --
+ * Close a dynamic library
+ */
+int
+__wt_dlclose(WT_SESSION_IMPL *session, WT_DLH *dlh)
+{
+ WT_DECL_RET;
+
+ /*
+ * FreeBSD dies inside __cxa_finalize when closing handles.
+ *
+ * For now, just skip the dlclose: this may leak some resources until
+ * the process exits, but that is preferable to hard-to-debug crashes
+ * during exit.
+ */
+#ifndef __FreeBSD__
+ if (dlclose(dlh->handle) != 0) {
+ ret = __wt_errno();
+ __wt_err(session, ret, "dlclose: %s", dlerror());
+ }
+#endif
+
+ __wt_free(session, dlh->name);
+ __wt_free(session, dlh);
+ return (ret);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_errno.c b/src/third_party/wiredtiger/src/os_posix/os_errno.c
new file mode 100644
index 00000000000..9290f7d651f
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_errno.c
@@ -0,0 +1,22 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_errno --
+ * Return errno, or WT_ERROR if errno not set.
+ */
+int
+__wt_errno(void)
+{
+ /*
+ * Called when we know an error occurred, and we want the system
+ * error code, but there's some chance it's not set.
+ */
+ return (errno == 0 ? WT_ERROR : errno);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_exist.c b/src/third_party/wiredtiger/src/os_posix/os_exist.c
new file mode 100644
index 00000000000..723f07026e1
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_exist.c
@@ -0,0 +1,37 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_exist --
+ * Return if the file exists.
+ */
+int
+__wt_exist(WT_SESSION_IMPL *session, const char *filename, int *existp)
+{
+ struct stat sb;
+ WT_DECL_RET;
+ char *path;
+
+ WT_RET(__wt_filename(session, filename, &path));
+
+ WT_SYSCALL_RETRY(stat(path, &sb), ret);
+
+ __wt_free(session, path);
+
+ if (ret == 0) {
+ *existp = 1;
+ return (0);
+ }
+ if (ret == ENOENT) {
+ *existp = 0;
+ return (0);
+ }
+
+ WT_RET_MSG(session, ret, "%s: fstat", filename);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_fallocate.c b/src/third_party/wiredtiger/src/os_posix/os_fallocate.c
new file mode 100644
index 00000000000..28cd1979c77
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_fallocate.c
@@ -0,0 +1,97 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+#if defined(HAVE_FALLOCATE)
+#include <linux/falloc.h>
+#endif
+
+/*
+ * __wt_fallocate_config --
+ * Configure fallocate behavior for a file handle.
+ */
+void
+__wt_fallocate_config(WT_SESSION_IMPL *session, WT_FH *fh)
+{
+ WT_UNUSED(session);
+
+ fh->fallocate_available = 0;
+ fh->fallocate_requires_locking = 0;
+
+#ifdef __linux__
+ /*
+ * We've seen Linux systems where posix_fallocate corrupts existing data
+ * (even though that is explicitly disallowed by POSIX). We've not seen
+ * problems with fallocate, it's unlocked for now.
+ */
+#if defined(HAVE_FALLOCATE)
+ fh->fallocate_available = 1;
+ fh->fallocate_requires_locking = 0;
+#elif defined(HAVE_POSIX_FALLOCATE)
+ fh->fallocate_available = 1;
+ fh->fallocate_requires_locking = 1;
+#endif
+#elif defined(HAVE_POSIX_FALLOCATE)
+ /*
+ * FreeBSD and Solaris support posix_fallocate, and so far we've seen
+ * no problems leaving it unlocked.
+ */
+ fh->fallocate_available = 1;
+ fh->fallocate_requires_locking = 0;
+#endif
+}
+
+/*
+ * __wt_fallocate --
+ * Allocate space for a file handle.
+ */
+int
+__wt_fallocate(
+ WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t offset, wt_off_t len)
+{
+ WT_DECL_RET;
+
+#if defined(HAVE_FALLOCATE)
+ WT_RET(__wt_verbose(
+ session, WT_VERB_FILEOPS, "%s: fallocate", fh->name));
+ WT_SYSCALL_RETRY(
+ fallocate(fh->fd, FALLOC_FL_KEEP_SIZE, offset, len), ret);
+ if (ret == 0)
+ return (0);
+
+ /*
+ * Linux returns ENOTSUP for fallocate on some file systems; we return
+ * ENOTSUP, and our caller should avoid calling us again.
+ */
+ if (ret != ENOTSUP)
+ WT_RET_MSG(session, ret, "%s: fallocate", fh->name);
+#elif defined(HAVE_POSIX_FALLOCATE)
+ WT_RET(__wt_verbose(
+ session, WT_VERB_FILEOPS, "%s: posix_fallocate", fh->name));
+ WT_SYSCALL_RETRY(posix_fallocate(fh->fd, offset, len), ret);
+ if (ret == 0)
+ return (0);
+
+ /*
+ * Solaris returns EINVAL for posix_fallocate on some file systems; we
+ * return ENOTSUP, and our caller should avoid calling us again.
+ */
+ if (ret != EINVAL)
+ WT_RET_MSG(session, ret, "%s: posix_fallocate", fh->name);
+#else
+ WT_UNUSED(session);
+ WT_UNUSED(fh);
+ WT_UNUSED(offset);
+ WT_UNUSED(len);
+ WT_UNUSED(ret);
+#endif
+
+ fh->fallocate_available = 0;
+ fh->fallocate_requires_locking = 0;
+ return (ENOTSUP);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_filesize.c b/src/third_party/wiredtiger/src/os_posix/os_filesize.c
new file mode 100644
index 00000000000..3692b135d73
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_filesize.c
@@ -0,0 +1,55 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_filesize --
+ * Get the size of a file in bytes.
+ */
+int
+__wt_filesize(WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t *sizep)
+{
+ struct stat sb;
+ WT_DECL_RET;
+
+ WT_RET(__wt_verbose(session, WT_VERB_FILEOPS, "%s: fstat", fh->name));
+
+ WT_SYSCALL_RETRY(fstat(fh->fd, &sb), ret);
+ if (ret == 0) {
+ *sizep = sb.st_size;
+ return (0);
+ }
+
+ WT_RET_MSG(session, ret, "%s: fstat", fh->name);
+}
+
+/*
+ * __wt_filesize_name --
+ * Return the size of a file in bytes, given a file name.
+ */
+int
+__wt_filesize_name(
+ WT_SESSION_IMPL *session, const char *filename, wt_off_t *sizep)
+{
+ struct stat sb;
+ WT_DECL_RET;
+ char *path;
+
+ WT_RET(__wt_filename(session, filename, &path));
+
+ WT_SYSCALL_RETRY(stat(path, &sb), ret);
+
+ __wt_free(session, path);
+
+ if (ret == 0) {
+ *sizep = sb.st_size;
+ return (0);
+ }
+
+ WT_RET_MSG(session, ret, "%s: fstat", filename);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_flock.c b/src/third_party/wiredtiger/src/os_posix/os_flock.c
new file mode 100644
index 00000000000..e9e653d73e6
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_flock.c
@@ -0,0 +1,37 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_bytelock --
+ * Lock/unlock a byte in a file.
+ */
+int
+__wt_bytelock(WT_FH *fhp, wt_off_t byte, int lock)
+{
+ struct flock fl;
+ WT_DECL_RET;
+
+ /*
+ * WiredTiger requires this function be able to acquire locks past
+ * the end of file.
+ *
+ * Note we're using fcntl(2) locking: all fcntl locks associated with a
+ * file for a given process are removed when any file descriptor for the
+ * file is closed by the process, even if a lock was never requested for
+ * that file descriptor.
+ */
+ fl.l_start = byte;
+ fl.l_len = 1;
+ fl.l_type = lock ? F_WRLCK : F_UNLCK;
+ fl.l_whence = SEEK_SET;
+
+ WT_SYSCALL_RETRY(fcntl(fhp->fd, F_SETLK, &fl), ret);
+
+ return (ret);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_fsync.c b/src/third_party/wiredtiger/src/os_posix/os_fsync.c
new file mode 100644
index 00000000000..c181809df95
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_fsync.c
@@ -0,0 +1,54 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_fsync --
+ * Flush a file handle.
+ */
+int
+__wt_fsync(WT_SESSION_IMPL *session, WT_FH *fh)
+{
+ WT_DECL_RET;
+
+ WT_RET(__wt_verbose(session, WT_VERB_FILEOPS, "%s: fsync", fh->name));
+
+#ifdef HAVE_FDATASYNC
+ WT_SYSCALL_RETRY(fdatasync(fh->fd), ret);
+#else
+ WT_SYSCALL_RETRY(fsync(fh->fd), ret);
+#endif
+ if (ret != 0)
+ WT_RET_MSG(session, ret, "%s fsync error", fh->name);
+
+ return (0);
+}
+
+/*
+ * __wt_fsync_async --
+ * Flush a file handle and don't wait for the result.
+ */
+int
+__wt_fsync_async(WT_SESSION_IMPL *session, WT_FH *fh)
+{
+#ifdef HAVE_SYNC_FILE_RANGE
+ WT_DECL_RET;
+
+ WT_RET(__wt_verbose(
+ session, WT_VERB_FILEOPS, "%s: sync_file_range", fh->name));
+
+ if ((ret = sync_file_range(fh->fd,
+ (off64_t)0, (off64_t)0, SYNC_FILE_RANGE_WRITE)) == 0)
+ return (0);
+ WT_RET_MSG(session, ret, "%s: sync_file_range", fh->name);
+#else
+ WT_UNUSED(session);
+ WT_UNUSED(fh);
+ return (0);
+#endif
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_ftruncate.c b/src/third_party/wiredtiger/src/os_posix/os_ftruncate.c
new file mode 100644
index 00000000000..3f3034de551
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_ftruncate.c
@@ -0,0 +1,26 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_ftruncate --
+ * Truncate a file.
+ */
+int
+__wt_ftruncate(WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t len)
+{
+ WT_DECL_RET;
+
+ WT_SYSCALL_RETRY(ftruncate(fh->fd, len), ret);
+ if (ret == 0) {
+ fh->size = fh->extend_size = len;
+ return (0);
+ }
+
+ WT_RET_MSG(session, ret, "%s ftruncate error", fh->name);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_getline.c b/src/third_party/wiredtiger/src/os_posix/os_getline.c
new file mode 100644
index 00000000000..7ef4065ac3b
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_getline.c
@@ -0,0 +1,48 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_getline --
+ * Get a line from a stream.
+ *
+ * Implementation of the POSIX getline or BSD fgetln functions (finding the
+ * function in a portable way is hard, it's simple enough to write it instead).
+ *
+ * Note: Unlike the standard getline calls, this function doesn't include the
+ * trailing newline character in the returned buffer and discards empty lines
+ * (so the caller's EOF marker is a returned line length of 0).
+ */
+int
+__wt_getline(WT_SESSION_IMPL *session, WT_ITEM *buf, FILE *fp)
+{
+ int c;
+
+ /*
+ * We always NUL-terminate the returned string (even if it's empty),
+ * make sure there's buffer space for a trailing NUL in all cases.
+ */
+ WT_RET(__wt_buf_init(session, buf, 100));
+
+ while ((c = fgetc(fp)) != EOF) {
+ /* Leave space for a trailing NUL. */
+ WT_RET(__wt_buf_extend(session, buf, buf->size + 2));
+ if (c == '\n') {
+ if (buf->size == 0)
+ continue;
+ break;
+ }
+ ((char *)buf->mem)[buf->size++] = (char)c;
+ }
+ if (c == EOF && ferror(fp))
+ WT_RET_MSG(session, __wt_errno(), "file read");
+
+ ((char *)buf->mem)[buf->size] = '\0';
+
+ return (0);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_getopt.c b/src/third_party/wiredtiger/src/os_posix/os_getopt.c
new file mode 100644
index 00000000000..1c25521dacd
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_getopt.c
@@ -0,0 +1,150 @@
+/*-
+ * Public Domain 2008-2014 WiredTiger, Inc.
+ *
+ * This is free and unencumbered software released into the public domain.
+ *
+ * Anyone is free to copy, modify, publish, use, compile, sell, or
+ * distribute this software, either in source code form or as a compiled
+ * binary, for any purpose, commercial or non-commercial, and by any
+ * means.
+ *
+ * In jurisdictions that recognize copyright laws, the author or authors
+ * of this software dedicate any and all copyright interest in the
+ * software to the public domain. We make this dedication for the benefit
+ * of the public at large and to the detriment of our heirs and
+ * successors. We intend this dedication to be an overt act of
+ * relinquishment in perpetuity of all present and future rights to this
+ * software under copyright law.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/* $NetBSD: getopt.c,v 1.26 2003/08/07 16:43:40 agc Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "wt_internal.h"
+
+extern int __wt_opterr, __wt_optind, __wt_optopt, __wt_optreset;
+int __wt_opterr = 1, /* if error message should be printed */
+ __wt_optind = 1, /* index into parent argv vector */
+ __wt_optopt, /* character checked for validity */
+ __wt_optreset; /* reset getopt */
+
+extern char *__wt_optarg;
+char *__wt_optarg; /* argument associated with option */
+
+#define BADCH (int)'?'
+#define BADARG (int)':'
+#define EMSG ""
+
+/*
+ * __wt_getopt --
+ * Parse argc/argv argument vector.
+ */
+int
+__wt_getopt(
+ const char *progname, int nargc, char * const *nargv, const char *ostr)
+{
+ static const char *place = EMSG; /* option letter processing */
+ const char *oli; /* option letter list index */
+
+ if (__wt_optreset || *place == 0) { /* update scanning pointer */
+ __wt_optreset = 0;
+ place = nargv[__wt_optind];
+ if (__wt_optind >= nargc || *place++ != '-') {
+ /* Argument is absent or is not an option */
+ place = EMSG;
+ return (-1);
+ }
+ __wt_optopt = *place++;
+ if (__wt_optopt == '-' && *place == 0) {
+ /* "--" => end of options */
+ ++__wt_optind;
+ place = EMSG;
+ return (-1);
+ }
+ if (__wt_optopt == 0) {
+ /* Solitary '-', treat as a '-' option
+ if the program (eg su) is looking for it. */
+ place = EMSG;
+ if (strchr(ostr, '-') == NULL)
+ return (-1);
+ __wt_optopt = '-';
+ }
+ } else
+ __wt_optopt = *place++;
+
+ /* See if option letter is one the caller wanted... */
+ if (__wt_optopt == ':' || (oli = strchr(ostr, __wt_optopt)) == NULL) {
+ if (*place == 0)
+ ++__wt_optind;
+ if (__wt_opterr && *ostr != ':')
+ (void)fprintf(stderr,
+ "%s: illegal option -- %c\n", progname,
+ __wt_optopt);
+ return (BADCH);
+ }
+
+ /* Does this option need an argument? */
+ if (oli[1] != ':') {
+ /* don't need argument */
+ __wt_optarg = NULL;
+ if (*place == 0)
+ ++__wt_optind;
+ } else {
+ /* Option-argument is either the rest of this argument or the
+ entire next argument. */
+ if (*place)
+ __wt_optarg = (char *)place;
+ else if (nargc > ++__wt_optind)
+ __wt_optarg = nargv[__wt_optind];
+ else {
+ /* option-argument absent */
+ place = EMSG;
+ if (*ostr == ':')
+ return (BADARG);
+ if (__wt_opterr)
+ (void)fprintf(stderr,
+ "%s: option requires an argument -- %c\n",
+ progname, __wt_optopt);
+ return (BADCH);
+ }
+ place = EMSG;
+ ++__wt_optind;
+ }
+ return (__wt_optopt); /* return option letter */
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_map.c b/src/third_party/wiredtiger/src/os_posix/os_map.c
new file mode 100644
index 00000000000..be4d27e96a3
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_map.c
@@ -0,0 +1,136 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_mmap --
+ * Map a file into memory.
+ */
+int
+__wt_mmap(WT_SESSION_IMPL *session,
+ WT_FH *fh, void *mapp, size_t *lenp, void **mappingcookie)
+{
+ void *map;
+ size_t orig_size;
+
+ WT_UNUSED(mappingcookie);
+
+ /*
+ * Record the current size and only map and set that as the length, it
+ * could change between the map call and when we set the return length.
+ * For the same reason we could actually map past the end of the file;
+ * we don't read bytes past the end of the file though, so as long as
+ * the map call succeeds, it's all OK.
+ */
+ orig_size = (size_t)fh->size;
+ if ((map = mmap(NULL, orig_size,
+ PROT_READ,
+#ifdef MAP_NOCORE
+ MAP_NOCORE |
+#endif
+ MAP_PRIVATE,
+ fh->fd, (wt_off_t)0)) == MAP_FAILED) {
+ WT_RET_MSG(session, __wt_errno(),
+ "%s map error: failed to map %" WT_SIZET_FMT " bytes",
+ fh->name, orig_size);
+ }
+ (void)__wt_verbose(session, WT_VERB_FILEOPS,
+ "%s: map %p: %" WT_SIZET_FMT " bytes", fh->name, map, orig_size);
+
+ *(void **)mapp = map;
+ *lenp = orig_size;
+ return (0);
+}
+
+#define WT_VM_PAGESIZE 4096
+
+/*
+ * __wt_mmap_preload --
+ * Cause a section of a memory map to be faulted in.
+ */
+int
+__wt_mmap_preload(WT_SESSION_IMPL *session, const void *p, size_t size)
+{
+#ifdef HAVE_POSIX_MADVISE
+ /* Linux requires the address be aligned to a 4KB boundary. */
+ WT_BM *bm = S2BT(session)->bm;
+ WT_DECL_RET;
+ void *blk = (void *)((uintptr_t)p & ~(uintptr_t)(WT_VM_PAGESIZE - 1));
+ size += WT_PTRDIFF(p, 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) &
+ (uintptr_t)((1<<20) - 1)) < (uintptr_t)blk)
+ return (0);
+ size = WT_MIN(WT_MAX(20 * size, 2 << 20),
+ WT_PTRDIFF((uint8_t *)bm->map + bm->maplen, blk));
+ }
+
+ /*
+ * Manual pages aren't clear on whether alignment is required for the
+ * size, so we will be conservative.
+ */
+ size &= ~(size_t)(WT_VM_PAGESIZE - 1);
+
+ if (size > WT_VM_PAGESIZE &&
+ (ret = posix_madvise(blk, size, POSIX_MADV_WILLNEED)) != 0)
+ WT_RET_MSG(session, ret, "posix_madvise will need");
+#else
+ WT_UNUSED(session);
+ WT_UNUSED(p);
+ WT_UNUSED(size);
+#endif
+
+ return (0);
+}
+
+/*
+ * __wt_mmap_discard --
+ * Discard a chunk of the memory map.
+ */
+int
+__wt_mmap_discard(WT_SESSION_IMPL *session, void *p, size_t size)
+{
+#ifdef HAVE_POSIX_MADVISE
+ /* Linux requires the address be aligned to a 4KB boundary. */
+ WT_DECL_RET;
+ void *blk = (void *)((uintptr_t)p & ~(uintptr_t)(WT_VM_PAGESIZE - 1));
+ size += WT_PTRDIFF(p, blk);
+
+ if ((ret = posix_madvise(blk, size, POSIX_MADV_DONTNEED)) != 0)
+ WT_RET_MSG(session, ret, "posix_madvise don't need");
+#else
+ WT_UNUSED(session);
+ WT_UNUSED(p);
+ WT_UNUSED(size);
+#endif
+ return (0);
+}
+
+/*
+ * __wt_munmap --
+ * Remove a memory mapping.
+ */
+int
+__wt_munmap(WT_SESSION_IMPL *session,
+ WT_FH *fh, void *map, size_t len, void **mappingcookie)
+{
+ WT_UNUSED(mappingcookie);
+
+ WT_RET(__wt_verbose(session, WT_VERB_FILEOPS,
+ "%s: unmap %p: %" WT_SIZET_FMT " bytes", fh->name, map, len));
+
+ if (munmap(map, len) == 0)
+ return (0);
+
+ WT_RET_MSG(session, __wt_errno(),
+ "%s unmap error: failed to unmap %" WT_SIZET_FMT " bytes",
+ fh->name, len);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_mtx_cond.c b/src/third_party/wiredtiger/src/os_posix/os_mtx_cond.c
new file mode 100644
index 00000000000..3a76cceb3f0
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_mtx_cond.c
@@ -0,0 +1,157 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_cond_alloc --
+ * Allocate and initialize a condition variable.
+ */
+int
+__wt_cond_alloc(WT_SESSION_IMPL *session,
+ const char *name, int is_signalled, WT_CONDVAR **condp)
+{
+ WT_CONDVAR *cond;
+ WT_DECL_RET;
+
+ /*
+ * !!!
+ * This function MUST handle a NULL session handle.
+ */
+ WT_RET(__wt_calloc(session, 1, sizeof(WT_CONDVAR), &cond));
+
+ WT_ERR(pthread_mutex_init(&cond->mtx, NULL));
+
+ /* Initialize the condition variable to permit self-blocking. */
+ WT_ERR(pthread_cond_init(&cond->cond, NULL));
+
+ cond->name = name;
+ cond->waiters = is_signalled ? -1 : 0;
+
+ *condp = cond;
+ return (0);
+
+err: __wt_free(session, cond);
+ return (ret);
+}
+
+/*
+ * __wt_cond_wait --
+ * Wait on a mutex, optionally timing out.
+ */
+int
+__wt_cond_wait(WT_SESSION_IMPL *session, WT_CONDVAR *cond, long usecs)
+{
+ struct timespec ts;
+ WT_DECL_RET;
+ int locked;
+
+ locked = 0;
+ WT_ASSERT(session, usecs >= 0);
+
+ /* Fast path if already signalled. */
+ if (WT_ATOMIC_ADD4(cond->waiters, 1) == 0)
+ return (0);
+
+ /*
+ * !!!
+ * This function MUST handle a NULL session handle.
+ */
+ if (session != NULL) {
+ WT_RET(__wt_verbose(session, WT_VERB_MUTEX,
+ "wait %s cond (%p)", cond->name, cond));
+ WT_STAT_FAST_CONN_INCR(session, cond_wait);
+ }
+
+ WT_ERR(pthread_mutex_lock(&cond->mtx));
+ locked = 1;
+
+ if (usecs > 0) {
+ WT_ERR(__wt_epoch(session, &ts));
+ ts.tv_sec += (ts.tv_nsec + 1000 * usecs) / WT_BILLION;
+ ts.tv_nsec = (ts.tv_nsec + 1000 * usecs) % WT_BILLION;
+ ret = pthread_cond_timedwait(&cond->cond, &cond->mtx, &ts);
+ } else
+ ret = pthread_cond_wait(&cond->cond, &cond->mtx);
+
+ /*
+ * Check pthread_cond_wait() return for EINTR, ETIME and
+ * ETIMEDOUT, some systems return these errors.
+ */
+ if (ret == EINTR ||
+#ifdef ETIME
+ ret == ETIME ||
+#endif
+ ret == ETIMEDOUT)
+ ret = 0;
+
+ (void)WT_ATOMIC_SUB4(cond->waiters, 1);
+
+err: if (locked)
+ WT_TRET(pthread_mutex_unlock(&cond->mtx));
+ if (ret == 0)
+ return (0);
+ WT_RET_MSG(session, ret, "pthread_cond_wait");
+}
+
+/*
+ * __wt_cond_signal --
+ * Signal a waiting thread.
+ */
+int
+__wt_cond_signal(WT_SESSION_IMPL *session, WT_CONDVAR *cond)
+{
+ WT_DECL_RET;
+ int locked;
+
+ locked = 0;
+
+ /*
+ * !!!
+ * This function MUST handle a NULL session handle.
+ */
+ if (session != NULL)
+ WT_RET(__wt_verbose(session, WT_VERB_MUTEX,
+ "signal %s cond (%p)", cond->name, cond));
+
+ /* Fast path if already signalled. */
+ if (cond->waiters == -1)
+ return (0);
+
+ if (cond->waiters > 0 || !WT_ATOMIC_CAS4(cond->waiters, 0, -1)) {
+ WT_ERR(pthread_mutex_lock(&cond->mtx));
+ locked = 1;
+ WT_ERR(pthread_cond_broadcast(&cond->cond));
+ }
+
+err: if (locked)
+ WT_TRET(pthread_mutex_unlock(&cond->mtx));
+ if (ret == 0)
+ return (0);
+ WT_RET_MSG(session, ret, "pthread_cond_broadcast");
+}
+
+/*
+ * __wt_cond_destroy --
+ * Destroy a condition variable.
+ */
+int
+__wt_cond_destroy(WT_SESSION_IMPL *session, WT_CONDVAR **condp)
+{
+ WT_CONDVAR *cond;
+ WT_DECL_RET;
+
+ cond = *condp;
+ if (cond == NULL)
+ return (0);
+
+ ret = pthread_cond_destroy(&cond->cond);
+ WT_TRET(pthread_mutex_destroy(&cond->mtx));
+ __wt_free(session, *condp);
+
+ return (ret);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_mtx_rw.c b/src/third_party/wiredtiger/src/os_posix/os_mtx_rw.c
new file mode 100644
index 00000000000..1a692f71dce
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_mtx_rw.c
@@ -0,0 +1,227 @@
+/*-
+ * Public Domain 2008-2014 WiredTiger, Inc.
+ *
+ * This is free and unencumbered software released into the public domain.
+ *
+ * Anyone is free to copy, modify, publish, use, compile, sell, or
+ * distribute this software, either in source code form or as a compiled
+ * binary, for any purpose, commercial or non-commercial, and by any
+ * means.
+ *
+ * In jurisdictions that recognize copyright laws, the author or authors
+ * of this software dedicate any and all copyright interest in the
+ * software to the public domain. We make this dedication for the benefit
+ * of the public at large and to the detriment of our heirs and
+ * successors. We intend this dedication to be an overt act of
+ * relinquishment in perpetuity of all present and future rights to this
+ * software under copyright law.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR
+ * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
+ * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+ * OTHER DEALINGS IN THE SOFTWARE.
+ */
+
+/*
+ * Based on "Spinlocks and Read-Write Locks" by Dr. Steven Fuerst:
+ * http://locklessinc.com/articles/locks/
+ *
+ * Dr. Fuerst further credits:
+ * There exists a form of the ticket lock that is designed for read-write
+ * locks. An example written in assembly was posted to the Linux kernel mailing
+ * list in 2002 by David Howells from RedHat. This was a highly optimized
+ * version of a read-write ticket lock developed at IBM in the early 90's by
+ * Joseph Seigh. Note that a similar (but not identical) algorithm was published
+ * by John Mellor-Crummey and Michael Scott in their landmark paper "Scalable
+ * Reader-Writer Synchronization for Shared-Memory Multiprocessors".
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_rwlock_alloc --
+ * Allocate and initialize a read/write lock.
+ */
+int
+__wt_rwlock_alloc(
+ WT_SESSION_IMPL *session, WT_RWLOCK **rwlockp, const char *name)
+{
+ WT_RWLOCK *rwlock;
+
+ WT_RET(__wt_verbose(session, WT_VERB_MUTEX, "rwlock: alloc %s", name));
+
+ WT_RET(__wt_calloc_def(session, 1, &rwlock));
+
+ rwlock->name = name;
+
+ *rwlockp = rwlock;
+ return (0);
+}
+
+/*
+ * __wt_try_readlock --
+ * Try to get a shared lock, fail immediately if unavailable.
+ */
+int
+__wt_try_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock)
+{
+ wt_rwlock_t *l;
+ uint64_t old, new, pad, users, writers;
+
+ WT_RET(__wt_verbose(
+ session, WT_VERB_MUTEX, "rwlock: try_readlock %s", rwlock->name));
+ WT_STAT_FAST_CONN_INCR(session, rwlock_read);
+
+ l = &rwlock->rwlock;
+ pad = l->s.pad;
+ users = l->s.users;
+ writers = l->s.writers;
+ old = (pad << 48) + (users << 32) + (users << 16) + writers;
+ new = (pad << 48) + ((users + 1) << 32) + ((users + 1) << 16) + writers;
+ return (WT_ATOMIC_CAS_VAL8(l->u, old, new) == old ? 0 : EBUSY);
+}
+
+/*
+ * __wt_readlock --
+ * Get a shared lock.
+ */
+int
+__wt_readlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock)
+{
+ wt_rwlock_t *l;
+ uint64_t me;
+ uint16_t val;
+
+ WT_RET(__wt_verbose(
+ session, WT_VERB_MUTEX, "rwlock: readlock %s", rwlock->name));
+ WT_STAT_FAST_CONN_INCR(session, rwlock_read);
+
+ l = &rwlock->rwlock;
+ me = WT_ATOMIC_FETCH_ADD8(l->u, (uint64_t)1 << 32);
+ val = (uint16_t)(me >> 32);
+ while (val != l->s.readers)
+ WT_PAUSE();
+
+ ++l->s.readers;
+
+ return (0);
+}
+
+/*
+ * __wt_readunlock --
+ * Release a shared lock.
+ */
+int
+__wt_readunlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock)
+{
+ wt_rwlock_t *l;
+
+ WT_RET(__wt_verbose(
+ session, WT_VERB_MUTEX, "rwlock: read unlock %s", rwlock->name));
+
+ l = &rwlock->rwlock;
+ WT_ATOMIC_ADD2(l->s.writers, 1);
+
+ return (0);
+}
+
+/*
+ * __wt_try_writelock --
+ * Try to get an exclusive lock, fail immediately if unavailable.
+ */
+int
+__wt_try_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock)
+{
+ wt_rwlock_t *l;
+ uint64_t old, new, pad, readers, users;
+
+ WT_RET(__wt_verbose(
+ session, WT_VERB_MUTEX, "rwlock: try_writelock %s", rwlock->name));
+ WT_STAT_FAST_CONN_INCR(session, rwlock_write);
+
+ l = &rwlock->rwlock;
+ pad = l->s.pad;
+ readers = l->s.readers;
+ users = l->s.users;
+ old = (pad << 48) + (users << 32) + (readers << 16) + users;
+ new = (pad << 48) + ((users + 1) << 32) + (readers << 16) + users;
+ return (WT_ATOMIC_CAS_VAL8(l->u, old, new) == old ? 0 : EBUSY);
+}
+
+/*
+ * __wt_writelock --
+ * Wait to get an exclusive lock.
+ */
+int
+__wt_writelock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock)
+{
+ wt_rwlock_t *l;
+ uint64_t me;
+ uint16_t val;
+
+ WT_RET(__wt_verbose(
+ session, WT_VERB_MUTEX, "rwlock: writelock %s", rwlock->name));
+ WT_STAT_FAST_CONN_INCR(session, rwlock_write);
+
+ /*
+ * Possibly wrap: if we have more than 64K lockers waiting, the count
+ * of writers will wrap and two lockers will simultaneously be granted
+ * the write lock.
+ */
+ l = &rwlock->rwlock;
+ me = WT_ATOMIC_FETCH_ADD8(l->u, (uint64_t)1 << 32);
+ val = (uint16_t)(me >> 32);
+ while (val != l->s.writers)
+ WT_PAUSE();
+
+ return (0);
+}
+
+/*
+ * __wt_writeunlock --
+ * Release an exclusive lock.
+ */
+int
+__wt_writeunlock(WT_SESSION_IMPL *session, WT_RWLOCK *rwlock)
+{
+ wt_rwlock_t *l, copy;
+
+ WT_RET(__wt_verbose(
+ session, WT_VERB_MUTEX, "rwlock: writeunlock %s", rwlock->name));
+
+ l = &rwlock->rwlock;
+
+ copy = *l;
+
+ WT_BARRIER();
+
+ ++copy.s.writers;
+ ++copy.s.readers;
+
+ l->us = copy.us;
+ return (0);
+}
+
+/*
+ * __wt_rwlock_destroy --
+ * Destroy a read/write lock.
+ */
+int
+__wt_rwlock_destroy(WT_SESSION_IMPL *session, WT_RWLOCK **rwlockp)
+{
+ WT_RWLOCK *rwlock;
+
+ rwlock = *rwlockp; /* Clear our caller's reference. */
+ if (rwlock == NULL)
+ return (0);
+ *rwlockp = NULL;
+
+ WT_RET(__wt_verbose(
+ session, WT_VERB_MUTEX, "rwlock: destroy %s", rwlock->name));
+
+ __wt_free(session, rwlock);
+ return (0);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_once.c b/src/third_party/wiredtiger/src/os_posix/os_once.c
new file mode 100644
index 00000000000..22eaf5f0ee5
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_once.c
@@ -0,0 +1,20 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_once --
+ * One-time initialization per process.
+ */
+int
+__wt_once(void (*init_routine)(void))
+{
+ static pthread_once_t once_control = PTHREAD_ONCE_INIT;
+
+ return (pthread_once(&once_control, init_routine));
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_open.c b/src/third_party/wiredtiger/src/os_posix/os_open.c
new file mode 100644
index 00000000000..a1bc3feb7d2
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_open.c
@@ -0,0 +1,253 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __open_directory_sync --
+ * Fsync the directory in which we created the file.
+ */
+static int
+__open_directory_sync(WT_SESSION_IMPL *session, char *path)
+{
+#ifdef __linux__
+ WT_DECL_RET;
+ int fd;
+ char *dir;
+
+ /*
+ * According to the Linux fsync man page:
+ * Calling fsync() does not necessarily ensure that the entry in
+ * the directory containing the file has also reached disk. For
+ * that an explicit fsync() on a file descriptor for the directory
+ * is also needed.
+ *
+ * Open the WiredTiger home directory and sync it, I don't want the rest
+ * of the system to have to wonder if opening a file creates it.
+ */
+ if ((dir = strrchr(path, '/')) == NULL)
+ path = (char *)".";
+ else
+ *dir = '\0';
+ WT_SYSCALL_RETRY(((fd =
+ open(path, O_RDONLY, 0444)) == -1 ? 1 : 0), ret);
+ if (dir != NULL)
+ *dir = '/';
+ if (ret != 0)
+ WT_RET_MSG(session, ret, "%s: open", path);
+
+ WT_SYSCALL_RETRY(fsync(fd), ret);
+ if (ret != 0)
+ WT_ERR_MSG(session, ret, "%s: fsync", path);
+
+err: WT_SYSCALL_RETRY(close(fd), ret);
+ if (ret != 0)
+ __wt_err(session, ret, "%s: close", path);
+ return (ret);
+#else
+ WT_UNUSED(session);
+ WT_UNUSED(path);
+ return (0);
+#endif
+}
+
+/*
+ * __wt_open --
+ * Open a file handle.
+ */
+int
+__wt_open(WT_SESSION_IMPL *session,
+ const char *name, int ok_create, int exclusive, int dio_type, WT_FH **fhp)
+{
+ WT_CONNECTION_IMPL *conn;
+ WT_DECL_RET;
+ WT_FH *fh, *tfh;
+ mode_t mode;
+ int direct_io, f, fd, matched;
+ char *path;
+
+ conn = S2C(session);
+ fh = NULL;
+ fd = -1;
+ path = NULL;
+
+ WT_RET(__wt_verbose(session, WT_VERB_FILEOPS, "%s: open", name));
+
+ /* Increment the reference count if we already have the file open. */
+ matched = 0;
+ __wt_spin_lock(session, &conn->fh_lock);
+ TAILQ_FOREACH(tfh, &conn->fhqh, q)
+ if (strcmp(name, tfh->name) == 0) {
+ ++tfh->ref;
+ *fhp = tfh;
+ matched = 1;
+ break;
+ }
+ __wt_spin_unlock(session, &conn->fh_lock);
+ if (matched)
+ return (0);
+
+ WT_RET(__wt_filename(session, name, &path));
+
+ f = O_RDWR;
+#ifdef O_BINARY
+ /* Windows clones: we always want to treat the file as a binary. */
+ f |= O_BINARY;
+#endif
+#ifdef O_CLOEXEC
+ /*
+ * Security:
+ * The application may spawn a new process, and we don't want another
+ * process to have access to our file handles.
+ */
+ f |= O_CLOEXEC;
+#endif
+#ifdef O_NOATIME
+ /* Avoid updating metadata for read-only workloads. */
+ if (dio_type == WT_FILE_TYPE_DATA ||
+ dio_type == WT_FILE_TYPE_CHECKPOINT)
+ f |= O_NOATIME;
+#endif
+
+ if (ok_create) {
+ f |= O_CREAT;
+ if (exclusive)
+ f |= O_EXCL;
+ mode = 0666;
+ } else
+ mode = 0;
+
+ direct_io = 0;
+#ifdef O_DIRECT
+ if (dio_type && FLD_ISSET(conn->direct_io, dio_type)) {
+ f |= O_DIRECT;
+ direct_io = 1;
+ }
+#endif
+ if (dio_type == WT_FILE_TYPE_LOG &&
+ FLD_ISSET(conn->txn_logsync, WT_LOG_DSYNC))
+#ifdef O_DSYNC
+ f |= O_DSYNC;
+#elif defined(O_SYNC)
+ f |= O_SYNC;
+#else
+ WT_ERR_MSG(session, ENOTSUP,
+ "Unsupported log sync mode requested");
+#endif
+ WT_SYSCALL_RETRY(((fd = open(path, f, mode)) == -1 ? 1 : 0), ret);
+ if (ret != 0)
+ WT_ERR_MSG(session, ret,
+ direct_io ?
+ "%s: open failed with direct I/O configured, some "
+ "filesystem types do not support direct I/O" : "%s", path);
+
+#if defined(HAVE_FCNTL) && defined(FD_CLOEXEC) && !defined(O_CLOEXEC)
+ /*
+ * Security:
+ * The application may spawn a new process, and we don't want another
+ * process to have access to our file handles. There's an obvious
+ * race here, so we prefer the flag to open if available.
+ */
+ if ((f = fcntl(fd, F_GETFD)) == -1 ||
+ fcntl(fd, F_SETFD, f | FD_CLOEXEC) == -1)
+ WT_ERR_MSG(session, __wt_errno(), "%s: fcntl", name);
+#endif
+
+#if defined(HAVE_POSIX_FADVISE)
+ /* Disable read-ahead on trees: it slows down random read workloads. */
+ if (dio_type == WT_FILE_TYPE_DATA ||
+ dio_type == WT_FILE_TYPE_CHECKPOINT)
+ WT_ERR(posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM));
+#endif
+
+ if (F_ISSET(conn, WT_CONN_CKPT_SYNC))
+ WT_ERR(__open_directory_sync(session, path));
+
+ WT_ERR(__wt_calloc(session, 1, sizeof(WT_FH), &fh));
+ WT_ERR(__wt_strdup(session, name, &fh->name));
+ fh->fd = fd;
+ fh->ref = 1;
+ fh->direct_io = direct_io;
+
+ /* Set the file's size. */
+ WT_ERR(__wt_filesize(session, fh, &fh->size));
+
+ /* Configure file extension. */
+ if (dio_type == WT_FILE_TYPE_DATA ||
+ dio_type == WT_FILE_TYPE_CHECKPOINT)
+ fh->extend_len = conn->data_extend_len;
+
+ /* Configure fallocate/posix_fallocate calls. */
+ __wt_fallocate_config(session, fh);
+
+ /*
+ * Repeat the check for a match, but then link onto the database's list
+ * of files.
+ */
+ matched = 0;
+ __wt_spin_lock(session, &conn->fh_lock);
+ TAILQ_FOREACH(tfh, &conn->fhqh, q)
+ if (strcmp(name, tfh->name) == 0) {
+ ++tfh->ref;
+ *fhp = tfh;
+ matched = 1;
+ break;
+ }
+ if (!matched) {
+ TAILQ_INSERT_TAIL(&conn->fhqh, fh, q);
+ WT_STAT_FAST_CONN_INCR(session, file_open);
+
+ *fhp = fh;
+ }
+ __wt_spin_unlock(session, &conn->fh_lock);
+ if (matched) {
+err: if (fh != NULL) {
+ __wt_free(session, fh->name);
+ __wt_free(session, fh);
+ }
+ if (fd != -1)
+ (void)close(fd);
+ }
+
+ __wt_free(session, path);
+ return (ret);
+}
+
+/*
+ * __wt_close --
+ * Close a file handle.
+ */
+int
+__wt_close(WT_SESSION_IMPL *session, WT_FH *fh)
+{
+ WT_CONNECTION_IMPL *conn;
+ WT_DECL_RET;
+
+ conn = S2C(session);
+
+ __wt_spin_lock(session, &conn->fh_lock);
+ if (fh == NULL || fh->ref == 0 || --fh->ref > 0) {
+ __wt_spin_unlock(session, &conn->fh_lock);
+ return (0);
+ }
+
+ /* Remove from the list. */
+ TAILQ_REMOVE(&conn->fhqh, fh, q);
+ WT_STAT_FAST_CONN_DECR(session, file_open);
+
+ __wt_spin_unlock(session, &conn->fh_lock);
+
+ /* Discard the memory. */
+ if (close(fh->fd) != 0) {
+ ret = __wt_errno();
+ __wt_err(session, ret, "close: %s", fh->name);
+ }
+
+ __wt_free(session, fh->name);
+ __wt_free(session, fh);
+ return (ret);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_path.c b/src/third_party/wiredtiger/src/os_posix/os_path.c
new file mode 100644
index 00000000000..aed99d1d027
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_path.c
@@ -0,0 +1,28 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_absolute_path --
+ * Return if a filename is an absolute path.
+ */
+int
+__wt_absolute_path(const char *path)
+{
+ return (path[0] == '/' ? 1 : 0);
+}
+
+/*
+ * __wt_path_separator --
+ * Return the path separator string.
+ */
+const char *
+__wt_path_separator(void)
+{
+ return ("/");
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_priv.c b/src/third_party/wiredtiger/src/os_posix/os_priv.c
new file mode 100644
index 00000000000..7d56359da4f
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_priv.c
@@ -0,0 +1,19 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_has_priv --
+ * Return if the process has special privileges, defined as having
+ * different effective and read UIDs or GIDs.
+ */
+int
+__wt_has_priv(void)
+{
+ return (getuid() != geteuid() || getgid() != getegid());
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_remove.c b/src/third_party/wiredtiger/src/os_posix/os_remove.c
new file mode 100644
index 00000000000..a52a4db6bc7
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_remove.c
@@ -0,0 +1,66 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __remove_file_check --
+ * Check if the file is currently open before removing it.
+ */
+static void
+__remove_file_check(WT_SESSION_IMPL *session, const char *name)
+{
+#ifdef HAVE_DIAGNOSTIC
+ WT_CONNECTION_IMPL *conn;
+ WT_FH *fh;
+
+ conn = S2C(session);
+ fh = NULL;
+
+ /*
+ * Check if the file is open: it's an error if it is, since a higher
+ * level should have closed it before removing.
+ */
+ __wt_spin_lock(session, &conn->fh_lock);
+ TAILQ_FOREACH(fh, &conn->fhqh, q) {
+ if (strcmp(name, fh->name) == 0)
+ break;
+ }
+ __wt_spin_unlock(session, &conn->fh_lock);
+
+ WT_ASSERT(session, fh == NULL);
+#else
+ WT_UNUSED(session);
+ WT_UNUSED(name);
+#endif
+}
+
+/*
+ * __wt_remove --
+ * Remove a file.
+ */
+int
+__wt_remove(WT_SESSION_IMPL *session, const char *name)
+{
+ WT_DECL_RET;
+ char *path;
+
+ WT_RET(__wt_verbose(session, WT_VERB_FILEOPS, "%s: remove", name));
+
+ __remove_file_check(session, name);
+
+ WT_RET(__wt_filename(session, name, &path));
+
+ WT_SYSCALL_RETRY(remove(path), ret);
+
+ __wt_free(session, path);
+
+ if (ret == 0 || ret == ENOENT)
+ return (0);
+
+ WT_RET_MSG(session, ret, "%s: remove", name);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_rename.c b/src/third_party/wiredtiger/src/os_posix/os_rename.c
new file mode 100644
index 00000000000..ddbb59aaf37
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_rename.c
@@ -0,0 +1,38 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_rename --
+ * Rename a file.
+ */
+int
+__wt_rename(WT_SESSION_IMPL *session, const char *from, const char *to)
+{
+ WT_DECL_RET;
+ char *from_path, *to_path;
+
+ WT_RET(__wt_verbose(
+ session, WT_VERB_FILEOPS, "rename %s to %s", from, to));
+
+ from_path = to_path = NULL;
+
+ WT_RET(__wt_filename(session, from, &from_path));
+ WT_TRET(__wt_filename(session, to, &to_path));
+
+ if (ret == 0)
+ WT_SYSCALL_RETRY(rename(from_path, to_path), ret);
+
+ __wt_free(session, from_path);
+ __wt_free(session, to_path);
+
+ if (ret == 0)
+ return (0);
+
+ WT_RET_MSG(session, ret, "rename %s to %s", from, to);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_rw.c b/src/third_party/wiredtiger/src/os_posix/os_rw.c
new file mode 100644
index 00000000000..4247fb30fd1
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_rw.c
@@ -0,0 +1,86 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_read --
+ * Read a chunk.
+ */
+int
+__wt_read(
+ WT_SESSION_IMPL *session, WT_FH *fh, wt_off_t offset, size_t len, void *buf)
+{
+ size_t chunk;
+ ssize_t nr;
+ uint8_t *addr;
+
+ WT_STAT_FAST_CONN_INCR(session, read_io);
+
+ WT_RET(__wt_verbose(session, WT_VERB_FILEOPS,
+ "%s: read %" WT_SIZET_FMT " bytes at offset %" PRIuMAX,
+ fh->name, len, (uintmax_t)offset));
+
+ /* Assert direct I/O is aligned and a multiple of the alignment. */
+ WT_ASSERT(session,
+ !fh->direct_io ||
+ S2C(session)->buffer_alignment == 0 ||
+ (!((uintptr_t)buf &
+ (uintptr_t)(S2C(session)->buffer_alignment - 1)) &&
+ len >= S2C(session)->buffer_alignment &&
+ len % S2C(session)->buffer_alignment == 0));
+
+ /* 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)
+ WT_RET_MSG(session, nr == 0 ? WT_ERROR : __wt_errno(),
+ "%s read error: failed to read %" WT_SIZET_FMT
+ " bytes at offset %" PRIuMAX,
+ fh->name, chunk, (uintmax_t)offset);
+ }
+ return (0);
+}
+
+/*
+ * __wt_write --
+ * Write a chunk.
+ */
+int
+__wt_write(WT_SESSION_IMPL *session,
+ WT_FH *fh, wt_off_t offset, size_t len, const void *buf)
+{
+ size_t chunk;
+ ssize_t nw;
+ const uint8_t *addr;
+
+ WT_STAT_FAST_CONN_INCR(session, write_io);
+
+ WT_RET(__wt_verbose(session, WT_VERB_FILEOPS,
+ "%s: write %" WT_SIZET_FMT " bytes at offset %" PRIuMAX,
+ fh->name, len, (uintmax_t)offset));
+
+ /* Assert direct I/O is aligned and a multiple of the alignment. */
+ WT_ASSERT(session,
+ !fh->direct_io ||
+ S2C(session)->buffer_alignment == 0 ||
+ (!((uintptr_t)buf &
+ (uintptr_t)(S2C(session)->buffer_alignment - 1)) &&
+ len >= S2C(session)->buffer_alignment &&
+ len % S2C(session)->buffer_alignment == 0));
+
+ /* 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)
+ WT_RET_MSG(session, __wt_errno(),
+ "%s write error: failed to write %" WT_SIZET_FMT
+ " bytes at offset %" PRIuMAX,
+ fh->name, chunk, (uintmax_t)offset);
+ }
+ return (0);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_sleep.c b/src/third_party/wiredtiger/src/os_posix/os_sleep.c
new file mode 100644
index 00000000000..665330a26e7
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_sleep.c
@@ -0,0 +1,23 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_sleep --
+ * Pause the thread of control.
+ */
+void
+__wt_sleep(long seconds, long micro_seconds)
+{
+ struct timeval t;
+
+ t.tv_sec = seconds + micro_seconds / 1000000;
+ t.tv_usec = (suseconds_t)(micro_seconds % 1000000);
+
+ (void)select(0, NULL, NULL, NULL, &t);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_strtouq.c b/src/third_party/wiredtiger/src/os_posix/os_strtouq.c
new file mode 100644
index 00000000000..97f9759f76f
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_strtouq.c
@@ -0,0 +1,24 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_strtouq --
+ * Convert a string to an unsigned quad integer.
+ */
+uint64_t
+__wt_strtouq(const char *nptr, char **endptr, int base)
+{
+#if defined(HAVE_STRTOUQ)
+ return (strtouq(nptr, endptr, base));
+#else
+ WT_STATIC_ASSERT(sizeof(uint64_t) == sizeof(unsigned long long));
+
+ return (strtoull(nptr, endptr, base));
+#endif
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_thread.c b/src/third_party/wiredtiger/src/os_posix/os_thread.c
new file mode 100644
index 00000000000..7c447710b46
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_thread.c
@@ -0,0 +1,59 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_thread_create --
+ * Create a new thread of control.
+ */
+int
+__wt_thread_create(WT_SESSION_IMPL *session,
+ wt_thread_t *tidret, void *(*func)(void *), void *arg)
+{
+ WT_DECL_RET;
+
+ /* Spawn a new thread of control. */
+ if ((ret = pthread_create(tidret, NULL, func, arg)) == 0)
+ return (0);
+ WT_RET_MSG(session, ret, "pthread_create");
+}
+
+/*
+ * __wt_thread_join --
+ * Wait for a thread of control to exit.
+ */
+int
+__wt_thread_join(WT_SESSION_IMPL *session, wt_thread_t tid)
+{
+ WT_DECL_RET;
+
+ if ((ret = pthread_join(tid, NULL)) == 0)
+ return (0);
+
+ WT_RET_MSG(session, ret, "pthread_join");
+}
+
+/*
+ * __wt_thread_id --
+ * Fill in a printable version of the process and thread IDs.
+ */
+void
+__wt_thread_id(char *buf, size_t buflen)
+{
+ pthread_t self;
+
+ /*
+ * POSIX 1003.1 allows pthread_t to be an opaque type, but on systems
+ * where it's a pointer, we'd rather print out the pointer and match
+ * gdb output. Since we don't yet run on any systems where pthread_t
+ * is not a pointer, do it that way for now.
+ */
+ self = pthread_self();
+ (void)snprintf(buf, buflen,
+ "%" PRIu64 ":%p", (uint64_t)getpid(), (void *)self);
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_time.c b/src/third_party/wiredtiger/src/os_posix/os_time.c
new file mode 100644
index 00000000000..56f688a1e14
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_time.c
@@ -0,0 +1,53 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_seconds --
+ * Return the seconds since the Epoch.
+ */
+int
+__wt_seconds(WT_SESSION_IMPL *session, time_t *timep)
+{
+ struct timespec t;
+
+ WT_RET(__wt_epoch(session, &t));
+
+ *timep = t.tv_sec;
+
+ return (0);
+}
+
+/*
+ * __wt_epoch --
+ * Return the time since the Epoch.
+ */
+int
+__wt_epoch(WT_SESSION_IMPL *session, struct timespec *tsp)
+{
+ WT_DECL_RET;
+
+#if defined(HAVE_CLOCK_GETTIME)
+ WT_SYSCALL_RETRY(clock_gettime(CLOCK_REALTIME, tsp), ret);
+ if (ret == 0)
+ return (0);
+ WT_RET_MSG(session, ret, "clock_gettime");
+#elif defined(HAVE_GETTIMEOFDAY)
+ struct timeval v;
+
+ WT_SYSCALL_RETRY(gettimeofday(&v, NULL), ret);
+ if (ret == 0) {
+ tsp->tv_sec = v.tv_sec;
+ tsp->tv_nsec = v.tv_usec * 1000;
+ return (0);
+ }
+ WT_RET_MSG(session, ret, "gettimeofday");
+#else
+ NO TIME-OF-DAY IMPLEMENTATION: see src/os_posix/os_time.c
+#endif
+}
diff --git a/src/third_party/wiredtiger/src/os_posix/os_yield.c b/src/third_party/wiredtiger/src/os_posix/os_yield.c
new file mode 100644
index 00000000000..6af30803e81
--- /dev/null
+++ b/src/third_party/wiredtiger/src/os_posix/os_yield.c
@@ -0,0 +1,18 @@
+/*-
+ * Copyright (c) 2008-2014 WiredTiger, Inc.
+ * All rights reserved.
+ *
+ * See the file LICENSE for redistribution information.
+ */
+
+#include "wt_internal.h"
+
+/*
+ * __wt_yield --
+ * Yield the thread of control.
+ */
+void
+__wt_yield(void)
+{
+ sched_yield();
+}