Date: Mon, 20 Jan 2003 14:14:59 -0800 From: David Schultz <dschultz@uclink.Berkeley.EDU> To: Matthew Dillon <dillon@apollo.backplane.com> Cc: Jan Srzednicki <winfried@student.agh.edu.pl>, current@FreeBSD.ORG Subject: Re: background fsck did not create lost+found Message-ID: <20030120221459.GA3668@HAL9000.homeunix.com> In-Reply-To: <200301201911.h0KJBZ4g065531@apollo.backplane.com> References: <Pine.GSO.4.44.0301201630350.22474-100000@student.uci.agh.edu.pl> <20030120183442.GA2778@HAL9000.homeunix.com> <200301201911.h0KJBZ4g065531@apollo.backplane.com>
next in thread | previous in thread | raw e-mail | index | archive | help
Thus spake Matthew Dillon <dillon@apollo.backplane.com>: > :However, when you are saving a new version of an important file, > :you need to be careful that the new version (and its directory > :entry) hits the disk before the old one goes away. I know that vi > :saves files in a safe way, whereas ee and emacs do not. (Emacs > :introduces only a small race, though.) Also, mv will DTRT only if > :the source and destination files live on the same filesystem. > : > > I think you have that reversed. vi just overwrites the destination > file (O_CREAT|O_TRUNC, try ktrace'ing a vi session and you will see). > I believe emacs defaults to a mode where it creates a new file and > renames it over the original. > > This means that there is a period of time where a crash may result in > the loss of the file if the vi session cannot be recovered (with vi -r) > after the fact. vi writes and fsyncs a recovery file when it opens a file for editing, and it fsyncs the real file before removing the recovery file. (I don't know how reliable vi's recovery mechanism is because I don't use vi, but at least it's ensuring that the recovery file is written to disk when it should be.) In Emacs, if 'make-backup-files' is non-nil (the default), the original file ${FILE} is renamed to ${FILE}~. Then it writes out and fsyncs a new file, which is perfectly safe. If 'make-backup-files' is nil, emacs simply omits the renaming part, unsafely overwriting the original file. The behavior in the latter case appears to be a bug, or at least an undocumented feature. Emacs even causes data loss in this case when the disk fills up! It needs to either do an fsync/rename or write and fsync a backup file for the duration of the save. Lastly, with ee, there's no backup file and no fsync. Some ktrace snippets are below. 3662 vi CALL open(0x808e260,0x2,0x180) 3662 vi NAMI "/var/tmp/vi.recover/vi.HjDlgO" 3662 vi RET open 4 ... 3662 vi CALL write(0x4,0x809a01c,0x400) 3662 vi GIO fd 4 wrote 1024 bytes "[...]old contents[...]" ... 3662 vi CALL fsync(0x4) 3662 vi RET fsync 0 ... [I edit the file from "old contents" to "new contents"] ... 3662 vi CALL open(0x8095140,0x601,0x1b6) 3662 vi NAMI "foo" 3662 vi RET open 7 ... 3662 vi CALL write(0x7,0x80bb000,0xd) 3662 vi GIO fd 7 wrote 13 bytes "new contents " 3662 vi RET write 13/0xd ... 3662 vi CALL fsync(0x7) 3662 vi RET fsync 0 3662 vi CALL close(0x7) 3662 vi RET close 0 ... 3662 vi CALL lseek(0x4,0,0x400,0,0) 3662 vi RET lseek 1024/0x400 3662 vi CALL write(0x4,0x809a01c,0x400) 3662 vi GIO fd 4 wrote 1024 bytes "[...]new contents[...]" ... 3662 vi CALL fsync(0x4) 3662 vi RET fsync 0 [The following bit only happens if make-backup-files is non-nil] 3799 emacs CALL rename(0x848c328,0x848fba8) 3799 emacs NAMI "/home/test/foo" 3799 emacs NAMI "/home/test/foo~" 3799 emacs RET rename 0 ... [This part happens unconditionally] 3799 emacs CALL open(0x848c328,0x601,0x1b6) 3799 emacs NAMI "/home/test/foo" 3799 emacs RET open 3 3799 emacs CALL write(0x3,0xbfbfae24,0x3) 3799 emacs GIO fd 3 wrote 3 bytes "new" 3799 emacs RET write 3 3799 emacs CALL write(0x3,0xbfbfae24,0x9) 3799 emacs GIO fd 3 wrote 9 bytes " contents" 3799 emacs RET write 9 3799 emacs CALL fsync(0x3) 3799 emacs RET fsync 0 3799 emacs CALL close(0x3) 3799 emacs RET close 0 To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-current" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030120221459.GA3668>