Message ID | 20230918-rst-updates-v1-4-17686dc06859@wdc.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | btrfs: RAID stripe tree updates | expand |
On 2023/9/18 23:44, Johannes Thumshirn wrote: > Add a tree checker for RAID stripe tree items. > > Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> > --- > fs/btrfs/tree-checker.c | 42 ++++++++++++++++++++++++++++++++++++++++++ > 1 file changed, 42 insertions(+) > > diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c > index 01bba79165e7..ea84ca2767e9 100644 > --- a/fs/btrfs/tree-checker.c > +++ b/fs/btrfs/tree-checker.c > @@ -30,6 +30,7 @@ > #include "file-item.h" > #include "inode-item.h" > #include "dir-item.h" > +#include "raid-stripe-tree.h" > > /* > * Error message should follow the following format: > @@ -1635,6 +1636,44 @@ static int check_inode_ref(struct extent_buffer *leaf, > return 0; > } > > +static int check_raid_stripe_extent(struct extent_buffer *leaf, > + struct btrfs_key *key, int slot) > +{ > + struct btrfs_stripe_extent *stripe_extent = > + btrfs_item_ptr(leaf, slot, struct btrfs_stripe_extent); > + > + if (unlikely(!IS_ALIGNED(key->objectid, leaf->fs_info->sectorsize))) { > + generic_err(leaf, slot, > +"invalid key objectid for raid stripe extent, have %llu expect aligned to %u", > + key->objectid, leaf->fs_info->sectorsize); > + return -EUCLEAN; > + } > + > + if (unlikely(!btrfs_fs_incompat(leaf->fs_info, RAID_STRIPE_TREE))) { > + generic_err(leaf, slot, > + "RAID_STRIPE_EXTENT present but RAID_STRIPE_TREE incompat bit unset"); > + return -EUCLEAN; > + } > + > + switch (btrfs_stripe_extent_encoding(leaf, stripe_extent)) { > + case BTRFS_STRIPE_RAID0: > + case BTRFS_STRIPE_RAID1: > + case BTRFS_STRIPE_DUP: > + case BTRFS_STRIPE_RAID10: > + case BTRFS_STRIPE_RAID5: > + case BTRFS_STRIPE_RAID6: > + case BTRFS_STRIPE_RAID1C3: > + case BTRFS_STRIPE_RAID1C4: > + break; > + default: > + generic_err(leaf, slot, "invalid raid stripe encoding %u", > + btrfs_stripe_extent_encoding(leaf, stripe_extent)); > + return -EUCLEAN; > + } Another thing we can check is the item size, the item size should be aligned to a single record, or we can get garbage reading the last record. Thanks, Qu > + > + return 0; > +} > + > /* > * Common point to switch the item-specific validation. > */ > @@ -1689,6 +1728,9 @@ static enum btrfs_tree_block_status check_leaf_item(struct extent_buffer *leaf, > case BTRFS_EXTENT_DATA_REF_KEY: > ret = check_extent_data_ref(leaf, key, slot); > break; > + case BTRFS_RAID_STRIPE_KEY: > + ret = check_raid_stripe_extent(leaf, key, slot); > + break; > } > > if (ret) >
diff --git a/fs/btrfs/tree-checker.c b/fs/btrfs/tree-checker.c index 01bba79165e7..ea84ca2767e9 100644 --- a/fs/btrfs/tree-checker.c +++ b/fs/btrfs/tree-checker.c @@ -30,6 +30,7 @@ #include "file-item.h" #include "inode-item.h" #include "dir-item.h" +#include "raid-stripe-tree.h" /* * Error message should follow the following format: @@ -1635,6 +1636,44 @@ static int check_inode_ref(struct extent_buffer *leaf, return 0; } +static int check_raid_stripe_extent(struct extent_buffer *leaf, + struct btrfs_key *key, int slot) +{ + struct btrfs_stripe_extent *stripe_extent = + btrfs_item_ptr(leaf, slot, struct btrfs_stripe_extent); + + if (unlikely(!IS_ALIGNED(key->objectid, leaf->fs_info->sectorsize))) { + generic_err(leaf, slot, +"invalid key objectid for raid stripe extent, have %llu expect aligned to %u", + key->objectid, leaf->fs_info->sectorsize); + return -EUCLEAN; + } + + if (unlikely(!btrfs_fs_incompat(leaf->fs_info, RAID_STRIPE_TREE))) { + generic_err(leaf, slot, + "RAID_STRIPE_EXTENT present but RAID_STRIPE_TREE incompat bit unset"); + return -EUCLEAN; + } + + switch (btrfs_stripe_extent_encoding(leaf, stripe_extent)) { + case BTRFS_STRIPE_RAID0: + case BTRFS_STRIPE_RAID1: + case BTRFS_STRIPE_DUP: + case BTRFS_STRIPE_RAID10: + case BTRFS_STRIPE_RAID5: + case BTRFS_STRIPE_RAID6: + case BTRFS_STRIPE_RAID1C3: + case BTRFS_STRIPE_RAID1C4: + break; + default: + generic_err(leaf, slot, "invalid raid stripe encoding %u", + btrfs_stripe_extent_encoding(leaf, stripe_extent)); + return -EUCLEAN; + } + + return 0; +} + /* * Common point to switch the item-specific validation. */ @@ -1689,6 +1728,9 @@ static enum btrfs_tree_block_status check_leaf_item(struct extent_buffer *leaf, case BTRFS_EXTENT_DATA_REF_KEY: ret = check_extent_data_ref(leaf, key, slot); break; + case BTRFS_RAID_STRIPE_KEY: + ret = check_raid_stripe_extent(leaf, key, slot); + break; } if (ret)
Add a tree checker for RAID stripe tree items. Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com> --- fs/btrfs/tree-checker.c | 42 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+)