On Tue, Oct 29, 2013 at 08:06:40AM -0700, Tim Kientzle wrote: > What about this sparse file: > > $ truncate -s 10G file && echo hello >> file > > Are there filesystems where the 6 bytes here would be > stored in the inode? That would give a large sparse > file with zero allocated blocks but not zero content.
On my netapp, that does not result in a file with zero blocks. But I can't say for sure it could never happen on any filesystem. This is why I find the current logic a bit frightening. It is not robust to assume that a file with zero blocks is empty. The assertion being made is that the test in ST_IS_SPARSE is guaranteed to protect against all cases where st_blocks is 0 but the file is not all zeroes. >From lib/system.h: /* Network Appliance file systems store small files directly in the inode if st_size <= 64; in this case the number of blocks can be zero. Perhaps other file systems have similar problems; so, somewhat arbitrarily, do not consider a file to be sparse if it has no blocks but st_size < ST_NBLOCKSIZE. */ #define ST_IS_SPARSE(st) \ (ST_NBLOCKS (st) \ < ((st).st_size / ST_NBLOCKSIZE \ + ((st).st_size % ST_NBLOCKSIZE != 0 \ && (st).st_size / ST_NBLOCKSIZE != 0))) A problem would occur if ST_IS_SPARSE is true and ST_NBLOCKS is zero, but the file is not completely empty. For that to happen, I think we need a file where ST_NBLOCKS is zero and (st_size >= ST_NBLOCKSIZE). So the implicit assumption here is that there are no filesystems that can store a non-empty file with length >= the block size in the inode. I don't know if that's guaranteed always to be true. Regards, Andy