diff options
-rw-r--r-- | dist/s_string.ok | 1 | ||||
-rw-r--r-- | src/include/os.h | 27 | ||||
-rw-r--r-- | src/os_posix/os_dir.c | 2 | ||||
-rw-r--r-- | src/os_posix/os_fs.c | 45 | ||||
-rw-r--r-- | src/os_posix/os_map.c | 2 | ||||
-rw-r--r-- | src/os_win/os_fs.c | 5 |
6 files changed, 50 insertions, 32 deletions
diff --git a/dist/s_string.ok b/dist/s_string.ok index eed034abb47..06173fe978c 100644 --- a/dist/s_string.ok +++ b/dist/s_string.ok @@ -439,6 +439,7 @@ bzDecompressInit bzalloc bzfree bzip +call's calloc cas catfmt diff --git a/src/include/os.h b/src/include/os.h index 2ff41d39f46..44cceee6c40 100644 --- a/src/include/os.h +++ b/src/include/os.h @@ -17,15 +17,26 @@ #define WT_SYSCALL_RETRY(call, ret) do { \ int __retry; \ for (__retry = 0; __retry < 10; ++__retry) { \ - if ((call) == 0) { \ - (ret) = 0; \ - break; \ - } \ - switch ((ret) = __wt_errno()) { \ - case 0: \ - /* The call failed but didn't set errno. */ \ - (ret) = WT_ERROR; \ + /* \ + * A call returning 0 indicates success; any call where \ + * 0 is not the only successful return must provide an \ + * expression evaluating to 0 in all successful cases. \ + */ \ + if (((ret) = (call)) == 0) \ break; \ + /* \ + * The call's error was either returned by the call or \ + * is in errno, and there are cases where it depends on \ + * the software release as to which it is (for example, \ + * posix_fadvise on FreeBSD and OS X). Failing calls \ + * must either return a non-zero error value, or -1 if \ + * the error value is in errno. (The WiredTiger errno \ + * function returns WT_ERROR if errno is 0, which isn't \ + * ideal but won't discard the failure.) \ + */ \ + if ((ret) == -1) \ + (ret) = __wt_errno(); \ + switch (ret) { \ case EAGAIN: \ case EBUSY: \ case EINTR: \ diff --git a/src/os_posix/os_dir.c b/src/os_posix/os_dir.c index 78ae5f8edd4..02f12ec7311 100644 --- a/src/os_posix/os_dir.c +++ b/src/os_posix/os_dir.c @@ -36,7 +36,7 @@ __wt_posix_directory_list(WT_SESSION_IMPL *session, const char *dir, dirsz = 0; entries = NULL; - WT_SYSCALL_RETRY(((dirp = opendir(path)) == NULL ? 1 : 0), ret); + WT_SYSCALL_RETRY(((dirp = opendir(path)) == NULL ? -1 : 0), ret); if (ret != 0) WT_ERR_MSG(session, ret, "%s: directory-list: opendir", path); diff --git a/src/os_posix/os_fs.c b/src/os_posix/os_fs.c index 86aa8db8f4f..7d8f3b937b6 100644 --- a/src/os_posix/os_fs.c +++ b/src/os_posix/os_fs.c @@ -52,7 +52,7 @@ __posix_sync(WT_SESSION_IMPL *session, * "This is currently implemented on HFS, MS-DOS (FAT), and Universal * Disk Format (UDF) file systems." */ - WT_SYSCALL_RETRY(fcntl(fd, F_FULLFSYNC, 0), ret); + WT_SYSCALL_RETRY(fcntl(fd, F_FULLFSYNC, 0) == -1 ? -1 : 0, ret); if (ret == 0) return (0); /* @@ -107,7 +107,7 @@ __posix_directory_sync(WT_SESSION_IMPL *session, const char *path) } WT_SYSCALL_RETRY(( - (fd = open(path, O_RDONLY, 0444)) == -1 ? 1 : 0), ret); + (fd = open(path, O_RDONLY, 0444)) == -1 ? -1 : 0), ret); if (ret != 0) WT_ERR_MSG(session, ret, "%s: directory-sync: open", path); @@ -172,14 +172,19 @@ __posix_file_remove(WT_SESSION_IMPL *session, const char *name) #endif WT_RET(__wt_filename(session, name, &path)); - name = path; - - WT_SYSCALL_RETRY(remove(name), ret); - if (ret != 0) - __wt_err(session, ret, "%s: file-remove: remove", name); + /* + * ISO C doesn't require remove return -1 on failure or set errno (note + * POSIX 1003.1 extends C with those requirements). Regardless, use the + * unlink system call, instead of remove, to simplify error handling; + * where we're not doing any special checking for standards compliance, + * using unlink may be marginally safer. + */ + WT_SYSCALL_RETRY(unlink(path), ret); __wt_free(session, path); - return (ret); + if (ret == 0) + return (0); + WT_RET_MSG(session, ret, "%s: file-remove: unlink", name); } /* @@ -203,18 +208,22 @@ __posix_file_rename(WT_SESSION_IMPL *session, const char *from, const char *to) 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_SYSCALL_RETRY(rename(from, to), ret); - if (ret != 0) - __wt_err(session, ret, - "%s to %s: file-rename: rename", from, to); + /* + * ISO C doesn't require rename return -1 on failure or set errno (note + * POSIX 1003.1 extends C with those requirements). Be cautious, force + * any non-zero return to -1 so we'll check errno. We can still end up + * with the wrong errno (if errno is garbage), or the generic WT_ERROR + * return (if errno is 0), but we've done the best we can. + */ + WT_SYSCALL_RETRY(rename(from_path, to_path) != 0 ? -1 : 0, ret); err: __wt_free(session, from_path); __wt_free(session, to_path); - return (ret); + if (ret == 0) + return (0); + WT_RET_MSG(session, ret, "%s to %s: file-rename: rename", from, to); } /* @@ -360,7 +369,7 @@ __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(fh->fd, F_SETLK, &fl) == -1 ? -1 : 0, ret); if (ret == 0) return (0); WT_RET_MSG(session, ret, "%s: handle-lock: fcntl", fh->name); @@ -560,7 +569,7 @@ __posix_handle_open(WT_SESSION_IMPL *session, f |= O_CLOEXEC; #endif WT_SYSCALL_RETRY(( - (fd = open(name, f, 0444)) == -1 ? 1 : 0), ret); + (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)); @@ -622,7 +631,7 @@ __posix_handle_open(WT_SESSION_IMPL *session, #endif } - WT_SYSCALL_RETRY(((fd = open(name, f, mode)) == -1 ? 1 : 0), ret); + WT_SYSCALL_RETRY(((fd = open(name, f, mode)) == -1 ? -1 : 0), ret); if (ret != 0) WT_ERR_MSG(session, ret, direct_io ? diff --git a/src/os_posix/os_map.c b/src/os_posix/os_map.c index de28891ffd1..e161e268f6d 100644 --- a/src/os_posix/os_map.c +++ b/src/os_posix/os_map.c @@ -98,6 +98,7 @@ __posix_map_preload_madvise( if (size <= (size_t)conn->page_size || (ret = posix_madvise(blk, size, POSIX_MADV_WILLNEED)) == 0) return (0); + WT_RET_MSG(session, ret, "%s: memory-map preload: posix_madvise: POSIX_MADV_WILLNEED", fh->name); @@ -145,6 +146,7 @@ __posix_map_discard_madvise( if ((ret = posix_madvise(blk, size, POSIX_MADV_DONTNEED)) == 0) return (0); + WT_RET_MSG(session, ret, "%s: memory-map discard: posix_madvise: POSIX_MADV_DONTNEED", fh->name); diff --git a/src/os_win/os_fs.c b/src/os_win/os_fs.c index 95c0ea40ce6..4ac613fc9f9 100644 --- a/src/os_win/os_fs.c +++ b/src/os_win/os_fs.c @@ -286,11 +286,6 @@ __win_handle_lock(WT_SESSION_IMPL *session, WT_FH *fh, bool lock) * 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. - * * http://msdn.microsoft.com/ * en-us/library/windows/desktop/aa365202%28v=vs.85%29.aspx * |