Re: FIDEDUPERANGE claims to succeed for non-identical files

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

 



On Tue, Dec 20, 2022 at 2:51 AM Zbigniew Halas <zhalas@xxxxxxxxx> wrote:
>
> Hi,
>
> I noticed a strange and misleading edge case in FIDEDUPERANGE ioctl.
> For the files with the following content:
> f1: abcd
> f2: efghi
> FIDEDUPERANGE claims to succeed and reports 4 bytes deduplicated,
> despite the files being clearly different. Strace output:
> openat(AT_FDCWD, "f1", O_RDONLY|O_CLOEXEC) = 3
> openat(AT_FDCWD, "f2", O_WRONLY|O_CLOEXEC) = 4
> ioctl(3, BTRFS_IOC_FILE_EXTENT_SAME or FIDEDUPERANGE, {src_offset=0,
> src_length=4, dest_count=1, info=[{dest_fd=4, dest_offset=0}]} =>
> {info=[{bytes_deduped=4, status=0}]}) = 0
>
> The reason is that generic_remap_checks function is doing block
> alignment of the deduplication length when the end of the destination
> file is not at the end of the deduplication range (as described in the
> comment):
> /*
> * If the user wanted us to link to the infile's EOF, round up to the
> * next block boundary for this check.
> *
> * Otherwise, make sure the count is also block-aligned, having
> * already confirmed the starting offsets' block alignment.
> */
>
> So it effectively becomes a zero-length deduplication, which succeeds.
> Despite that it's reported as a successful 4 bytes deduplication.

Ouch!

>
> For a very similar test case, but with the files of the same length:
> f3: abcd
> f4: efgh
> FIDEDUPERANGE fails with FILE_DEDUPE_RANGE_DIFFERS. Strace output:
> openat(AT_FDCWD, "f3", O_RDONLY|O_CLOEXEC) = 3
> openat(AT_FDCWD, "f4", O_WRONLY|O_CLOEXEC) = 4
> ioctl(3, BTRFS_IOC_FILE_EXTENT_SAME or FIDEDUPERANGE, {src_offset=0,
> src_length=4, dest_count=1, info=[{dest_fd=4, dest_offset=0}]} =>
> {info=[{bytes_deduped=0, status=1}]}) = 0
>
> For this case generic_remap_checks does not alter deduplication
> length, and deduplication fails when comparing the content of the
> files.
>

Thanks for the analysis.
Would you be interested in trying to fix the bug and writing a test?
I can help if you would like.

It's hard to follow all the changes since
54dbc1517237 ("vfs: hoist the btrfs deduplication ioctl to the vfs")
in v4.5, but it *looks* like this behavior might have been in btrfs,
before the ioctl was promoted to vfs.. not sure.

We have fstests coverage for the "good" case of same size src/dst
(generic/136), but I didn't find a test for the non-same size src/dst.

In any case, vfs_dedupe_file_range_one() and ->remap_file_range()
do not even have an interface to return the actual bytes_deduped,
so I do not see how any of the REMAP_FILE_CAN_SHORTEN cases
are valid, regardless of EOF.

What am I missing?

Thanks,
Amir.



[Index of Archives]     [Linux Ext4 Filesystem]     [Union Filesystem]     [Filesystem Testing]     [Ceph Users]     [Ecryptfs]     [NTFS 3]     [AutoFS]     [Kernel Newbies]     [Share Photos]     [Security]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux Cachefs]     [Reiser Filesystem]     [Linux RAID]     [NTFS 3]     [Samba]     [Device Mapper]     [CEPH Development]

  Powered by Linux