]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve interactive file-saving performance
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 2 Jan 2023 18:00:41 +0000 (10:00 -0800)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 2 Jan 2023 19:29:06 +0000 (11:29 -0800)
* src/fileio.c (init_fileio):
No longer any need to set write-region-inhibit-fsync here.
(syms_of_fileio): Default write-region-inhibit-fsync to t (Bug#60474).

doc/emacs/files.texi
doc/lispref/files.texi
etc/NEWS
src/fileio.c

index 6d666831612b17c77c765c353c32337a3010f147..6a9103d3a09979cc1e202fb5ddc970c31da7a863 100644 (file)
@@ -801,22 +801,21 @@ in these cases, customize the variable
 @vindex write-region-inhibit-fsync
   Normally, when a program writes a file, the operating system briefly
 caches the file's data in main memory before committing the data to
-disk.  This can greatly improve performance; for example, when running
-on laptops, it can avoid a disk spin-up each time a file is written.
-However, it risks data loss if the operating system crashes before
-committing the cache to disk.
+secondary storage.  Although this can greatly improve performance, it
+risks data loss if the system loses power before committing the cache,
+and on some platforms other processes might not immediately notice the
+file's change.
 
   To lessen this risk, Emacs can invoke the @code{fsync} system call
 after saving a file.  Using @code{fsync} does not eliminate the risk
-of data loss, partly because many systems do not implement
+of data loss or slow notification, partly because many systems do not support
 @code{fsync} properly, and partly because Emacs's file-saving
 procedure typically relies also on directory updates that might not
 survive a crash even if @code{fsync} works properly.
 
   The @code{write-region-inhibit-fsync} variable controls whether
 Emacs invokes @code{fsync} after saving a file.  The variable's
-default value is @code{nil} when Emacs is interactive, and @code{t}
-when Emacs runs in batch mode (@pxref{Initial Options, Batch Mode}).
+default value is @code{t}.
 
   Emacs never uses @code{fsync} when writing auto-save files, as these
 files might lose data anyway.
index 707af6ee64c0a38d674057d3fc44d7d73781cb2a..91643530f7f0cca23a9beb75069c1af240a964d9 100644 (file)
@@ -692,11 +692,9 @@ files that the user does not need to know about.
 
 @defvar write-region-inhibit-fsync
 If this variable's value is @code{nil}, @code{write-region} uses the
-@code{fsync} system call after writing a file.  Although this slows
-Emacs down, it lessens the risk of data loss after power failure.  If
-the value is @code{t}, Emacs does not use @code{fsync}.  The default
-value is @code{nil} when Emacs is interactive, and @code{t} when Emacs
-runs in batch mode.  @xref{Files and Storage}.
+@code{fsync} system call after writing a file.  If the value is
+@code{t}, Emacs does not use @code{fsync}.  The default value is
+@code{t}.  @xref{Files and Storage}.
 @end defvar
 
 @defmac with-temp-file file body@dots{}
@@ -2038,17 +2036,28 @@ data already stored elsewhere on secondary storage until one file or
 the other is later modified; this will lose both files if the only
 copy on secondary storage is lost due to media failure.  Second, the
 operating system might not write data to secondary storage
-immediately, which will lose the data if power is lost.
+immediately, which will lose the data if power is lost
+or if there is a media failure.
 
 @findex write-region
 Although both sorts of failures can largely be avoided by a suitably
-configured file system, such systems are typically more expensive or
-less efficient.  In more-typical systems, to survive media failure you
+configured system, such systems are typically more expensive or
+less efficient.  In lower-end systems, to survive media failure you
 can copy the file to a different device, and to survive a power
-failure you can use the @code{write-region} function with the
+failure (or be immediately notified of a media failure) you can use
+the @code{write-region} function with the
 @code{write-region-inhibit-fsync} variable set to @code{nil}.
+Although this variable is ordinarily @code{t} because that can
+significantly improve performance, it may make sense to temporarily
+bind it to @code{nil} if using Emacs to implement database-like
+transactions that survive power failure on lower-end systems.
 @xref{Writing to Files}.
 
+On some platforms when Emacs changes a file other processes might not
+be notified of the change immediately.  Setting
+@code{write-region-inhibit-fsync} to @code{nil} may improve
+notification speed in this case, though there are no guarantees.
+
 @node File Names
 @section File Names
 @cindex file names
index eb68ce434b35cfc69d95d4cbeec43b7973a27fb4..1ab6822da3f703e845feaa77ff3983368e1dc6cf 100644 (file)
--- a/etc/NEWS
+++ b/etc/NEWS
@@ -41,6 +41,10 @@ compositing manager, Emacs will now redisplay such a frame even though
 'frame-visible-' returns nil or 'icon' for it.  This can happen, for
 example, as part of preview for iconified frames.
 
++++
+** 'write-region-inhibit-fsync' now defaults to t in interactive mode,
+as it has in batch mode since Emacs 24.
+
 \f
 * Editing Changes in Emacs 30.1
 
index 7fb7f5ddc5ebd1d518e945f3acc94c8a74ab67ba..c672e0f7baf83cf2c1d72adb56c53dc652db8762 100644 (file)
@@ -6334,24 +6334,6 @@ init_fileio (void)
   umask (realmask);
 
   valid_timestamp_file_system = 0;
-
-  /* fsync can be a significant performance hit.  Often it doesn't
-     suffice to make the file-save operation survive a crash.  For
-     batch scripts, which are typically part of larger shell commands
-     that don't fsync other files, its effect on performance can be
-     significant so its utility is particularly questionable.
-     Hence, for now by default fsync is used only when interactive.
-
-     For more on why fsync often fails to work on today's hardware, see:
-     Zheng M et al. Understanding the robustness of SSDs under power fault.
-     11th USENIX Conf. on File and Storage Technologies, 2013 (FAST '13), 271-84
-     https://www.usenix.org/system/files/conference/fast13/fast13-final80.pdf
-
-     For more on why fsync does not suffice even if it works properly, see:
-     Roche X. Necessary step(s) to synchronize filename operations on disk.
-     Austin Group Defect 672, 2013-03-19
-     https://austingroupbugs.net/view.php?id=672  */
-  write_region_inhibit_fsync = noninteractive;
 }
 
 void
