diff options
-rw-r--r-- | config/CMakeLists.txt | 7 | ||||
-rw-r--r-- | config/config.h.in | 1 | ||||
-rw-r--r-- | runtime/doc/options.txt | 10 | ||||
-rw-r--r-- | src/nvim/fileio.c | 20 | ||||
-rw-r--r-- | src/nvim/memfile.c | 24 | ||||
-rw-r--r-- | src/nvim/option_defs.h | 40 | ||||
-rw-r--r-- | src/nvim/options.lua | 1 | ||||
-rw-r--r-- | src/nvim/os/fs.c | 13 | ||||
-rw-r--r-- | src/nvim/shada.c | 4 |
9 files changed, 52 insertions, 68 deletions
diff --git a/config/CMakeLists.txt b/config/CMakeLists.txt index 3d7660ed58..c64e7e1ddb 100644 --- a/config/CMakeLists.txt +++ b/config/CMakeLists.txt @@ -38,7 +38,6 @@ check_include_files(utime.h HAVE_UTIME_H) # Functions check_function_exists(fseeko HAVE_FSEEKO) -check_function_exists(fsync HAVE_FSYNC) check_function_exists(getpwent HAVE_GETPWENT) check_function_exists(getpwnam HAVE_GETPWNAM) check_function_exists(getpwuid HAVE_GETPWUID) @@ -101,10 +100,10 @@ endif() if (NOT "${HAVE_BE64TOH}") if (NOT "${CMAKE_CROSSCOMPILING}") # It is safe to make ORDER_BIG_ENDIAN not defined if - # - HAVE_BE64TOH is true. In this case be64toh will be used unconditionally in + # - HAVE_BE64TOH is true. In this case be64toh will be used unconditionally in # any case and ORDER_BIG_ENDIAN will not be examined. - # - CMAKE_CROSSCOMPILING *and* HAVE_BE64TOH are both false. In this case - # be64toh function which uses cycle and arithmetic operations is used which + # - CMAKE_CROSSCOMPILING *and* HAVE_BE64TOH are both false. In this case + # be64toh function which uses cycle and arithmetic operations is used which # will work regardless of endianess. Function is sub-optimal though. check_c_source_runs(" ${SI} diff --git a/config/config.h.in b/config/config.h.in index 017cb80f2f..b442a732e5 100644 --- a/config/config.h.in +++ b/config/config.h.in @@ -18,7 +18,6 @@ #cmakedefine HAVE_FCNTL_H #cmakedefine HAVE_FD_CLOEXEC #cmakedefine HAVE_FSEEKO -#cmakedefine HAVE_FSYNC #cmakedefine HAVE_GETPWENT #cmakedefine HAVE_GETPWNAM #cmakedefine HAVE_GETPWUID diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt index 610a1964f9..9d3a87b978 100644 --- a/runtime/doc/options.txt +++ b/runtime/doc/options.txt @@ -2821,9 +2821,7 @@ A jump table for the options with a short description can be found at |Q_op|. written even on filesystems which do metadata-only journaling. This will force the harddrive to spin up on Linux systems running in laptop mode, so it may be undesirable in some situations. Be warned that - turning this off increases the chances of data loss after a crash. On - systems without an fsync() implementation, this variable is always - off. + turning this off increases the chances of data loss after a crash. Also see 'swapsync' for controlling fsync() on swap files. *'gdefault'* *'gd'* *'nogdefault'* *'nogd'* @@ -6220,14 +6218,12 @@ A jump table for the options with a short description can be found at |Q_op|. 'swapsync' 'sws' string (default "fsync") global When this option is not empty a swap file is synced to disk after - writing to it. This takes some time, especially on busy unix systems. + writing to it. This takes some time, especially on busy Unix systems. When this option is empty parts of the swap file may be in memory and not written to disk. When the system crashes you may lose more work. On Unix the system does a sync now and then without Vim asking for it, so the disadvantage of setting this option off is small. On some - systems the swap file will not be written at all. For a unix system - setting it to "sync" will use the sync() call instead of the default - fsync(), which may work better on some systems. + systems the swap file will not be written at all. The 'fsync' option is used for the actual file. *'switchbuf'* *'swb'* diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index 1a6c85abaa..58269983c5 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -3368,16 +3368,16 @@ restore_backup: nchars += len; } -#if defined(UNIX) && defined(HAVE_FSYNC) - /* On many journalling file systems there is a bug that causes both the - * original and the backup file to be lost when halting the system right - * after writing the file. That's because only the meta-data is - * journalled. Syncing the file slows down the system, but assures it has - * been written to disk and we don't lose it. - * For a device do try the fsync() but don't complain if it does not work - * (could be a pipe). - * If the 'fsync' option is FALSE, don't fsync(). Useful for laptops. */ - if (p_fs && fsync(fd) != 0 && !device) { +#if defined(UNIX) + // On many journalling file systems there is a bug that causes both the + // original and the backup file to be lost when halting the system right + // after writing the file. That's because only the meta-data is + // journalled. Syncing the file slows down the system, but assures it has + // been written to disk and we don't lose it. + // For a device do try the fsync() but don't complain if it does not work + // (could be a pipe). + // If the 'fsync' option is FALSE, don't fsync(). Useful for laptops. + if (p_fs && os_fsync(fd) != 0 && !device) { errmsg = (char_u *)_("E667: Fsync failed"); end = 0; } diff --git a/src/nvim/memfile.c b/src/nvim/memfile.c index 3df4cbc4a3..9f5e4247b5 100644 --- a/src/nvim/memfile.c +++ b/src/nvim/memfile.c @@ -460,31 +460,11 @@ int mf_sync(memfile_T *mfp, int flags) mfp->mf_dirty = false; if ((flags & MFS_FLUSH) && *p_sws != NUL) { -#if defined(UNIX) -# ifdef HAVE_FSYNC if (STRCMP(p_sws, "fsync") == 0) { - if (fsync(mfp->mf_fd)) + if (os_fsync(mfp->mf_fd)) { status = FAIL; - } else { -# endif - // OpenNT is strictly POSIX (Benzinger). - // Tandem/Himalaya NSK-OSS doesn't have sync() -# if defined(__OPENNT) || defined(__TANDEM) - fflush(NULL); -# else - sync(); -# endif -# ifdef HAVE_FSYNC + } } -# endif -#endif -# ifdef SYNC_DUP_CLOSE - // Win32 is a bit more work: Duplicate the file handle and close it. - // This should flush the file to disk. - int fd; - if ((fd = dup(mfp->mf_fd)) >= 0) - close(fd); -# endif } got_int |= got_int_save; diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index c72e1cf0bb..938aa9bc83 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -405,27 +405,25 @@ static char *(p_fdo_values[]) = {"all", "block", "hor", "mark", "percent", # define FDO_INSERT 0x100 # define FDO_UNDO 0x200 # define FDO_JUMP 0x400 -EXTERN char_u *p_fp; /* 'formatprg' */ -#ifdef HAVE_FSYNC -EXTERN int p_fs; /* 'fsync' */ -#endif -EXTERN int p_gd; /* 'gdefault' */ -EXTERN char_u *p_pdev; /* 'printdevice' */ -EXTERN char_u *p_penc; /* 'printencoding' */ -EXTERN char_u *p_pexpr; /* 'printexpr' */ -EXTERN char_u *p_pmfn; /* 'printmbfont' */ -EXTERN char_u *p_pmcs; /* 'printmbcharset' */ -EXTERN char_u *p_pfn; /* 'printfont' */ -EXTERN char_u *p_popt; /* 'printoptions' */ -EXTERN char_u *p_header; /* 'printheader' */ -EXTERN int p_prompt; /* 'prompt' */ -EXTERN char_u *p_guicursor; /* 'guicursor' */ -EXTERN char_u *p_hf; /* 'helpfile' */ -EXTERN long p_hh; /* 'helpheight' */ -EXTERN char_u *p_hlg; /* 'helplang' */ -EXTERN int p_hid; /* 'hidden' */ -/* Use P_HID to check if a buffer is to be hidden when it is no longer - * visible in a window. */ +EXTERN char_u *p_fp; // 'formatprg' +EXTERN int p_fs; // 'fsync' +EXTERN int p_gd; // 'gdefault' +EXTERN char_u *p_pdev; // 'printdevice' +EXTERN char_u *p_penc; // 'printencoding' +EXTERN char_u *p_pexpr; // 'printexpr' +EXTERN char_u *p_pmfn; // 'printmbfont' +EXTERN char_u *p_pmcs; // 'printmbcharset' +EXTERN char_u *p_pfn; // 'printfont' +EXTERN char_u *p_popt; // 'printoptions' +EXTERN char_u *p_header; // 'printheader' +EXTERN int p_prompt; // 'prompt' +EXTERN char_u *p_guicursor; // 'guicursor' +EXTERN char_u *p_hf; // 'helpfile' +EXTERN long p_hh; // 'helpheight' +EXTERN char_u *p_hlg; // 'helplang' +EXTERN int p_hid; // 'hidden' +// Use P_HID to check if a buffer is to be hidden when it is no longer +// visible in a window. # define P_HID(buf) (buf_hide(buf)) EXTERN char_u *p_hl; /* 'highlight' */ EXTERN int p_hls; /* 'hlsearch' */ diff --git a/src/nvim/options.lua b/src/nvim/options.lua index 5187340629..e485b90394 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -959,7 +959,6 @@ return { type='bool', scope={'global'}, secure=true, vi_def=true, - enable_if='HAVE_FSYNC', varname='p_fs', defaults={if_true={vi=true}} }, diff --git a/src/nvim/os/fs.c b/src/nvim/os/fs.c index d59b66e773..1a4c3495f2 100644 --- a/src/nvim/os/fs.c +++ b/src/nvim/os/fs.c @@ -202,6 +202,19 @@ int os_open(const char* path, int flags, int mode) return r; } +/// Flushes file modifications to disk. +/// +/// @param fd the file descriptor of the file to flush to disk. +/// +/// @return `0` on success, a libuv error code on failure. +int os_fsync(int fd) +{ + uv_fs_t fsync_req; + int r = uv_fs_fsync(&fs_loop, &fsync_req, fd, NULL); + uv_fs_req_cleanup(&fsync_req); + return r; +} + /// Get stat information for a file. /// /// @return libuv return code. diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 42e514aa95..6a30472a7c 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -761,9 +761,9 @@ static void close_sd_writer(ShaDaWriteDef *const sd_writer) FUNC_ATTR_NONNULL_ALL { const int fd = (int)(intptr_t) sd_writer->cookie; - if (fsync(fd) < 0) { + if (os_fsync(fd) < 0) { emsg2(_(SERR "System error while synchronizing ShaDa file: %s"), - strerror(errno)); + os_strerror(errno)); errno = 0; } close_file(fd); |