From 0e97d3d4ee013b6f405bebeb2e4383e39a01d1e1 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 20 Feb 2019 21:37:23 +0100 Subject: [PATCH 1/3] fix "E667: Fsync failed" on macOS macOS: Try direct fsync() if F_FULLFSYNC fails. closes #6725 ref https://github.com/vim/vim/pull/4016 vim-patch:8.1.0957 > on macOS F_FULLFSYNC fails with ENOTSUP for unsupported storage systems > (e.g. SMB), though this is not documented in the Apple fcntl man page. libuv fixed this in v1.25.0: https://github.com/libuv/libuv/commit/6fc797c3fe18d8df71b36ecf2184f085c0283251 --- src/nvim/os/fs.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index 9a4391a0ae..cead8d802b 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -643,12 +643,19 @@ ptrdiff_t os_write(const int fd, const char *const buf, const size_t size, /// /// @param fd the file descriptor of the file to flush to disk. /// -/// @return `0` on success, a libuv error code on failure. +/// @return 0 on success, or libuv error code on failure. int os_fsync(int fd) { int r; RUN_UV_FS_FUNC(r, uv_fs_fsync, fd, NULL); g_stats.fsync++; +#ifdef __APPLE__ + // TODO(justinmk): Remove this after it is fixed in libuv. #6725 + if (r == UV_ENOTSUP) { + int rv = fsync(fd); + return rv ? -rv : rv; + } +#endif return r; } From c59aa771a631be53215eaadadfa4589d168a5c2b Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 20 Feb 2019 21:42:24 +0100 Subject: [PATCH 2/3] deps: update to libuv v1.26.0 Notable changes since v1.23.2: - v1.26.0 - uv_os_uname() - unix: don't attempt to invalidate invalid fd https://github.com/libuv/libuv/commit/1ce6393a5780538ad8601cae00c5bd079b9415a9 - v1.25.0 - unix: better handling of unsupported F_FULLFSYNC (fixes #6725) https://github.com/libuv/libuv/commit/6fc797c3fe18d8df71b36ecf2184f085c0283251 - tty,win: fix Alt+key under WSL https://github.com/libuv/libuv/commit/d2e59bb6003d707bdebd7a381f5a7e1d0cc3fd3b - fsevents: really watch files with fsevents on macos 10.7+ https://github.com/libuv/libuv/commit/2d2af382ce84b91d6ee7a185af32fca7f0acd84b - win: fix duplicate tty vt100 fn key - v1.24.0 - win,fs: retry if uv_fs_rename fails https://github.com/libuv/libuv/commit/e94c184c7c4a18f3de569c97caeb83f4ff98a4b2 - later [reverted](https://github.com/libuv/libuv/issues/2098) but may be useful reference - win: support more fine-grained windows hiding https://github.com/libuv/libuv/commit/4c2dcca27b80945d6b7063f0ea031b8a75a46a52 --- src/nvim/event/socket.c | 2 +- src/nvim/os/fs.c | 7 ------- third-party/CMakeLists.txt | 4 ++-- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/src/nvim/event/socket.c b/src/nvim/event/socket.c index 6fcb9f7e7a..af326f9c82 100644 --- a/src/nvim/event/socket.c +++ b/src/nvim/event/socket.c @@ -169,7 +169,7 @@ void socket_watcher_close(SocketWatcher *watcher, socket_close_cb cb) FUNC_ATTR_NONNULL_ARG(1) { watcher->close_cb = cb; - uv_close((uv_handle_t *)watcher->stream, close_cb); + uv_close(STRUCT_CAST(uv_handle_t, watcher->stream), close_cb); } static void connection_event(void **argv) diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index cead8d802b..99ece275b1 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -649,13 +649,6 @@ int os_fsync(int fd) int r; RUN_UV_FS_FUNC(r, uv_fs_fsync, fd, NULL); g_stats.fsync++; -#ifdef __APPLE__ - // TODO(justinmk): Remove this after it is fixed in libuv. #6725 - if (r == UV_ENOTSUP) { - int rv = fsync(fd); - return rv ? -rv : rv; - } -#endif return r; } diff --git a/third-party/CMakeLists.txt b/third-party/CMakeLists.txt index f316e5bd0d..b1c8c95b31 100644 --- a/third-party/CMakeLists.txt +++ b/third-party/CMakeLists.txt @@ -123,8 +123,8 @@ if(WIN32) set(LIBUV_URL https://github.com/neovim/libuv/archive/0ed7feb71ca949f7a96ccb102481d17ea1bb5933.tar.gz) set(LIBUV_SHA256 813fe763022f19878557c6fde311b6394fb9180caaaab0dd98d8704732234508) else() - set(LIBUV_URL https://github.com/libuv/libuv/archive/v1.23.2.tar.gz) - set(LIBUV_SHA256 30af979c4f4b8d1b895ae6d115f7400c751542ccb9e656350fc89fda08d4eabd) + set(LIBUV_URL https://github.com/libuv/libuv/archive/v1.26.0.tar.gz) + set(LIBUV_SHA256 e414cf74615b7dae768f0f5667092f1d4975f5067c087bcbe0641e241ebe4693) endif() set(MSGPACK_URL https://github.com/msgpack/msgpack-c/releases/download/cpp-3.0.0/msgpack-3.0.0.tar.gz) From 996916277d9845b61f026c53197880889e5004e2 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 20 Feb 2019 21:52:12 +0100 Subject: [PATCH 3/3] I/O: ignore ENOTSUP for failed fsync() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Suggested by ZyX in https://github.com/neovim/neovim/issues/6725#issuecomment-312197691 : > There already is an exception if writing to a “device” (e.g. FIFO). > It makes sense to ignore certain errors like ENOTSUP or EOPNOTSUPP > since it is not something we or user can do anything about. ref #6725 --- src/nvim/fileio.c | 4 +++- src/nvim/os/fileio.c | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 6356290b9c..ba3625bf95 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -3405,7 +3405,9 @@ restore_backup: // (could be a pipe). // If the 'fsync' option is FALSE, don't fsync(). Useful for laptops. int error; - if (p_fs && (error = os_fsync(fd)) != 0 && !device) { + if (p_fs && (error = os_fsync(fd)) != 0 && !device + // fsync not supported on this storage. + && error != UV_ENOTSUP) { SET_ERRMSG_ARG(_("E667: Fsync failed: %s"), error); end = 0; } diff --git a/src/nvim/os/fileio.c b/src/nvim/os/fileio.c index ccf35fd57c..bb68326a03 100644 --- a/src/nvim/os/fileio.c +++ b/src/nvim/os/fileio.c @@ -229,7 +229,10 @@ int file_fsync(FileDescriptor *const fp) return flush_error; } const int fsync_error = os_fsync(fp->fd); - if (fsync_error != UV_EINVAL && fsync_error != UV_EROFS) { + if (fsync_error != UV_EINVAL + && fsync_error != UV_EROFS + // fsync not supported on this storage. + && fsync_error != UV_ENOTSUP) { return fsync_error; } return 0;