Btrfs-progs: check, fix csum check in the presence of non-inlined refs
PATCH 1/1 Btrfs-progs: check, fix csum check in the presence of non-inlined refs
When we have non-inlined extent references, we were failing to find the corresponding extent item for an existing csum item in the csum tree.
Reproducer:
mkfs.btrfs -f /dev/sdd
mount /dev/sdd /mnt
xfs_io -f -c "falloc 780366 135302" /mnt/foo xfs_io -c "falloc 327680 151552" /mnt/foo xfs_io -c "pwrite -S 0xff -b 131072 0 131072" /mnt/foo sync
for i in seq 1 40; do btrfs subvolume snapshot /mnt /mnt/snap$i ; done umount /mnt
btrfs check /dev/sdd
The check command exited with status 1 and the following output:
Checking filesystem on /dev/sdd
UUID: 2416ab5f-9d71-457e-bb13-a27d4f6b399a
checking extents
checking free space cache
checking fs roots
checking csums
There are no extents for csum range 12980224-12984320 Csum exists for 12980224-12984320 but there is no extent record found 1388544 bytes used err is 1
total csum bytes: 132
total tree bytes: 704512
total fs tree bytes: 573440
total extent tree bytes: 16384
btree space waste bytes: 564479
file data blocks allocated: 19341312
referenced 14606336
Btrfs v3.14.1-94-g80597e7
After this change it no longer erroneously reports a missing extent for the csum item and exits with a status of 0.
Also added missing btrfs_prev_leaf() return value checks, as we were ignoring errors and non-existence of left siblings completely.
--- cmds-check.c | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-)
cmds-check.c +27 -11
@@ -3650,8 +3650,7 @@ static int check_extent_exists(struct btrfs_root *root, u64 bytenr, key.objectid = bytenr; key.type =BTRFS_EXTENT_ITEM_KEY ; - key.offset =0 ; - + key.offset = (u64)-1 ; again: ret = btrfs_search_slot(NULL, root->fs_info->extent_root, &key, path,
@@ -3661,10 +3660,17 @@ again:btrfs_free_path (path);return ret; }else if (ret) { -if (path->slots[0 ]) +if (path->slots[0 ] >0 ) { path->slots[0 ]--; -else -btrfs_prev_leaf (root, path); + }else { + ret =btrfs_prev_leaf (root, path); +if (ret <0 ) { + goto out; + }else if (ret >0 ) { + ret =0 ; + goto out; + } + } }btrfs_item_key_to_cpu (path->nodes[0 ], &key, path->slots[0 ]);
@@ -3674,13 +3680,22 @@ again:* bytenr, so walk back one more just in case. Dear future traveler, * first congrats on mastering time travel. Now if it's not too much * trouble could you go back to 2006 and tell Chris to make the -* BLOCK_GROUP_ITEM_KEY lower than the EXTENT_ITEM_KEY please? +* BLOCK_GROUP_ITEM_KEY (and BTRFS_*_REF_KEY) lower than the +* EXTENT_ITEM_KEY please? */ -if (key.type ==BTRFS_BLOCK_GROUP_ITEM_KEY ) { -if (path->slots[0 ]) +while (key.type >BTRFS_EXTENT_ITEM_KEY ) { +if (path->slots[0 ] >0 ) { path->slots[0 ]--; -else -btrfs_prev_leaf (root, path); + }else { + ret =btrfs_prev_leaf (root, path); +if (ret <0 ) { + goto out; + }else if (ret >0 ) { + ret =0 ; + goto out; + } + } +btrfs_item_key_to_cpu (path->nodes[0 ], &key, path->slots[0 ]); }while (num_bytes) {
@@ -3752,7 +3767,8 @@ again: } ret =0 ; -if (num_bytes) { +out: +if (num_bytes && !ret) {fprintf (stderr,"There are no extents for csum range " "%Lu-%Lu\n" , bytenr, bytenr+num_bytes); ret =1 ;
Signature · 1 line
1.9.1