Skip to content

Commit 0e7b824

Browse files
Li Zefanchrismason-xx
authored andcommitted
Btrfs: don't make a file partly checksummed through file clone
To reproduce the bug: # mount /dev/sda7 /mnt # dd if=/dev/zero of=/mnt/src bs=4K count=1 # umount /mnt # mount -o nodatasum /dev/sda7 /mnt # dd if=/dev/zero of=/mnt/dst bs=4K count=1 # clone_range -s 4K -l 4K /mnt/src /mnt/dst # echo 3 > /proc/sys/vm/drop_caches # cat /mnt/dst # dmesg ... btrfs no csum found for inode 258 start 0 btrfs csum failed ino 258 off 0 csum 2566472073 private 0 It's because part of the file is checksummed and the other part is not, and then btrfs will complain checksum is not found when we read the file. Disallow file clone if src and dst file have different checksum flag, so we ensure a file is completely checksummed or unchecksummed. Signed-off-by: Li Zefan <[email protected]> Signed-off-by: Chris Mason <[email protected]>
1 parent 71ef078 commit 0e7b824

File tree

1 file changed

+5
-0
lines changed

1 file changed

+5
-0
lines changed

fs/btrfs/ioctl.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,6 +2185,11 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd,
21852185
if (!(src_file->f_mode & FMODE_READ))
21862186
goto out_fput;
21872187

2188+
/* don't make the dst file partly checksummed */
2189+
if ((BTRFS_I(src)->flags & BTRFS_INODE_NODATASUM) !=
2190+
(BTRFS_I(inode)->flags & BTRFS_INODE_NODATASUM))
2191+
goto out_fput;
2192+
21882193
ret = -EISDIR;
21892194
if (S_ISDIR(src->i_mode) || S_ISDIR(inode->i_mode))
21902195
goto out_fput;

0 commit comments

Comments
 (0)