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>
index | next in thread | previous in thread | raw e-mail
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
help
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20030120221459.GA3668>
