Esempio n. 1
0
/*
 * __posix_directory_sync --
 *	Flush a directory to ensure file creation is durable.
 */
static int
__posix_directory_sync(
    WT_FILE_SYSTEM *file_system, WT_SESSION *wt_session, const char *path)
{
	WT_DECL_RET;
	WT_SESSION_IMPL *session;
	int fd, tret;

	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_RET_MSG(session, ret, "%s: directory-sync: open", path);

	ret = __posix_sync(session, fd, path, "directory-sync");

	WT_SYSCALL_RETRY(close(fd), tret);
	if (tret != 0) {
		__wt_err(session, tret, "%s: directory-sync: close", path);
		if (ret == 0)
			ret = tret;
	}
	return (ret);
}
Esempio n. 2
0
/*
 * __open_directory_sync --
 *	Fsync the directory in which we created the file.
 */
static int
__open_directory_sync(WT_SESSION_IMPL *session)
{
#ifdef __linux__
	WT_CONNECTION_IMPL *conn;
	WT_DECL_RET;
	int fd;

	conn = S2C(session);

	/*
	 * 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.
	 */
	WT_SYSCALL_RETRY(((fd =
	    open(conn->home, O_RDONLY, 0444)) == -1 ? 1 : 0), ret);
	if (ret != 0)
		WT_RET_MSG(session, ret, "%s: open", conn->home);
	WT_SYSCALL_RETRY(fsync(fd), ret);
	if (ret != 0)
		WT_ERR_MSG(session, ret, "%s: fsync", conn->home);
err:	WT_SYSCALL_RETRY(close(fd), ret);
	if (ret != 0)
		WT_ERR_MSG(session, ret, "%s: close", conn->home);
#else
	WT_UNUSED(session);
#endif
	return (0);
}
Esempio n. 3
0
/*
 * __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, bool silent, 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);
	}

	/*
	 * Some callers of this function expect failure if the file doesn't
	 * exist, and don't want an error message logged.
	 */
	if (!silent)
		WT_RET_MSG(session, ret, "%s: fstat", filename);
	return (ret);
}
Esempio n. 4
0
/*
 * __posix_file_lock --
 *	Lock/unlock a file.
 */
static int
__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
	 * 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 = 0;
	fl.l_len = 1;
	fl.l_type = lock ? F_WRLCK : F_UNLCK;
	fl.l_whence = SEEK_SET;

	WT_SYSCALL_RETRY(fcntl(pfh->fd, F_SETLK, &fl), ret);
	if (ret == 0)
		return (0);
	WT_RET_MSG(session, ret, "%s: handle-lock: fcntl", file_handle->name);
}
Esempio n. 5
0
/*
 * __posix_sys_fallocate --
 *	Linux fallocate call (system call version).
 */
static int
__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
	 * not found.  The system call actually exists in the kernel for some
	 * 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, pfh->fd, 0, offset, len), ret);
	return (ret);
#else
	WT_UNUSED(file_handle);
	WT_UNUSED(wt_session);
	WT_UNUSED(offset);
	WT_UNUSED(len);
	return (ENOTSUP);
#endif
}
Esempio n. 6
0
/*
 * __posix_file_advise --
 *	POSIX fadvise.
 */
