patch 9.1.2024: 'fsync' option cannot be set per buffer

Commit: 
https://github.com/vim/vim/commit/4d5b30372663e8ea356b25fe94334558c6ae283f
Author: glepnir <[email protected]>
Date:   Sat Dec 27 14:26:38 2025 +0000

    patch 9.1.2024: 'fsync' option cannot be set per buffer
    
    Problem:  'fsync' option cannot be set per buffer
    Solution: Make 'fsync' option global-local
              (glepnir)
    
    closes: #19019
    
    Signed-off-by: glepnir <[email protected]>
    Signed-off-by: Christian Brabandt <[email protected]>

diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index b1550dfcc..67c8b2904 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -1,4 +1,4 @@
-*options.txt*  For Vim version 9.1.  Last change: 2025 Dec 23
+*options.txt*  For Vim version 9.1.  Last change: 2025 Dec 27
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -4274,7 +4274,7 @@ A jump table for the options with a short description can 
be found at |Q_op|.
 
                                        *'fsync'* *'fs'* *'nofsync'* *'nofs'*
 'fsync' 'fs'           boolean (default on)
-                       global
+                       global or local to buffer |global-local|
        When on, the library function fsync() will be called after writing a
        file.  This will flush a file to disk, ensuring that it is safely
        written even on filesystems which do metadata-only journaling.  This
@@ -4283,6 +4283,8 @@ A jump table for the options with a short description can 
be found at |Q_op|.
        turning this off increases the chances of data loss after a crash.  On
        systems without an fsync() implementation, this variable is always
        off.
+       This is a |global-local| option, so it can be set per buffer, for
+       example when writing to a slow filesystem.
        Also see 'swapsync' for controlling fsync() on swap files.
        'fsync' also applies to |writefile()| (unless a flag is used to
        overrule it) and when writing undo files (see |undo-persistence|).
diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index f1cfd0979..b626f2dea 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -1,4 +1,4 @@
-*version9.txt* For Vim version 9.1.  Last change: 2025 Dec 21
+*version9.txt* For Vim version 9.1.  Last change: 2025 Dec 27
 
 
                  VIM REFERENCE MANUAL    by Bram Moolenaar
@@ -41727,6 +41727,7 @@ Options: ~
 - 'guioptions': New value |'go-s'| to support fullscreen on MS-Windows GUI
   (see also the below platform specific change).
 - 'completepopup': Add more values to style popup windows.
+- 'fsync' is now a |global-local| option.
 
 Ex commands: ~
 - allow to specify a priority when defining a new sign |:sign-define|
