(Illustration by Gaich Muramatsu)
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