@@ -6609,9 +6591,22 @@ file is usually more useful if it contains the deleted text.  */);
   DEFVAR_BOOL ("write-region-inhibit-fsync", write_region_inhibit_fsync,
               doc: /* Non-nil means don't call fsync in `write-region'.
 This variable affects calls to `write-region' as well as save commands.
-Setting this to nil may avoid data loss if the system loses power or
-the operating system crashes.  By default, it is non-nil in batch mode.  */);
-  write_region_inhibit_fsync = 0; /* See also `init_fileio' above.  */
+By default, it is non-nil.
+
+Although setting this to nil may avoid data loss if the system loses power,
+it can be a significant performance hit in the usual case, and it doesn't
+necessarily cause file-save operations to actually survive a crash.  */);
+
+  /* For more on why fsync often fails to work on today's hardware, see:
+     Zheng M et al. Understanding the robustness of SSDs under power fault.
+     11th USENIX Conf. on File and Storage Technologies, 2013 (FAST '13), 271-84
+     https://www.usenix.org/system/files/conference/fast13/fast13-final80.pdf
+
+     For more on why fsync does not suffice even if it works properly, see:
+     Roche X. Necessary step(s) to synchronize filename operations on disk.
+     Austin Group Defect 672, 2013-03-19
+     https://austingroupbugs.net/view.php?id=672  */
+  write_region_inhibit_fsync = true;
 
   DEFVAR_BOOL ("delete-by-moving-to-trash", delete_by_moving_to_trash,
                doc: /* Specifies whether to use the system's trash can.