diff options
| author | Paul Eggert | 2023-01-02 10:00:41 -0800 |
|---|---|---|
| committer | Paul Eggert | 2023-01-02 11:29:06 -0800 |
| commit | 2ee6012b3faaf12710ec63626795148caeef0f6a (patch) | |
| tree | 4d305a3d2dc5d05eee0f6ebb0d1078c5e8c9ac25 | |
| parent | c209802f7b3721a1b95113290934a23fee88f678 (diff) | |
| download | emacs-2ee6012b3faaf12710ec63626795148caeef0f6a.tar.gz emacs-2ee6012b3faaf12710ec63626795148caeef0f6a.zip | |
Improve interactive file-saving performance
* 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).
| -rw-r--r-- | doc/emacs/files.texi | 13 | ||||
| -rw-r--r-- | doc/lispref/files.texi | 27 | ||||
| -rw-r--r-- | etc/NEWS | 4 | ||||
| -rw-r--r-- | src/fileio.c | 37 |
4 files changed, 44 insertions, 37 deletions
diff --git a/doc/emacs/files.texi b/doc/emacs/files.texi index 6d666831612..6a9103d3a09 100644 --- a/doc/emacs/files.texi +++ b/doc/emacs/files.texi | |||
| @@ -801,22 +801,21 @@ in these cases, customize the variable | |||
| 801 | @vindex write-region-inhibit-fsync | 801 | @vindex write-region-inhibit-fsync |
| 802 | Normally, when a program writes a file, the operating system briefly | 802 | Normally, when a program writes a file, the operating system briefly |
| 803 | caches the file's data in main memory before committing the data to | 803 | caches the file's data in main memory before committing the data to |
| 804 | disk. This can greatly improve performance; for example, when running | 804 | secondary storage. Although this can greatly improve performance, it |
| 805 | on laptops, it can avoid a disk spin-up each time a file is written. | 805 | risks data loss if the system loses power before committing the cache, |
| 806 | However, it risks data loss if the operating system crashes before | 806 | and on some platforms other processes might not immediately notice the |
| 807 | committing the cache to disk. | 807 | file's change. |
| 808 | 808 | ||
| 809 | To lessen this risk, Emacs can invoke the @code{fsync} system call | 809 | To lessen this risk, Emacs can invoke the @code{fsync} system call |
| 810 | after saving a file. Using @code{fsync} does not eliminate the risk | 810 | after saving a file. Using @code{fsync} does not eliminate the risk |
| 811 | of data loss, partly because many systems do not implement | 811 | of data loss or slow notification, partly because many systems do not support |
| 812 | @code{fsync} properly, and partly because Emacs's file-saving | 812 | @code{fsync} properly, and partly because Emacs's file-saving |
| 813 | procedure typically relies also on directory updates that might not | 813 | procedure typically relies also on directory updates that might not |
| 814 | survive a crash even if @code{fsync} works properly. | 814 | survive a crash even if @code{fsync} works properly. |
| 815 | 815 | ||
| 816 | The @code{write-region-inhibit-fsync} variable controls whether | 816 | The @code{write-region-inhibit-fsync} variable controls whether |
| 817 | Emacs invokes @code{fsync} after saving a file. The variable's | 817 | Emacs invokes @code{fsync} after saving a file. The variable's |
| 818 | default value is @code{nil} when Emacs is interactive, and @code{t} | 818 | default value is @code{t}. |
| 819 | when Emacs runs in batch mode (@pxref{Initial Options, Batch Mode}). | ||
| 820 | 819 | ||
| 821 | Emacs never uses @code{fsync} when writing auto-save files, as these | 820 | Emacs never uses @code{fsync} when writing auto-save files, as these |
| 822 | files might lose data anyway. | 821 | files might lose data anyway. |
diff --git a/doc/lispref/files.texi b/doc/lispref/files.texi index 707af6ee64c..91643530f7f 100644 --- a/doc/lispref/files.texi +++ b/doc/lispref/files.texi | |||
| @@ -692,11 +692,9 @@ files that the user does not need to know about. | |||
| 692 | 692 | ||
| 693 | @defvar write-region-inhibit-fsync | 693 | @defvar write-region-inhibit-fsync |
| 694 | If this variable's value is @code{nil}, @code{write-region} uses the | 694 | If this variable's value is @code{nil}, @code{write-region} uses the |
| 695 | @code{fsync} system call after writing a file. Although this slows | 695 | @code{fsync} system call after writing a file. If the value is |
| 696 | Emacs down, it lessens the risk of data loss after power failure. If | 696 | @code{t}, Emacs does not use @code{fsync}. The default value is |
| 697 | the value is @code{t}, Emacs does not use @code{fsync}. The default | 697 | @code{t}. @xref{Files and Storage}. |
| 698 | value is @code{nil} when Emacs is interactive, and @code{t} when Emacs | ||
| 699 | runs in batch mode. @xref{Files and Storage}. | ||
| 700 | @end defvar | 698 | @end defvar |
| 701 | 699 | ||
| 702 | @defmac with-temp-file file body@dots{} | 700 | @defmac with-temp-file file body@dots{} |
| @@ -2038,17 +2036,28 @@ data already stored elsewhere on secondary storage until one file or | |||
| 2038 | the other is later modified; this will lose both files if the only | 2036 | the other is later modified; this will lose both files if the only |
| 2039 | copy on secondary storage is lost due to media failure. Second, the | 2037 | copy on secondary storage is lost due to media failure. Second, the |
| 2040 | operating system might not write data to secondary storage | 2038 | operating system might not write data to secondary storage |
| 2041 | immediately, which will lose the data if power is lost. | 2039 | immediately, which will lose the data if power is lost |
| 2040 | or if there is a media failure. | ||
| 2042 | 2041 | ||
| 2043 | @findex write-region | 2042 | @findex write-region |
| 2044 | Although both sorts of failures can largely be avoided by a suitably | 2043 | Although both sorts of failures can largely be avoided by a suitably |
| 2045 | configured file system, such systems are typically more expensive or | 2044 | configured system, such systems are typically more expensive or |
| 2046 | less efficient. In more-typical systems, to survive media failure you | 2045 | less efficient. In lower-end systems, to survive media failure you |
| 2047 | can copy the file to a different device, and to survive a power | 2046 | can copy the file to a different device, and to survive a power |
| 2048 | failure you can use the @code{write-region} function with the | 2047 | failure (or be immediately notified of a media failure) you can use |
| 2048 | the @code{write-region} function with the | ||
| 2049 | @code{write-region-inhibit-fsync} variable set to @code{nil}. | 2049 | @code{write-region-inhibit-fsync} variable set to @code{nil}. |
| 2050 | Although this variable is ordinarily @code{t} because that can | ||
| 2051 | significantly improve performance, it may make sense to temporarily | ||
| 2052 | bind it to @code{nil} if using Emacs to implement database-like | ||
| 2053 | transactions that survive power failure on lower-end systems. | ||
| 2050 | @xref{Writing to Files}. | 2054 | @xref{Writing to Files}. |
| 2051 | 2055 | ||
| 2056 | On some platforms when Emacs changes a file other processes might not | ||
| 2057 | be notified of the change immediately. Setting | ||
| 2058 | @code{write-region-inhibit-fsync} to @code{nil} may improve | ||
| 2059 | notification speed in this case, though there are no guarantees. | ||
| 2060 | |||
| 2052 | @node File Names | 2061 | @node File Names |
| 2053 | @section File Names | 2062 | @section File Names |
| 2054 | @cindex file names | 2063 | @cindex file names |
| @@ -41,6 +41,10 @@ compositing manager, Emacs will now redisplay such a frame even though | |||
| 41 | 'frame-visible-' returns nil or 'icon' for it. This can happen, for | 41 | 'frame-visible-' returns nil or 'icon' for it. This can happen, for |
| 42 | example, as part of preview for iconified frames. | 42 | example, as part of preview for iconified frames. |
| 43 | 43 | ||
| 44 | +++ | ||
| 45 | ** 'write-region-inhibit-fsync' now defaults to t in interactive mode, | ||
| 46 | as it has in batch mode since Emacs 24. | ||
| 47 | |||
| 44 | 48 | ||
| 45 | * Editing Changes in Emacs 30.1 | 49 | * Editing Changes in Emacs 30.1 |
| 46 | 50 | ||
diff --git a/src/fileio.c b/src/fileio.c index 7fb7f5ddc5e..c672e0f7baf 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -6334,24 +6334,6 @@ init_fileio (void) | |||
| 6334 | umask (realmask); | 6334 | umask (realmask); |
| 6335 | 6335 | ||
| 6336 | valid_timestamp_file_system = 0; | 6336 | valid_timestamp_file_system = 0; |
| 6337 | |||
| 6338 | /* fsync can be a significant performance hit. Often it doesn't | ||
| 6339 | suffice to make the file-save operation survive a crash. For | ||
| 6340 | batch scripts, which are typically part of larger shell commands | ||
| 6341 | that don't fsync other files, its effect on performance can be | ||
| 6342 | significant so its utility is particularly questionable. | ||
| 6343 | Hence, for now by default fsync is used only when interactive. | ||
| 6344 | |||
| 6345 | For more on why fsync often fails to work on today's hardware, see: | ||
| 6346 | Zheng M et al. Understanding the robustness of SSDs under power fault. | ||
| 6347 | 11th USENIX Conf. on File and Storage Technologies, 2013 (FAST '13), 271-84 | ||
| 6348 | https://www.usenix.org/system/files/conference/fast13/fast13-final80.pdf | ||
| 6349 | |||
| 6350 | For more on why fsync does not suffice even if it works properly, see: | ||
| 6351 | Roche X. Necessary step(s) to synchronize filename operations on disk. | ||
| 6352 | Austin Group Defect 672, 2013-03-19 | ||
| 6353 | https://austingroupbugs.net/view.php?id=672 */ | ||
| 6354 | write_region_inhibit_fsync = noninteractive; | ||
| 6355 | } | 6337 | } |
| 6356 | 6338 | ||
| 6357 | void | 6339 | void |
| @@ -6609,9 +6591,22 @@ file is usually more useful if it contains the deleted text. */); | |||
| 6609 | DEFVAR_BOOL ("write-region-inhibit-fsync", write_region_inhibit_fsync, | 6591 | DEFVAR_BOOL ("write-region-inhibit-fsync", write_region_inhibit_fsync, |
| 6610 | doc: /* Non-nil means don't call fsync in `write-region'. | 6592 | doc: /* Non-nil means don't call fsync in `write-region'. |
| 6611 | This variable affects calls to `write-region' as well as save commands. | 6593 | This variable affects calls to `write-region' as well as save commands. |
| 6612 | Setting this to nil may avoid data loss if the system loses power or | 6594 | By default, it is non-nil. |
| 6613 | the operating system crashes. By default, it is non-nil in batch mode. */); | 6595 | |
| 6614 | write_region_inhibit_fsync = 0; /* See also `init_fileio' above. */ | 6596 | Although setting this to nil may avoid data loss if the system loses power, |
| 6597 | it can be a significant performance hit in the usual case, and it doesn't | ||
| 6598 | necessarily cause file-save operations to actually survive a crash. */); | ||
| 6599 | |||
| 6600 | /* For more on why fsync often fails to work on today's hardware, see: | ||
| 6601 | Zheng M et al. Understanding the robustness of SSDs under power fault. | ||
| 6602 | 11th USENIX Conf. on File and Storage Technologies, 2013 (FAST '13), 271-84 | ||
| 6603 | https://www.usenix.org/system/files/conference/fast13/fast13-final80.pdf | ||
| 6604 | |||
| 6605 | For more on why fsync does not suffice even if it works properly, see: | ||
| 6606 | Roche X. Necessary step(s) to synchronize filename operations on disk. | ||
| 6607 | Austin Group Defect 672, 2013-03-19 | ||
| 6608 | https://austingroupbugs.net/view.php?id=672 */ | ||
| 6609 | write_region_inhibit_fsync = true; | ||
| 6615 | 6610 | ||
| 6616 | DEFVAR_BOOL ("delete-by-moving-to-trash", delete_by_moving_to_trash, | 6611 | DEFVAR_BOOL ("delete-by-moving-to-trash", delete_by_moving_to_trash, |
| 6617 | doc: /* Specifies whether to use the system's trash can. | 6612 | doc: /* Specifies whether to use the system's trash can. |