Coda File System

Re: strange lstat*() behaviour

From: Jan Harkes <jaharkes_at_cs.cmu.edu>
Date: Mon, 18 Mar 2002 15:08:17 -0500
Yeah, st_blocks and st_blocksize are pretty much unreliable at the
moment. I've been asking for a 'getattr' VFS call so that we have more
control in the Coda kernel module, and Al Viro has been saying 'any
moment now' for the past 2 years ;)

On Mon, Mar 18, 2002 at 08:35:35PM +0100, Ivan Popov wrote:
> lstat64("scp", {st_dev=makedev(0, 8), st_ino=229379461,
> st_mode=S_IFREG|0755, st_nlink=1, st_uid=1000, st_gid=65534,
> st_blksize=8192, st_blocks=0, st_size=27740, st_atime=2002/03/18-20:28:05,
> st_mtime=2002/03/18-20:28:05, st_ctime=2002/03/18-20:28:05}) = 0

Right after writing to the file, this one is incorrect...

> A couple of minutes later:
> lstat64("scp", {st_dev=makedev(0, 8), st_ino=229248381,
> st_mode=S_IFREG|0755, st_nlink=1, st_uid=1000, st_gid=65534,
> st_blksize=8192, st_blocks=55, st_size=27740,
> st_atime=2002/03/18-20:16:17, st_mtime=2002/03/18-20:16:17,
> st_ctime=2002/03/18-20:16:17}) = 0

And this one is correct.

> I was able to revert to the "wrong" behaviour again by running
> "strip ..../bin/*" again.
> 
> Is it something to be concerned about?.. :)
> Can it help to solve some other mystical things?

Well it really is very simple. The VFS looks at whatever things are set
in the 'Coda inode', however write is updating the fields in the
underlying containerfile inode. After a while, the kernel cache for the
inode is dropped/reused, and then when we refetch the inode attributes
from venus the Coda inode will contain the corrected information.

st_blocks used to be calculated from the length, but a misunderstanding
about st_blocksize/st_blocks introduced a patch that was later partly
reverted which broke this. It shouldn't be too critical, afaik only 'du'
is actually using this field.

There are 2 possible patches, one is to set st_blocksize to 0, the other
is to 'reset' i_blocks whenever we change i_size after a write operation.

Jan

--- linux/fs/coda/file.c.orig	Wed Mar  6 22:37:17 2002
+++ linux/fs/coda/file.c	Mon Mar 18 15:02:17 2002
@@ -69,6 +69,7 @@
 
 	cfile->f_flags = flags;
 	inode->i_size = cinode->i_size;
+	inode->i_blocks = (inode->i_size + 511) >> 9;
 	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 	up(&inode->i_sem);
 
Received on 2002-03-18 15:10:07