Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I vaguely recall reading somewhere that there used to be, in some Unices a way to open an existing file for writing, with a flag that asked the kernel to use the old version (for other processes accessing it for reading), until the "new" version was fully written (fd closed), from which point the file appeared as the new version.

In another words, other processes either saw the old version, or the new one, never an incompletely-written one.

Can someone knowledgeable point me to a reference?

share|improve this question
    
Sounds like what Plan 9 might do, but no. –  Gilles Nov 11 '11 at 23:14
2  
Sounds like Files-11 on OpenVMS: "Every time a file is saved, rather than overwriting the existing version, a new file with the same name but an incremented version number is created." –  Mat Nov 29 '11 at 13:10
    
Why did you ask? Do you need that functionality, or was it just curiosity? –  Nils Jan 28 '12 at 20:53
    
I would be happy to have that functionality, and I recalled reading somewhere that it existed. So a mixture of both need and curiosity. –  eudoxos Jan 29 '12 at 11:03
    
All Unix systems allow this in another manner - create new file in the same directory, fill with changed contents and do atomic rename. This is much more expensive for small changes but working. –  Netch Mar 24 '12 at 14:55
add comment

3 Answers

What youre describing sounds exactly like a basic rename to overwrite a file.

When you rename/move one file on top of another, the old file is unlinked. Meaning the file still exists, but it isnt in the filesystem tree any more. Thus old applications will continue to be able to access the file as long as they keep it open. Once all applications have closed the old file, then its actually unallocated on the disk.

The rename system call is an atomic operation. So to do this you would create a new file under a different name, and then call rename to rename the temporary file as the one you want to replace. Since the operation is atomic, there is absolutely no period where the file is missing. It instantly goes from old file to new file.
Note though that the temporary file and the file being replaced have to reside on the mount point.

share|improve this answer
    
You only can use that if your program is specifically written with the functionality in mind. In this case, however, it was an OS feature, whence even regular programs were given this atomical semantics automatically. –  eudoxos Mar 29 '12 at 8:05
    
@eudoxos your comment makes no sense. Youre saying programs would have to be written specifically to do the rename swap thing. Even if such a 'OS feature' as youre talking about existed, the program would still have to be written to take advantage of that as well. Whats the difference? –  Patrick Mar 29 '12 at 11:39
    
There is a difference if you pass a (possibly unsupported) flag to the open syscall or if you have to do what you describe by hand. –  eudoxos Mar 30 '12 at 11:10
add comment

As Patrick writes, the usual way to do this is to write the new version to a separate file, and when finished rename the new version to the old filename, overwriting it atomically. This second operation is called overwrite-by-rename.

Now, some references:

share|improve this answer
add comment

This reminds me of Allocate On Flush. When a filesystem uses this feature, instead of writing data directly to disk, it subtracts the size of the data to be written from the disk's free space counter, and holds the data in memory until it a sync system call is performed or the kernel decides to flush the dirty buffers.

In this case, if the file is being modified by one process, and gets opened by another process, the latter process will "see" the unmodified (or "old" if you prefer) version of the file.

Of course, the above are theoretical and depend on various factors, and I'd say a bit unpredictable -since you don't know exactly when the kernel is going flush the dirty pages. For instance in Linux (as you can also read in section 15.3 of Understanding the Linux Kernel), the dirty pages get written to disk under the following conditions:

  • The page cache gets too full and more pages are needed, or the number of dirty pages becomes too large.

  • Too much time has elapsed since a page has stayed dirty.

  • A process requests all pending changes of a block device or of a particular file to be flushed; it does this by invoking a sync(), fsync(), or fdatasync() system call.

This feature is known to be implemented in HFS+, XFS, Reiser4, ZFS, Btrfs and ext4 filesystems.

share|improve this answer
2  
What you describe is a filesystem technique which should be invisible from userspace (and thus does not do what you indicate) on POSIX (file)systems (see write: "If a read() of file data can be proven (by any means) to occur after a write() of the data, it must reflect that write(), even if the calls are made by different processes."). Other processes will not see the old data (on POSIX). –  Mat Nov 29 '11 at 13:03
    
Thanks for the correction. I guess my understanding of this filesystem technique was wrong. –  dkaragasidis Nov 29 '11 at 14:45
    
Right, this looks like something else. I vaguely recall now that it was in an interview with RMS that he mentioned this feature, perhaps it was some old arcane system that never lived outside academia... Thanks anyway. –  eudoxos Nov 29 '11 at 17:33
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.