[comp.unix.wizards] a creat

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)