Message ID | cc5a97b95855d170aecb76ae358c6dfc08e47559.1692305624.git.josef@toxicpanda.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | Fix incorrect splitting logic in btrfs_drop_extent_map_range | expand |
On Thu, Aug 17, 2023 at 04:57:32PM -0400, Josef Bacik wrote: > This helper is different from the normal add_extent_mapping in that it > will stuff an em into a gap that exists between overlapping em's in the > tree. It appeared there was a bug so I wrote a self test to validate it > did the correct thing when it worked with two side by side ems. > Thankfully it is correct, but more testing is better. > > Signed-off-by: Josef Bacik <josef@toxicpanda.com> Reviewed-by: Filipe Manana <fdmanana@suse.com> Looks good, thanks. > --- > fs/btrfs/tests/extent-map-tests.c | 57 +++++++++++++++++++++++++++++++ > 1 file changed, 57 insertions(+) > > diff --git a/fs/btrfs/tests/extent-map-tests.c b/fs/btrfs/tests/extent-map-tests.c > index d5f5e48ab55c..18ab03f0d029 100644 > --- a/fs/btrfs/tests/extent-map-tests.c > +++ b/fs/btrfs/tests/extent-map-tests.c > @@ -656,6 +656,60 @@ static int test_case_5(void) > return ret; > } > > +/* > + * Test the btrfs_add_extent_mapping helper which will attempt to create an em > + * for areas between two existing ems. Validate it doesn't do this when there > + * are two unmerged em's side by side. > + */ > +static int test_case_6(struct btrfs_fs_info *fs_info, > + struct extent_map_tree *em_tree) > +{ > + struct extent_map *em = NULL; > + int ret; > + > + ret = add_compressed_extent(em_tree, 0, SZ_4K, 0); > + if (ret) > + goto out; > + > + ret = add_compressed_extent(em_tree, SZ_4K, SZ_4K, 0); > + if (ret) > + goto out; > + > + em = alloc_extent_map(); > + if (!em) { > + test_std_err(TEST_ALLOC_EXTENT_MAP); > + return -ENOMEM; > + } > + > + em->start = SZ_4K; > + em->len = SZ_4K; > + em->block_start = SZ_16K; > + em->block_len = SZ_16K; > + write_lock(&em_tree->lock); > + ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, 0, SZ_8K); > + write_unlock(&em_tree->lock); > + > + if (ret != 0) { > + test_err("got an error when adding our em: %d", ret); > + goto out; > + } > + > + ret = -EINVAL; > + if (em->start != 0) { > + test_err("unexpected em->start at %llu, wanted 0", em->start); > + goto out; > + } > + if (em->len != SZ_4K) { > + test_err("unexpected em->len %llu, expected 4K", em->len); > + goto out; > + } > + ret = 0; > +out: > + free_extent_map(em); > + free_extent_map_tree(em_tree); > + return ret; > +} > + > struct rmap_test_vector { > u64 raid_type; > u64 physical_start; > @@ -836,6 +890,9 @@ int btrfs_test_extent_map(void) > if (ret) > goto out; > ret = test_case_5(); > + if (ret) > + goto out; > + ret = test_case_6(fs_info, em_tree); > if (ret) > goto out; > > -- > 2.26.3 >
diff --git a/fs/btrfs/tests/extent-map-tests.c b/fs/btrfs/tests/extent-map-tests.c index d5f5e48ab55c..18ab03f0d029 100644 --- a/fs/btrfs/tests/extent-map-tests.c +++ b/fs/btrfs/tests/extent-map-tests.c @@ -656,6 +656,60 @@ static int test_case_5(void) return ret; } +/* + * Test the btrfs_add_extent_mapping helper which will attempt to create an em + * for areas between two existing ems. Validate it doesn't do this when there + * are two unmerged em's side by side. + */ +static int test_case_6(struct btrfs_fs_info *fs_info, + struct extent_map_tree *em_tree) +{ + struct extent_map *em = NULL; + int ret; + + ret = add_compressed_extent(em_tree, 0, SZ_4K, 0); + if (ret) + goto out; + + ret = add_compressed_extent(em_tree, SZ_4K, SZ_4K, 0); + if (ret) + goto out; + + em = alloc_extent_map(); + if (!em) { + test_std_err(TEST_ALLOC_EXTENT_MAP); + return -ENOMEM; + } + + em->start = SZ_4K; + em->len = SZ_4K; + em->block_start = SZ_16K; + em->block_len = SZ_16K; + write_lock(&em_tree->lock); + ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, 0, SZ_8K); + write_unlock(&em_tree->lock); + + if (ret != 0) { + test_err("got an error when adding our em: %d", ret); + goto out; + } + + ret = -EINVAL; + if (em->start != 0) { + test_err("unexpected em->start at %llu, wanted 0", em->start); + goto out; + } + if (em->len != SZ_4K) { + test_err("unexpected em->len %llu, expected 4K", em->len); + goto out; + } + ret = 0; +out: + free_extent_map(em); + free_extent_map_tree(em_tree); + return ret; +} + struct rmap_test_vector { u64 raid_type; u64 physical_start; @@ -836,6 +890,9 @@ int btrfs_test_extent_map(void) if (ret) goto out; ret = test_case_5(); + if (ret) + goto out; + ret = test_case_6(fs_info, em_tree); if (ret) goto out;
This helper is different from the normal add_extent_mapping in that it will stuff an em into a gap that exists between overlapping em's in the tree. It appeared there was a bug so I wrote a self test to validate it did the correct thing when it worked with two side by side ems. Thankfully it is correct, but more testing is better. Signed-off-by: Josef Bacik <josef@toxicpanda.com> --- fs/btrfs/tests/extent-map-tests.c | 57 +++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+)