bug-tar
[Top][All Lists]
Advanced

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

Re: [Bug-tar] Detection of sparse files is broken on btrfs


From: Andreas Dilger
Subject: Re: [Bug-tar] Detection of sparse files is broken on btrfs
Date: Wed, 17 Jan 2018 14:09:07 -0700

On Jan 9, 2018, at 10:02 AM, Tim Kientzle <address@hidden> wrote:
>> Paul Eggert <address@hidden> wrote:
>> 
>>> POSIX does not require that st_nblocks remain constant across any system
>>> call. It doesn't even require that it remain constant if you merely call
>>> stat twice on the same file, without doing anything else in between.
> 
> The real question is then:
> 
> What is the most efficient (preferably portable) way for an archiving program 
> (such as tar) to determine whether it should archive a particular file as 
> sparse or non-sparse?
> 
> Historically, we’ve compared st_nblocks to st_size to quickly determine if a 
> file is sparse in order to avoid the SEEK_HOLE scan in most cases.  Some 
> programs even consider st_nblocks == 0 as an indication that a file is 
> entirely sparse.  Based on the claims I’ve read here, it sounds like 
> st_nblocks can no longer be trusted for these purposes.

We had this same problem with ext4 with delayed allocation (2008) and later
with the inline data feature (2013, store data inside the inode), as well
as Lustre (2011, does writeback caching on clients before specific blocks
are allocated on storage for a file).  In both cases, we ended up changing
the filesystem code to return st_blocks != 0 to userspace if there is dirty
data pending writes or if data is stored in the inode.  As such, the value
returned in st_blocks can be just an estimate, and can't reflect the actual
space used by the servers, but I'm not aware of any applications that care
about the actual st_blocks value other than zero or non-zero.

Even if tar were fixed today, there are older versions of tar that still use
the st_blocks == 0 heuristic, and likely other tools that can't be fixed
retroactively, so returning st_blocks == 0 for a file with data is just not
a good idea. I would recommend to the btrfs developers to fix this problem
as well, and backport it to stable kernels as well.

That said, something _also_ should be done in tar to avoid the problem for
older versions of btrfs, or other filesystems that have similar issues.  I
would recommend _against_ doing a filesystem-specific check like in Pavel's
btrfs-wholesparse.patch, since this is clearly a problem that is wider than
just btrfs, and if btrfs is fixed in the future the check will be useless
overhead (it will do a statfs .

> So is there some other way to quickly identify sparse files so we can avoid 
> the SEEK_HOLE scan for non-sparse files?

Given that calling SEEK_HOLE is also going to have some cost, my suggestion
would be to ignore st_blocks completely for small files (size < 64KB) and
just read the file in this case, since the overhead of reading will probably
be about the same as checking if any blocks are allocated.  If no blocks are
allocated, then the read will not do any disk IO, and if there are blocks
allocated they would have needed to be read from disk anyway and SEEK_HOLE
would be pure overhead.

To catch larger files that have been written to cache but haven't flushed
data to disk yet, it might still make sense to use SEEK_HOLE on larger files
with st_blocks == 0, especially if they have a recent mtime.

Cheers, Andreas


Attachment: signature.asc
Description: Message signed with OpenPGP


reply via email to

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