diff --git a/src/buffer.c b/src/buffer.c
index 52aa13de2..7dca75307 100644
--- a/src/buffer.c
+++ b/src/buffer.c
@@ -2538,6 +2538,9 @@ free_buf_options(
     clear_string_option(&buf->b_p_qe);
     buf->b_p_ac = -1;
     buf->b_p_ar = -1;
+#ifdef HAVE_FSYNC
+    buf->b_p_fs = -1;
+#endif
     buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
     clear_string_option(&buf->b_p_lw);
     clear_string_option(&buf->b_p_bkc);
diff --git a/src/bufwrite.c b/src/bufwrite.c
index 342b5f36f..c1a495318 100644
--- a/src/bufwrite.c
+++ b/src/bufwrite.c
@@ -2199,7 +2199,8 @@ restore_backup:
        // 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 && vim_fsync(fd) != 0 && !device)
+       if ((buf->b_p_fs >= 0 ? buf->b_p_fs : p_fs) && vim_fsync(fd) != 0
+               && !device)
        {
            errmsg = (char_u *)_(e_fsync_failed);
            end = 0;
diff --git a/src/option.c b/src/option.c
index b5594dd6e..1ec7efbf8 100644
--- a/src/option.c
+++ b/src/option.c
@@ -698,6 +698,9 @@ set_init_1(int clean_arg)
     curbuf->b_p_initialized = TRUE;
     curbuf->b_p_ac = -1;
     curbuf->b_p_ar = -1;       // no local 'autoread' value
+#ifdef HAVE_FSYNC
+    curbuf->b_p_fs = -1;       // no local 'fsync' value
+#endif
     curbuf->b_p_ul = NO_LOCAL_UNDOLEVEL;
     check_buf_options(curbuf);
     check_win_options(curwin);
@@ -2216,6 +2219,10 @@ do_set_option_bool(
            value = -1;
        else if ((int *)varp == &curbuf->b_p_ac && opt_flags == OPT_LOCAL)
            value = -1;
+#ifdef HAVE_FSYNC
+       else if ((int *)varp == &curbuf->b_p_fs && opt_flags == OPT_LOCAL)
+           value = -1;
+#endif
        else
            value = *(int *)get_varp_scope(&(options[opt_idx]), OPT_GLOBAL);
     }
@@ -6479,6 +6486,11 @@ unset_global_local_option(char_u *name, void *from)
        case PV_AR:
            buf->b_p_ar = -1;
            break;
+#ifdef HAVE_FSYNC
+       case PV_FS:
+           buf->b_p_fs = -1;
+           break;
+#endif
        case PV_BKC:
            clear_string_option(&buf->b_p_bkc);
            buf->b_bkc_flags = 0;
@@ -6613,6 +6625,9 @@ get_varp_scope(struct vimoption *p, int scope)
        switch ((int)p->indir)
        {
            case PV_FP:   return (char_u *)&(curbuf->b_p_fp);
+#ifdef HAVE_FSYNC
+           case PV_FS: return (char_u *)&(curbuf->b_p_fs);
+#endif
 #ifdef FEAT_EVAL
            case PV_FFU: return (char_u *)&(curbuf->b_p_ffu);
 #endif
@@ -6737,6 +6752,10 @@ get_varp(struct vimoption *p)
 #endif
        case PV_FP:     return *curbuf->b_p_fp != NUL
                                    ? (char_u *)&(curbuf->b_p_fp) : p->var;
+#ifdef HAVE_FSYNC
+       case PV_FS:     return curbuf->b_p_fs >= 0
+                                   ? (char_u *)&(curbuf->b_p_fs) : p->var;
+#endif
 #ifdef FEAT_EVAL
        case PV_FFU:    return *curbuf->b_p_ffu != NUL
                                    ? (char_u *)&(curbuf->b_p_ffu) : p->var;
@@ -7540,6 +7559,9 @@ buf_copy_options(buf_T *buf, int flags)
            // are not copied, start using the global value
            buf->b_p_ac = -1;
            buf->b_p_ar = -1;
+#ifdef HAVE_FSYNC
+           buf->b_p_fs = -1;
+#endif
            buf->b_p_ul = NO_LOCAL_UNDOLEVEL;
            buf->b_p_bkc = empty_option;
            buf->b_bkc_flags = 0;
diff --git a/src/option.h b/src/option.h
index f5c36ad89..7372ba924 100644
--- a/src/option.h
+++ b/src/option.h
@@ -1223,6 +1223,9 @@ enum
     , BV_FF
     , BV_FLP
     , BV_FO
+#ifdef HAVE_FSYNC
+    , BV_FS
+#endif
     , BV_FT
     , BV_IMI
     , BV_IMS
diff --git a/src/optiondefs.h b/src/optiondefs.h
index d888615f5..9e5612470 100644
--- a/src/optiondefs.h
+++ b/src/optiondefs.h
@@ -82,6 +82,9 @@
 #define PV_FF          OPT_BUF(BV_FF)
 #define PV_FLP         OPT_BUF(BV_FLP)
 #define PV_FO          OPT_BUF(BV_FO)
+#ifdef HAVE_FSYNC
+# define PV_FS         OPT_BOTH(OPT_BUF(BV_FS))
+#endif
 #define PV_FT          OPT_BUF(BV_FT)
 #define PV_IMI         OPT_BUF(BV_IMI)
 #define PV_IMS         OPT_BUF(BV_IMS)
@@ -1172,7 +1175,7 @@ static struct vimoption options[] =
                            {(char_u *)"", (char_u *)0L} SCTX_INIT},
     {"fsync",       "fs",   P_BOOL|P_SECURE|P_VI_DEF,
 #ifdef HAVE_FSYNC
-                           (char_u *)&p_fs, PV_NONE, NULL, NULL,
+                           (char_u *)&p_fs, PV_FS, NULL, NULL,
                            {(char_u *)TRUE, (char_u *)0L}
 #else
                            (char_u *)NULL, PV_NONE, NULL, NULL,
diff --git a/src/structs.h b/src/structs.h
index 9b095c328..37f9cf5d1 100644
--- a/src/structs.h
+++ b/src/structs.h
@@ -3380,6 +3380,9 @@ struct file_buffer
     char_u     *b_p_fex;       // 'formatexpr'
     long_u     b_p_fex_flags;  // flags for 'formatexpr'
 #endif
+#ifdef HAVE_FSYNC
+    int                b_p_fs;         // 'fsync'
+#endif
 #ifdef FEAT_CRYPT
     char_u     *b_p_key;       // 'key'
 #endif
diff --git a/src/testdir/test_options.vim b/src/testdir/test_options.vim
index 2e4e9f727..c6c83bb98 100644
--- a/src/testdir/test_options.vim
+++ b/src/testdir/test_options.vim
@@ -1681,25 +1681,34 @@ endfunc
 
 " Test for setting boolean global-local option value
 func Test_set_boolean_global_local_option()
-  setglobal autoread
-  setlocal noautoread
+  CheckUnix
+
+  setglobal autoread fsync
+  setlocal noautoread nofsync
   call assert_equal(1, &g:autoread)
   call assert_equal(0, &l:autoread)
   call assert_equal(0, &autoread)
+  call assert_equal(1, &g:fsync)
+  call assert_equal(0, &l:fsync)
+  call assert_equal(0, &fsync)
 
   " :set {option}< set the effective value of {option} to its global value.
-  set autoread<
+  set autoread< fsync<
   call assert_equal(1, &l:autoread)
   call assert_equal(1, &autoread)
+  call assert_equal(1, &l:fsync)
+  call assert_equal(1, &fsync)
 
   " :setlocal {option}< removes the local value, so that the global value will 
be used.
-  setglobal noautoread
-  setlocal autoread
-  setlocal autoread<
+  setglobal noautoread nofsync
+  setlocal autoread fsync
+  setlocal autoread< fsync<
   call assert_equal(-1, &l:autoread)
   call assert_equal(0, &autoread)
+  call assert_equal(-1, &l:fsync)
+  call assert_equal(0, &fsync)
 
-  set autoread&
+  set autoread& fsync&
 endfunc
 
 func Test_set_in_sandbox()
diff --git a/src/undo.c b/src/undo.c
index b1747996b..f40aca660 100644
--- a/src/undo.c
+++ b/src/undo.c
@@ -1774,7 +1774,8 @@ u_write_undo(
 #endif
 
 #if defined(UNIX) && defined(HAVE_FSYNC)
-    if (p_fs && fflush(fp) == 0 && vim_fsync(fd) != 0)
+    if ((buf->b_p_fs >= 0 ? buf->b_p_fs : p_fs) && fflush(fp) == 0
+           && vim_fsync(fd) != 0)
        write_ok = FALSE;
 #endif
 
diff --git a/src/version.c b/src/version.c
index fad0bdd58..f09ff1791 100644
--- a/src/version.c
+++ b/src/version.c
@@ -734,6 +734,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2024,
 /**/
     2023,
 /**/

-- 
-- 
You received this message from the "vim_dev" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

--- 
You received this message because you are subscribed to the Google Groups 
"vim_dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion visit 
https://groups.google.com/d/msgid/vim_dev/E1vZVXU-000p8i-Am%40256bit.org.

Raspunde prin e-mail lui