static int
__posix_file_advise(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session,
    wt_off_t offset, wt_off_t len, int advice)
{
	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(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, and reset the
	 * handle method to prevent future calls.
	 */
	if (ret == EINVAL) {
		file_handle->fadvise = NULL;
		return (ENOTSUP);
	}

	WT_RET_MSG(session, ret,
	    "%s: handle-advise: posix_fadvise", file_handle->name);

}
Esempio n. 7
0
/*
 * __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));

	WT_ASSERT(session, !F_ISSET(S2C(session), WT_CONN_READONLY));
	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);
}
Esempio n. 8
0
/*
 * __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);
}
Esempio n. 9
0
/*
 * __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);
}
Esempio n. 10
0
/*
 * __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;

	WT_SYSCALL_RETRY(pthread_join(tid, NULL), ret);
	if (ret == 0)
		return (0);

	WT_RET_MSG(session, ret, "pthread_join");
}
Esempio n. 11
0
/*
 * __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)
		return (0);

	WT_RET_MSG(session, ret, "%s ftruncate error", fh->name);
}
Esempio n. 12
0
File: os_fs.c Progetto: GYGit/mongo
/*
 * __posix_sync --
 *	Underlying support function to flush a file descriptor.
 */
static int
__posix_sync(
    WT_SESSION_IMPL *session, int fd, const char *name, const char *func)
{
	WT_DECL_RET;

#if defined(F_FULLFSYNC)
	/*
	 * OS X fsync documentation:
	 * "Note that while fsync() will flush all data from the host to the
	 * drive (i.e. the "permanent storage device"), the drive itself may
	 * not physically write the data to the platters for quite some time
	 * and it may be written in an out-of-order sequence. For applications
	 * that require tighter guarantees about the integrity of their data,
	 * Mac OS X provides the F_FULLFSYNC fcntl. The F_FULLFSYNC fcntl asks
	 * the drive to flush all buffered data to permanent storage."
	 *
	 * OS X F_FULLFSYNC fcntl documentation:
	 * "This is currently implemented on HFS, MS-DOS (FAT), and Universal
	 * Disk Format (UDF) file systems."
	 */
	WT_SYSCALL_RETRY(fcntl(fd, F_FULLFSYNC, 0) == -1 ? -1 : 0, ret);
	if (ret == 0)
		return (0);
	/*
	 * Assume F_FULLFSYNC failed because the file system doesn't support it
	 * and fallback to fsync.
	 */
#endif
#if defined(HAVE_FDATASYNC)
	WT_SYSCALL_RETRY(fdatasync(fd), ret);
	if (ret == 0)
		return (0);
	WT_RET_MSG(session, ret, "%s: %s: fdatasync", name, func);
#else
	WT_SYSCALL_RETRY(fsync(fd), ret);
	if (ret == 0)
		return (0);
	WT_RET_MSG(session, ret, "%s: %s: fsync", name, func);
#endif
}
Esempio n. 13
0
/*
 * __wt_thread_create --
 *	Create a new thread of control.
 */
int
__wt_thread_create(WT_SESSION_IMPL *session,
    wt_thread_t *tidret, WT_THREAD_CALLBACK(*func)(void *), void *arg)
{
	WT_DECL_RET;

	/* Spawn a new thread of control. */
	WT_SYSCALL_RETRY(pthread_create(tidret, NULL, func, arg), ret);
	if (ret == 0)
		return (0);
	WT_RET_MSG(session, ret, "pthread_create");
}
Esempio n. 14
0
/*
 * __wt_ftruncate --
 *	Truncate a file.
 */
int
__wt_ftruncate(WT_SESSION_IMPL *session, WT_FH *fh, off_t len)
{
	int ret;

	WT_SYSCALL_RETRY(ftruncate(fh->fd, len), ret);
	if (ret == 0) {
		fh->file_size = len;
		return (0);
	}

	WT_RET_MSG(session, ret, "%s ftruncate error", fh->name);
}
Esempio n. 15
0
/*
 * __wt_fsync --
 *	Flush a file handle.
 */
int
__wt_fsync(WT_SESSION_IMPL *session, WT_FH *fh)
{
	WT_DECL_RET;

	WT_VERBOSE_RET(session, fileops, "%s: fsync", fh->name);

	WT_SYSCALL_RETRY(fsync(fh->fd), ret);
	if (ret != 0)
		WT_RET_MSG(session, ret, "%s fsync error", fh->name);

	return (0);
}
Esempio n. 16
0
/*
 * __wt_posix_fallocate --
 *	POSIX fallocate call.
 */
static int
__wt_posix_fallocate(WT_FH *fh, wt_off_t offset, wt_off_t len)
{
#if defined(HAVE_POSIX_FALLOCATE)
	WT_DECL_RET;

	WT_SYSCALL_RETRY(posix_fallocate(fh->fd, offset, len), ret);
	return (ret);
#else
	WT_UNUSED(fh);
	WT_UNUSED(offset);
	WT_UNUSED(len);
	return (ENOTSUP);
#endif
}
Esempio n. 17
0
/*
 * __posix_fs_rename --
 *	Rename a file.
 */
static int
__posix_fs_rename(WT_FILE_SYSTEM *file_system,
    WT_SESSION *wt_session, const char *from, const char *to)
{
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	WT_UNUSED(file_system);

	session = (WT_SESSION_IMPL *)wt_session;

	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);
}
Esempio n. 18
0
/*
 * __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);
}
Esempio n. 19
0
File: os_fs.c Progetto: GYGit/mongo
/*
 * __posix_file_truncate --
 *	POSIX ftruncate.
 */
static int
__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(pfh->fd, len), ret);
	if (ret == 0)
		return (0);
	WT_RET_MSG(session, ret,
	    "%s: handle-truncate: ftruncate", file_handle->name);
}
Esempio n. 20
0
File: os_fs.c Progetto: GYGit/mongo
/*
 * __posix_file_sync_nowait --
 *	POSIX fsync.
 */
static int
__posix_file_sync_nowait(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session)
{
	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(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, ret,
	    "%s: handle-sync-nowait: sync_file_range", file_handle->name);
}
Esempio n. 21
0
/*
 * __posix_file_size --
 *	Get the size of a file in bytes, by file handle.
 */
