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. Signed-off-by: Filipe David Borba Manana <fdmanana@gmail.com> Signed-off-by: David Sterba <dsterba@suse.cz>
This commit is contained in:
parent
8909f11042
commit
6c9caa4dd6
38
cmds-check.c
38
cmds-check.c
|
@ -3792,8 +3792,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,
|
||||
|
@ -3803,10 +3802,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]);
|
||||
|
@ -3816,13 +3822,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) {
|
||||
|
@ -3894,7 +3909,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;
|
||||
|
|
Loading…
Reference in New Issue