diff options
| author | Paul Eggert | 2013-05-04 17:51:49 -0700 |
|---|---|---|
| committer | Paul Eggert | 2013-05-04 17:51:49 -0700 |
| commit | cbee2131718baa6389713bb551bcfd5c72b39035 (patch) | |
| tree | 2f28d12ed0cac14194f0e9a56376b19ccad3c2b5 /src | |
| parent | fd3a9a6b378e556c3b09b217920d95cb129a13d6 (diff) | |
| download | emacs-cbee2131718baa6389713bb551bcfd5c72b39035.tar.gz emacs-cbee2131718baa6389713bb551bcfd5c72b39035.zip | |
`write-region-inhibit-fsync' defaults to noninteractive.
* cmdargs.texi (Initial Options):
* files.texi (Customize Save): Document this.
* etc/NEWS: Document this.
* src/fileio.c (syms_of_fileio): Implement this.
* src/filelock.c (create_lock_file): If symbolic links don't work, so
we use a regular file as a lock file, do not fsync the lock file;
it's not needed.
Fixes: debbugs:14273
Diffstat (limited to 'src')
| -rw-r--r-- | src/ChangeLog | 9 | ||||
| -rw-r--r-- | src/fileio.c | 35 | ||||
| -rw-r--r-- | src/filelock.c | 10 |
3 files changed, 37 insertions, 17 deletions
diff --git a/src/ChangeLog b/src/ChangeLog index 86327fc7fb2..a3e466954cb 100644 --- a/src/ChangeLog +++ b/src/ChangeLog | |||
| @@ -1,3 +1,11 @@ | |||
| 1 | 2013-05-05 Paul Eggert <eggert@cs.ucla.edu> | ||
| 2 | |||
| 3 | `write-region-inhibit-fsync' defaults to noninteractive (Bug#14273). | ||
| 4 | * fileio.c (syms_of_fileio): Implement this. | ||
| 5 | * filelock.c (create_lock_file): If symbolic links don't work, so | ||
| 6 | we use a regular file as a lock file, do not fsync the lock file; | ||
| 7 | it's not needed. | ||
| 8 | |||
| 1 | 2013-05-04 Stefan Monnier <monnier@iro.umontreal.ca> | 9 | 2013-05-04 Stefan Monnier <monnier@iro.umontreal.ca> |
| 2 | 10 | ||
| 3 | * minibuf.c (Fread_minibuffer, Feval_minibuffer): Move to Elisp. | 11 | * minibuf.c (Fread_minibuffer, Feval_minibuffer): Move to Elisp. |
| @@ -51,6 +59,7 @@ | |||
| 51 | size. | 59 | size. |
| 52 | 60 | ||
| 53 | 2013-04-26 Paul Eggert <eggert@cs.ucla.edu> | 61 | 2013-04-26 Paul Eggert <eggert@cs.ucla.edu> |
| 62 | |||
| 54 | Port better to AIX (Bug#14258). | 63 | Port better to AIX (Bug#14258). |
| 55 | * lisp.h (ENUM_BF) [__IBMC__]: Make it 'unsigned int' here, too, | 64 | * lisp.h (ENUM_BF) [__IBMC__]: Make it 'unsigned int' here, too, |
| 56 | to pacify AIX xlc. | 65 | to pacify AIX xlc. |
diff --git a/src/fileio.c b/src/fileio.c index 1049522e5a9..38b98a243b2 100644 --- a/src/fileio.c +++ b/src/fileio.c | |||
| @@ -4979,15 +4979,14 @@ This calls `write-region-annotate-functions' at the start, and | |||
| 4979 | 4979 | ||
| 4980 | immediate_quit = 0; | 4980 | immediate_quit = 0; |
| 4981 | 4981 | ||
| 4982 | /* fsync appears to change the modtime on BSD4.2. | 4982 | /* fsync is not crucial for auto-save files, since they might lose |
| 4983 | Disk full in NFS may be reported here. */ | 4983 | some work anyway. */ |
| 4984 | /* mib says that closing the file will try to write as fast as NFS can do | ||
| 4985 | it, and that means the fsync here is not crucial for autosave files. */ | ||
| 4986 | if (!auto_saving && !write_region_inhibit_fsync) | 4984 | if (!auto_saving && !write_region_inhibit_fsync) |
| 4987 | { | 4985 | { |
| 4988 | /* Transfer data and metadata to disk, retrying if interrupted. Also, | 4986 | /* Transfer data and metadata to disk, retrying if interrupted. |
| 4989 | ignore EINVAL which happens when fsync is not supported on this | 4987 | fsync can report a write failure here, e.g., due to disk full |
| 4990 | file. */ | 4988 | under NFS. But ignore EINVAL, which means fsync is not |
| 4989 | supported on this file. */ | ||
| 4991 | while (fsync (desc) != 0) | 4990 | while (fsync (desc) != 0) |
| 4992 | if (errno != EINTR) | 4991 | if (errno != EINTR) |
| 4993 | { | 4992 | { |
| @@ -6069,11 +6068,29 @@ in the buffer; this is the default behavior, because the auto-save | |||
| 6069 | file is usually more useful if it contains the deleted text. */); | 6068 | file is usually more useful if it contains the deleted text. */); |
| 6070 | Vauto_save_include_big_deletions = Qnil; | 6069 | Vauto_save_include_big_deletions = Qnil; |
| 6071 | 6070 | ||
| 6071 | /* fsync can be a significant performance hit. Often it doesn't | ||
| 6072 | suffice to make the file-save operation survive a crash. For | ||
| 6073 | batch scripts, which are typically part of larger shell commands | ||
| 6074 | that don't fsync other files, its effect on performance can be | ||
| 6075 | significant so its utility is particularly questionable. | ||
| 6076 | Hence, for now by default fsync is used only when interactive. | ||
| 6077 | |||
| 6078 | For more on why fsync often fails to work on today's hardware, see: | ||
| 6079 | Zheng M, Tucek J, Qin F, Lillibridge M. Understanding the | ||
| 6080 | robustness of SSDs under power fault. 11th USENIX Conference on | ||
| 6081 | File and Storage Technologies, 2013 (FAST '13), 271-84 | ||
| 6082 | http://www.usenix.org/system/files/conference/fast13/fast13-final80.pdf | ||
| 6083 | |||
| 6084 | For more on why fsync does not suffice even if it works properly, see: | ||
| 6085 | Roche X. Necessary step(s) to synchronize filename operations on disk. | ||
| 6086 | Austin Group Defect 672, 2013-03-19 | ||
| 6087 | http://austingroupbugs.net/view.php?id=672 */ | ||
| 6072 | DEFVAR_BOOL ("write-region-inhibit-fsync", write_region_inhibit_fsync, | 6088 | DEFVAR_BOOL ("write-region-inhibit-fsync", write_region_inhibit_fsync, |
| 6073 | doc: /* Non-nil means don't call fsync in `write-region'. | 6089 | doc: /* Non-nil means don't call fsync in `write-region'. |
| 6074 | This variable affects calls to `write-region' as well as save commands. | 6090 | This variable affects calls to `write-region' as well as save commands. |
| 6075 | A non-nil value may result in data loss! */); | 6091 | Setting this to nil may avoid data loss if the system loses power or |
| 6076 | write_region_inhibit_fsync = 0; | 6092 | the operating system crashes. */); |
| 6093 | write_region_inhibit_fsync = noninteractive; | ||
| 6077 | 6094 | ||
| 6078 | DEFVAR_BOOL ("delete-by-moving-to-trash", delete_by_moving_to_trash, | 6095 | DEFVAR_BOOL ("delete-by-moving-to-trash", delete_by_moving_to_trash, |
| 6079 | doc: /* Specifies whether to use the system's trash can. | 6096 | doc: /* Specifies whether to use the system's trash can. |
diff --git a/src/filelock.c b/src/filelock.c index f17d3182eab..de6aba8385c 100644 --- a/src/filelock.c +++ b/src/filelock.c | |||
| @@ -437,14 +437,8 @@ create_lock_file (char *lfname, char *lock_info_str, bool force) | |||
| 437 | if (emacs_write (fd, lock_info_str, lock_info_len) != lock_info_len | 437 | if (emacs_write (fd, lock_info_str, lock_info_len) != lock_info_len |
| 438 | || (need_fchmod && fchmod (fd, world_readable) != 0)) | 438 | || (need_fchmod && fchmod (fd, world_readable) != 0)) |
| 439 | err = errno; | 439 | err = errno; |
| 440 | else | 440 | /* There is no need to call fsync here, as the contents of |
| 441 | while (fsync (fd) != 0) | 441 | the lock file need not survive system crashes. */ |
| 442 | if (errno != EINTR) | ||
| 443 | { | ||
| 444 | if (errno != EINVAL) | ||
| 445 | err = errno; | ||
| 446 | break; | ||
| 447 | } | ||
| 448 | if (emacs_close (fd) != 0) | 442 | if (emacs_close (fd) != 0) |
| 449 | err = errno; | 443 | err = errno; |
| 450 | if (!err && rename_lock_file (nonce, lfname, force) != 0) | 444 | if (!err && rename_lock_file (nonce, lfname, force) != 0) |