HPFS and truncate

Scott Johnson (johnsos@ECE.ORST.EDU)
Mon, 23 Oct 1995 18:42:35 -0700


I tried sending this out once before, and it appears to have found its way
into a bit bucket somewhere. If this appears twice anywhere, I apologize.

For those of you who don't know, I am currently working on making HPFS
read/write in Linux. So far, it can: create files and directories, extend
files and directories (allocate more space), write to file, and perform
various miscellaneous features (ie touch). It cannot yet delete files or
directories, rename files or directories, or truncate files. Truncate is next
on my list, and I have a few questions to ask of you.

First of all, what is Linux's policy on using truncate to increase a file's
size? I've noticed that some filesystems (MSDOS in particular, see below)
do not react kindly to this. If Linux's policy is to not support this
feature, and to enforce this on all filesystems, the rest of this post is
moot. If, OTOH the policy of Linux is to support it, or to leave it up to the
filesystem, I would like to support this for HPFS, as a possible method of
preallocating space for files.

Currently, sys_truncate() works thusly. First, it looks up the name and
checks to make sure that the truncate operation is legal in the first
place. Then it gets write permission for the inode, changes the file size
(inode->i_size), calls the filesystem-specific truncate command (if it
exists), then in modifies the ctime and mtime and calls notify_change, and
finally releases the inode. sys_ftruncate is similar (without the lookup
stuff.)

For truncates which reduce the file size, this scheme works great. For
truncates which INCREASE the file size, however, there is a problem with
this. HPFS, unlike traditional Unix filesystems, does not support holes.
Thus, in case such a truncate operation occurs, hpfs_truncate will have to
allocate and clear out space to hold the extra data.

This creates a rather troublesome race condition with read and bmap, in that
they may try to access stuff that isn't ready yet. The easiest solution to
this problem is to do what write() does--not change the file size until
AFTER everything is finished--this will cause any read which attempts to
access this space to safely return EOF. I would like to do this with
hpfs_truncate as well, BUT sys_truncate (and sys_ftruncate, and a few other
places) set i_size BEFORE calling the FS-specific truncate routine. Thus the
pre-truncate size is unknown.

Two solutions come to mind. One, which is a MAJOR kludge, is to keep a spare
copy of the file size in the struct hpfs_inode_info, and change THAT whenever
inode->i_size changes. That way, when hpfs_truncate is called, it knows what
the "old" file size is. This works, but isn't very elegant... :)

The other solution is to change the definitions of the FS-specific truncate
functions. Currently, they are prototyped as:

void fstype_truncate (struct inode * inode);

where fstype is one of (ext, ext2, hpfs, msdos, minix, etc.)

It would be nice to change them to:

int fstype_truncate (struct ionde * inode, off_t old_size);

allowing sys_truncate (or whatever) to pass the old file size to the FS-dep.
truncate routines. The existing fstype_truncate routines can ignore this
extra parameter, of course. However, hpfs_truncate can use it to its
advantage. The return type is given as int so that the truncate can safely
fail with -ENOSPC if there isn't enough space (other errors could creep up,
I'm sure.) The obvious problem with this is that it would require
modification to both linux/fs/open.c, as well as all of the fs-specific
sys_truncate commands. The modifications needed are trivial; still, I don't
like to mess with non-HPFS code TOO much without asking. Especially since
this modification will require many files to be altered.

Any comments from the list? Hopefully, I'll have a patch ready in about
a month, so get those HPFS partitions backed up. :)

Oh, BTW....while looking at the code to see how Linux handles things like this,
I found a bug in the MS-DOS filesystem. Attempting to use truncate to
enlarge a file in MS-DOS will (at least it did when I tried it) result in the
file being corrupted. (I did it, and could no longer access the file from
Linux. I rebooted, and couldn't access it from DOS, either. Running SCANDISK
revealed that the file had indeed been corrupted.)

/sj/

Scott Johnson -- Graduate Slave, ECE Department, Oregon State University
Check out my new (but unfinished) Web page--http://www.ece.orst.edu/~johnsos
-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
If the Republicans are so opposed to having a pot-smoking draft dodger as
President, then why did they elect one as Speaker?