Skip to content

Commit 924452c

Browse files
josefbacikkdave
authored andcommitted
btrfs: extend btrfs_leaf_check to return btrfs_tree_block_status
Instead of blanket returning -EUCLEAN for all the failures in btrfs_check_leaf, use btrfs_tree_block_status and return the appropriate status for each failure. Rename the helper to __btrfs_check_leaf and then make a wrapper of btrfs_check_leaf that will return -EUCLEAN to non-clean error codes. This will allow us to have the __btrfs_check_leaf variant in btrfs-progs while keeping the behavior in the kernel consistent. Signed-off-by: Josef Bacik <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent c8d5421 commit 924452c

File tree

2 files changed

+29
-13
lines changed

2 files changed

+29
-13
lines changed

fs/btrfs/tree-checker.c

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1678,7 +1678,7 @@ static enum btrfs_tree_block_status check_leaf_item(struct extent_buffer *leaf,
16781678
return BTRFS_TREE_BLOCK_CLEAN;
16791679
}
16801680

1681-
int btrfs_check_leaf(struct extent_buffer *leaf)
1681+
enum btrfs_tree_block_status __btrfs_check_leaf(struct extent_buffer *leaf)
16821682
{
16831683
struct btrfs_fs_info *fs_info = leaf->fs_info;
16841684
/* No valid key type is 0, so all key should be larger than this key */
@@ -1691,7 +1691,7 @@ int btrfs_check_leaf(struct extent_buffer *leaf)
16911691
generic_err(leaf, 0,
16921692
"invalid level for leaf, have %d expect 0",
16931693
btrfs_header_level(leaf));
1694-
return -EUCLEAN;
1694+
return BTRFS_TREE_BLOCK_INVALID_LEVEL;
16951695
}
16961696

16971697
/*
@@ -1714,32 +1714,32 @@ int btrfs_check_leaf(struct extent_buffer *leaf)
17141714
generic_err(leaf, 0,
17151715
"invalid root, root %llu must never be empty",
17161716
owner);
1717-
return -EUCLEAN;
1717+
return BTRFS_TREE_BLOCK_INVALID_NRITEMS;
17181718
}
17191719

17201720
/* Unknown tree */
17211721
if (unlikely(owner == 0)) {
17221722
generic_err(leaf, 0,
17231723
"invalid owner, root 0 is not defined");
1724-
return -EUCLEAN;
1724+
return BTRFS_TREE_BLOCK_INVALID_OWNER;
17251725
}
17261726

17271727
/* EXTENT_TREE_V2 can have empty extent trees. */
17281728
if (btrfs_fs_incompat(fs_info, EXTENT_TREE_V2))
1729-
return 0;
1729+
return BTRFS_TREE_BLOCK_CLEAN;
17301730

17311731
if (unlikely(owner == BTRFS_EXTENT_TREE_OBJECTID)) {
17321732
generic_err(leaf, 0,
17331733
"invalid root, root %llu must never be empty",
17341734
owner);
1735-
return -EUCLEAN;
1735+
return BTRFS_TREE_BLOCK_INVALID_NRITEMS;
17361736
}
17371737

1738-
return 0;
1738+
return BTRFS_TREE_BLOCK_CLEAN;
17391739
}
17401740

17411741
if (unlikely(nritems == 0))
1742-
return 0;
1742+
return BTRFS_TREE_BLOCK_CLEAN;
17431743

17441744
/*
17451745
* Check the following things to make sure this is a good leaf, and
@@ -1765,7 +1765,7 @@ int btrfs_check_leaf(struct extent_buffer *leaf)
17651765
prev_key.objectid, prev_key.type,
17661766
prev_key.offset, key.objectid, key.type,
17671767
key.offset);
1768-
return -EUCLEAN;
1768+
return BTRFS_TREE_BLOCK_BAD_KEY_ORDER;
17691769
}
17701770

17711771
item_data_end = (u64)btrfs_item_offset(leaf, slot) +
@@ -1784,7 +1784,7 @@ int btrfs_check_leaf(struct extent_buffer *leaf)
17841784
generic_err(leaf, slot,
17851785
"unexpected item end, have %llu expect %u",
17861786
item_data_end, item_end_expected);
1787-
return -EUCLEAN;
1787+
return BTRFS_TREE_BLOCK_INVALID_OFFSETS;
17881788
}
17891789

17901790
/*
@@ -1796,7 +1796,7 @@ int btrfs_check_leaf(struct extent_buffer *leaf)
17961796
generic_err(leaf, slot,
17971797
"slot end outside of leaf, have %llu expect range [0, %u]",
17981798
item_data_end, BTRFS_LEAF_DATA_SIZE(fs_info));
1799-
return -EUCLEAN;
1799+
return BTRFS_TREE_BLOCK_INVALID_OFFSETS;
18001800
}
18011801

18021802
/* Also check if the item pointer overlaps with btrfs item. */
@@ -1807,7 +1807,7 @@ int btrfs_check_leaf(struct extent_buffer *leaf)
18071807
btrfs_item_nr_offset(leaf, slot) +
18081808
sizeof(struct btrfs_item),
18091809
btrfs_item_ptr_offset(leaf, slot));
1810-
return -EUCLEAN;
1810+
return BTRFS_TREE_BLOCK_INVALID_OFFSETS;
18111811
}
18121812

18131813
/*
@@ -1823,14 +1823,24 @@ int btrfs_check_leaf(struct extent_buffer *leaf)
18231823
*/
18241824
ret = check_leaf_item(leaf, &key, slot, &prev_key);
18251825
if (unlikely(ret != BTRFS_TREE_BLOCK_CLEAN))
1826-
return -EUCLEAN;
1826+
return ret;
18271827
}
18281828

18291829
prev_key.objectid = key.objectid;
18301830
prev_key.type = key.type;
18311831
prev_key.offset = key.offset;
18321832
}
18331833

1834+
return BTRFS_TREE_BLOCK_CLEAN;
1835+
}
1836+
1837+
int btrfs_check_leaf(struct extent_buffer *leaf)
1838+
{
1839+
enum btrfs_tree_block_status ret;
1840+
1841+
ret = __btrfs_check_leaf(leaf);
1842+
if (unlikely(ret != BTRFS_TREE_BLOCK_CLEAN))
1843+
return -EUCLEAN;
18341844
return 0;
18351845
}
18361846
ALLOW_ERROR_INJECTION(btrfs_check_leaf, ERRNO);

fs/btrfs/tree-checker.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ enum btrfs_tree_block_status {
5353
BTRFS_TREE_BLOCK_INVALID_OWNER,
5454
};
5555

56+
/*
57+
* Exported simply for btrfs-progs which wants to have the
58+
* btrfs_tree_block_status return codes.
59+
*/
60+
enum btrfs_tree_block_status __btrfs_check_leaf(struct extent_buffer *leaf);
61+
5662
int btrfs_check_leaf(struct extent_buffer *leaf);
5763
int btrfs_check_node(struct extent_buffer *node);
5864

0 commit comments

Comments
 (0)