mangler@cit-vax.Caltech.Edu (System Mangler) (09/08/87)
creat() clobbers the file before anything is written. I wonder if this behaviour is necessary. Consider an alternate implementation, which instead of truncating the file upon creat(), just sets a "deferred truncate" flag. Upon a close() or lseek(), the file is truncated at the file pointer position if the flag is still set, and then the flag is reset. If the old and new sizes are similar, we've saved ourselves a lot of block allocation/deallocation. (Look at 4.3bsd rwhod sometime). If a long-running program does a creat() and the machine crashes before anything is written, the original contents of the file are left untouched, gaining some of the utility of multiple versions. If you copy a file over itself, it doesn't clobber the file. Other than tail -f, how much would this break? Don Speck speck@vlsi.caltech.edu {amdahl,rutgers}! die and n of
ron@topaz.rutgers.edu.UUCP (09/08/87)
We use the deferred truncate property to make cp/rcp totally fool proof for dunderheads who like to copy files on top of themselves (note you can not check for this in rcp or with remote file systems). The way we did it is to open files that exits rather than always creating over them. When we are finished we truncate them to the right length. The user gets what he asked for, each block is read and written back into the same place, but the file is not destroyed. -Ron
tim@brspyr1.BRS.Com (Tim Northrup) (09/08/87)
in article <3921@cit-vax.Caltech.Edu>, mangler@cit-vax.Caltech.Edu says: > > Consider an alternate implementation, which instead of truncating > the file upon creat(), just sets a "deferred truncate" flag. Upon > a close() or lseek(), the file is truncated at the file pointer > position if the flag is still set, and then the flag is reset. What happens if the system crashes half way through a copy? I would think you would lose track of where the "real" EOF is for the "new" file. This may not be bad for most things, but for others it could be a real pain, specifically in cases where an operation takes an extreme amount of time and is restartable -- we would not be able to restart if we did not know where the real EOF is. > If a long-running program does a creat() and the machine crashes > before anything is written, the original contents of the file are > left untouched, gaining some of the utility of multiple versions. This is true, but the problem comes if the long-running program DOES write something -- the file is then in a corrupt state with no way of telling where the "new" stuff ends and the "old" stuff continues. > If you copy a file over itself, it doesn't clobber the file. If you open the file for "read" first, then "creat()", the file won't get clobbered until you close the read end. I believe that even if the system crashes in the middle of this, the file will not be clobbered. > Don Speck speck@vlsi.caltech.edu {amdahl,rutgers}!cit-vax!speck -- ============================================ Tim "The Enchanter" Northrup tim@brspyr1.BRS.Com uunet!steinmetz!brspyr1!tim
mouse@mcgill-vision.UUCP (09/20/87)
In article <1765@brspyr1.BRS.Com>, tim@brspyr1.BRS.Com (Tim Northrup) writes: > in article <3921@cit-vax.Caltech.Edu>, mangler@cit-vax.Caltech.Edu says: >> Consider an alternate implementation, which instead of truncating >> the file upon creat(), just sets a "deferred truncate" flag. [...] >> If you copy a file over itself, it doesn't clobber the file. > If you open the file for "read" first, then "creat()", the file won't > get clobbered until you close the read end. I believe that even if > the system crashes in the middle of this, the file will not be > clobbered. I assume you are speaking of the way things work now? Close, but no cigar. If you open a file for read, and then creat() it, you will find that all the data has disappeared. If you open it for read, unlink() it, and then creat() it, you will have two files, one of which is full of data but has no directory entry and the other which is new but appears in a directory. If the system crashes fsck will generally trash the unreferenced one and leave the other. I seem to recall a suggestion heard here a while ago, which seems eminently sensible. Have some means to create an anonymous file, and then have a syscall to enter such an anonymous file in a directory. Since the anonymous file must be on the same filesystem as the directory, the first half could be done by using mktemp(), creat(), and unlink(). Then we need a syscall which is sort of like rename() except that the "from" file is a file descriptor instead of a pathname. But using a rename()-style call would lose link information. And none of this helps you where you can write the file but not the directory. I guess you Just Can't Win. der Mouse (mouse@mcgill-vision.uucp)