Subject: Re: bug#8001: cp (8.10) sparse handling fails on compressed btrfs (cp/fiemap-2)

From: Pádraig Brady <[email-masked]>
Date: Wed, 09 Feb 2011 10:57:14 +0000

On 08/02/11 03:53, Mike Frysinger wrote:
> after upgrading from coreutils 8.9 to 8.10, the sparse handling in cp is 
> silently breaking on btrfs filesystems with the compressed option enabled.  
> using --sparse=never works fine, but "auto" or "always" tend to fail.  the 
> cp/fiemap-2 test catches the issue nicely.
> 
> to reproduce (i'm using linux-2.6.37):
> file=btrfs.img
> mntp=/mnt/tmp/
> dd if=/dev/zero of=$file bs=1M count=0 seek=1024
> mkfs.btrfs $file 
> mount -t btrfs -o compress $file $mntp
> cd $mntp
> tar xf ~/coreutils-8.10.tar.xz
> cd coreutils-8.10/tests
> ./cp/fiemap-2
> 
> and this last test shows:
> Filesystem    Type   1K-blocks      Used Available Use% Mounted on
> /dev/loop0   btrfs     1048576     20420    377028   6% /mnt/tmp
> 0+0 records in
> 0+0 records out
> 0 bytes (0 B) copied, 2.7598e-05 s, 0.0 kB/s
> k k2 differ: byte 1, line 1

Eek.

That doesn't trigger here (2.6.35.10-72.fc14.i686)
because I guess this kernel doesn't honor the compress attribute:

dd if=/dev/zero of=test.size count=1000
# du -B512 test.size
1000    test.size

But on a general note, we may read more (or possibly less)
than is stored in the extent. So how to detect that?
I suppose one could use lseek() to get the current position
and see if it's ext_start + ext_length, otherwise adjust accordingly.
That would add a little overhead though.
I also notice the FIEMAP_EXTENT_DATA_ENCRYPTED and FIEMAP_EXTENT_ENCODED
flags, which could mean we only need to handle these extents specially.
Does `filefrag -v` show those for you? I see nothing here.

I don't suppose there is any facility to read the raw data
to also avoid decompressing and compressing again (sendfile, mmap?).

cheers,
Pádraig.