bug-tar
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Bug-tar] --sparse is broken on filesystems where small files may ha


From: Andrew J. Schorr
Subject: Re: [Bug-tar] --sparse is broken on filesystems where small files may have zero blocks
Date: Tue, 29 Oct 2013 11:29:26 -0400
User-agent: Mutt/1.5.21 (2010-09-15)

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



reply via email to

[Prev in Thread] Current Thread [Next in Thread]