static int
__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;

	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", file_handle->name);
}
Esempio n. 22
0
/*
 * __posix_fs_size --
 *	Get the size of a file in bytes, by file name.
 */
static int
__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;
	WT_SESSION_IMPL *session;

	WT_UNUSED(file_system);

	session = (WT_SESSION_IMPL *)wt_session;

	WT_SYSCALL_RETRY(stat(name, &sb), ret);
	if (ret == 0) {
		*sizep = sb.st_size;
		return (0);
	}
	WT_RET_MSG(session, ret, "%s: file-size: stat", name);
}
Esempio n. 23
0
/*
 * __wt_rename --
 *	Rename a file.
 */
int
__wt_rename(WT_SESSION_IMPL *session, const char *from, const char *to)
{
	int ret;
	const char *from_path, *to_path;

	WT_VERBOSE(session, fileops, "rename %s to %s", from, to);

	WT_RET(__wt_filename(session, from, &from_path));
	WT_RET(__wt_filename(session, to, &to_path));

	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);
}
Esempio n. 24
0
/*
 * __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);
}
Esempio n. 25
0
/*
 * __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);
}
Esempio n. 26
0
/*
 * __wt_sys_fallocate --
 *	Linux fallocate call (system call version).
 */
static int
__wt_sys_fallocate(WT_FH *fh, wt_off_t offset, wt_off_t len)
{
#if defined(__linux__) && defined(SYS_fallocate)
	WT_DECL_RET;

	/*
	 * Try the system call for fallocate even if the C library wrapper was
	 * not found.  The system call actually exists in the kernel for some
	 * 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);
	return (ret);
#else
	WT_UNUSED(fh);
	WT_UNUSED(offset);
	WT_UNUSED(len);
	return (ENOTSUP);
#endif
}
Esempio n. 27
0
/*
 * __posix_posix_fallocate --
 *	POSIX fallocate call.
 */
static int
__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);

	pfh = (WT_FILE_HANDLE_POSIX *)file_handle;

	WT_SYSCALL_RETRY(posix_fallocate(pfh->fd, offset, len), ret);
	return (ret);
#else
	WT_UNUSED(file_handle);
	WT_UNUSED(wt_session);
	WT_UNUSED(offset);
	WT_UNUSED(len);
	return (ENOTSUP);
#endif
}
Esempio n. 28
0
/*
 * __posix_file_close --
 *	ANSI C close.
 */
static int
__posix_file_close(WT_FILE_HANDLE *file_handle, WT_SESSION *wt_session)
{
	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;

	/* 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);
	}

	__wt_free(session, file_handle->name);
	__wt_free(session, pfh);
	return (ret);
}
Esempio n. 29
0
/*
 * __posix_fs_exist --
 *	Return if the file exists.
 */
static int
__posix_fs_exist(WT_FILE_SYSTEM *file_system,
    WT_SESSION *wt_session, const char *name, bool *existp)
{
	struct stat sb;
	WT_DECL_RET;
	WT_SESSION_IMPL *session;

	WT_UNUSED(file_system);

	session = (WT_SESSION_IMPL *)wt_session;

	WT_SYSCALL_RETRY(stat(name, &sb), ret);
	if (ret == 0) {
		*existp = true;
		return (0);
	}
	if (ret == ENOENT) {
		*existp = false;
		return (0);
	}
	WT_RET_MSG(session, ret, "%s: file-exist: stat", name);
}
Esempio n. 30
0
File: os_fs.c Progetto: GYGit/mongo
/*
 * __posix_directory_sync --
 *	Flush a directory to ensure file creation, remove or rename is durable.
 */
static int
__posix_directory_sync(WT_SESSION_IMPL *session, const char *path)
{
	WT_DECL_ITEM(tmp);
	WT_DECL_RET;
	int fd, tret;
	char *dir;

	WT_RET(__wt_scr_alloc(session, 0, &tmp));
	WT_ERR(__wt_buf_setstr(session, tmp, path));

	/*
	 * This layer should never see a path that doesn't include a trailing
	 * path separator, this code asserts that fact.
	 */
	dir = tmp->mem;
	strrchr(dir, '/')[1] = '\0';

	fd = -1;			/* -Wconditional-uninitialized */
	WT_SYSCALL_RETRY((
	    (fd = open(dir, O_RDONLY, 0444)) == -1 ? -1 : 0), ret);
	if (ret != 0)
		WT_ERR_MSG(session, ret, "%s: directory-sync: open", dir);

	ret = __posix_sync(session, fd, dir, "directory-sync");

	WT_SYSCALL(close(fd), tret);
	if (tret != 0) {
		__wt_err(session, tret, "%s: directory-sync: close", dir);
		if (ret == 0)
			ret = tret;
	}

err:	__wt_scr_free(session, &tmp);
	return (ret);
}