From 457a288cb5c7dccd88632dab5a903bd00a2142f0 Mon Sep 17 00:00:00 2001 From: Filipe Manana Date: Wed, 14 Mar 2018 20:11:09 +0000 Subject: Btrfs-progs: check, fix false error reports for shared prealloc extents Under some cases the filesystem checker reports an error when it finds checksum items for an extent that is referenced by an inode as a prealloc extent. Such cases are not an error when the extent is actually shared (was cloned/reflinked) with other inodes and was written through one of those other inodes. Example: $ mkfs.btrfs -f /dev/sdb $ mount /dev/sdb /mnt $ touch /mnt/foo $ xfs_io -c "falloc 0 256K" /mnt/foo $ sync $ xfs_io -c "pwrite -S 0xab 0 256K" /mnt/foo $ touch /mnt/bar $ xfs_io -c "reflink /mnt/foo 0 0 256K" /mnt/bar $ xfs_io -c "fsync" /mnt/bar $ mount /dev/sdb /mnt $ umount /mnt $ btrfs check /dev/sdc Checking filesystem on /dev/sdb UUID: 52d3006e-ee3b-40eb-aa21-e56253a03d39 checking extents checking free space cache checking fs roots root 5 inode 257 errors 800, odd csum item ERROR: errors found in fs roots found 688128 bytes used, error(s) found total csum bytes: 256 total tree bytes: 163840 total fs tree bytes: 65536 total extent tree bytes: 16384 btree space waste bytes: 138819 file data blocks allocated: 10747904 referenced 10747904 $ echo $? 1 So teach check to not report such cases as errors by checking if the extent is shared with other inodes and if so, consider it an error the existence of checksum items only if all those other inodes are referencing the extent as a prealloc extent. This case can be hit often when running the generic/475 testcase from fstests. A test case will follow in a separate patch. Signed-off-by: Filipe Manana Reviewed-by: Nikolay Borisov Signed-off-by: David Sterba --- check/mode-common.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'check/mode-common.h') diff --git a/check/mode-common.h b/check/mode-common.h index ffae782b..877c1aa9 100644 --- a/check/mode-common.h +++ b/check/mode-common.h @@ -80,6 +80,8 @@ static inline int fs_root_objectid(u64 objectid) return is_fstree(objectid); } +int check_prealloc_extent_written(struct btrfs_fs_info *fs_info, + u64 disk_bytenr, u64 num_bytes); int count_csum_range(struct btrfs_fs_info *fs_info, u64 start, u64 len, u64 *found); int insert_inode_item(struct btrfs_trans_handle *trans, -- cgit v1.2.3