diff options
authorJosef Bacik <>2013-04-16 13:00:56 -0400
committerDavid Sterba <>2013-04-23 18:56:27 +0200
commit18ce0501ce8a6bc2d66b6bf11358d284919c5d3c (patch)
parent617769147f96bcd05aa9a5c8534b29d00fdd8b90 (diff)
Btrfs-progs: fix csum check when extent lands on block group
I was running fsync() tests and noticed that occasionally I was getting a bunch of errors from fsck complaining about csums not having corresponding extents. Thankfully after a few days of debugging this it turned out to be a bug with fsck. The csums were for an extent that started at the same offset as a block group, and were offset within the extent. So the search put us out at the block group item and we just walked forward from there, never finding the actual extent. This is because the block group item key is higher than the extent item key, so it comes first. In order to fix this we need to check and see if we landed on a block group item and take another step backwards to make sure we end up at the extent item. With this patch my reproducer no longer finds csums that don't have matching extent records. Thanks, Signed-off-by: Josef Bacik <>
1 files changed, 22 insertions, 2 deletions
diff --git a/cmds-check.c b/cmds-check.c
index 9db048c2..44b19d8d 100644
--- a/cmds-check.c
+++ b/cmds-check.c
@@ -2841,6 +2841,7 @@ static int check_extent_exists(struct btrfs_root *root, u64 bytenr,
key.offset = 0;
ret = btrfs_search_slot(NULL, root->fs_info->extent_root, &key, path,
0, 0);
@@ -2848,8 +2849,27 @@ again:
fprintf(stderr, "Error looking up extent record %d\n", ret);
return ret;
- } else if (ret && path->slots[0]) {
- path->slots[0]--;
+ } else if (ret) {
+ if (path->slots[0])
+ path->slots[0]--;
+ else
+ btrfs_prev_leaf(root, path);
+ }
+ btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
+ /*
+ * Block group items come before extent items if they have the same
+ * 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?
+ */
+ if (key.type == BTRFS_BLOCK_GROUP_ITEM_KEY) {
+ if (path->slots[0])
+ path->slots[0]--;
+ else
+ btrfs_prev_leaf(root, path);
while (num_bytes) {