Skip to content

Commit cfda28f

Browse files
morbidrsakdave
authored andcommitted
btrfs: selftests: add test for punching a hole into 3 RAID stripe-extents
Test creating a range of three RAID stripe-extents and then punch a hole in the middle, deleting all of the middle extents and partially deleting the "book ends". Reviewed-by: Filipe Manana <[email protected]> Signed-off-by: Johannes Thumshirn <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 27ae15b commit cfda28f

File tree

1 file changed

+183
-0
lines changed

1 file changed

+183
-0
lines changed

fs/btrfs/tests/raid-stripe-tree-tests.c

+183
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,188 @@ static struct btrfs_device *btrfs_device_by_devid(struct btrfs_fs_devices *fs_de
3131
return NULL;
3232
}
3333

34+
/*
35+
* Test creating a range of three extents and then punch a hole in the middle,
36+
* deleting all of the middle extents and partially deleting the "book ends".
37+
*/
38+
static int test_punch_hole_3extents(struct btrfs_trans_handle *trans)
39+
{
40+
struct btrfs_fs_info *fs_info = trans->fs_info;
41+
struct btrfs_io_context *bioc;
42+
struct btrfs_io_stripe io_stripe = { 0 };
43+
u64 map_type = RST_TEST_RAID1_TYPE;
44+
u64 logical1 = SZ_1M;
45+
u64 len1 = SZ_1M;
46+
u64 logical2 = logical1 + len1;
47+
u64 len2 = SZ_1M;
48+
u64 logical3 = logical2 + len2;
49+
u64 len3 = SZ_1M;
50+
u64 hole_start = logical1 + SZ_256K;
51+
u64 hole_len = SZ_2M;
52+
int ret;
53+
54+
bioc = alloc_btrfs_io_context(fs_info, logical1, RST_TEST_NUM_DEVICES);
55+
if (!bioc) {
56+
test_std_err(TEST_ALLOC_IO_CONTEXT);
57+
ret = -ENOMEM;
58+
goto out;
59+
}
60+
61+
io_stripe.dev = btrfs_device_by_devid(fs_info->fs_devices, 0);
62+
63+
/* Prepare for the test, 1st create 3 x 1M extents. */
64+
bioc->map_type = map_type;
65+
bioc->size = len1;
66+
67+
for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
68+
struct btrfs_io_stripe *stripe = &bioc->stripes[i];
69+
70+
stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
71+
if (!stripe->dev) {
72+
test_err("cannot find device with devid %d", i);
73+
ret = -EINVAL;
74+
goto out;
75+
}
76+
77+
stripe->physical = logical1 + i * SZ_1G;
78+
}
79+
80+
ret = btrfs_insert_one_raid_extent(trans, bioc);
81+
if (ret) {
82+
test_err("inserting RAID extent failed: %d", ret);
83+
goto out;
84+
}
85+
86+
bioc->logical = logical2;
87+
bioc->size = len2;
88+
for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
89+
struct btrfs_io_stripe *stripe = &bioc->stripes[i];
90+
91+
stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
92+
if (!stripe->dev) {
93+
test_err("cannot find device with devid %d", i);
94+
ret = -EINVAL;
95+
goto out;
96+
}
97+
98+
stripe->physical = logical2 + i * SZ_1G;
99+
}
100+
101+
ret = btrfs_insert_one_raid_extent(trans, bioc);
102+
if (ret) {
103+
test_err("inserting RAID extent failed: %d", ret);
104+
goto out;
105+
}
106+
107+
bioc->logical = logical3;
108+
bioc->size = len3;
109+
for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
110+
struct btrfs_io_stripe *stripe = &bioc->stripes[i];
111+
112+
stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
113+
if (!stripe->dev) {
114+
test_err("cannot find device with devid %d", i);
115+
ret = -EINVAL;
116+
goto out;
117+
}
118+
119+
stripe->physical = logical3 + i * SZ_1G;
120+
}
121+
122+
ret = btrfs_insert_one_raid_extent(trans, bioc);
123+
if (ret) {
124+
test_err("inserting RAID extent failed: %d", ret);
125+
goto out;
126+
}
127+
128+
/*
129+
* Delete a range starting at logical1 + 256K and 2M in length. Extent
130+
* 1 is truncated to 256k length, extent 2 is completely dropped and
131+
* extent 3 is moved 256K to the right.
132+
*/
133+
ret = btrfs_delete_raid_extent(trans, hole_start, hole_len);
134+
if (ret) {
135+
test_err("deleting RAID extent [%llu, %llu] failed",
136+
hole_start, hole_start + hole_len);
137+
goto out;
138+
}
139+
140+
/* Get the first extent and check its size. */
141+
ret = btrfs_get_raid_extent_offset(fs_info, logical1, &len1, map_type,
142+
0, &io_stripe);
143+
if (ret) {
144+
test_err("lookup of RAID extent [%llu, %llu] failed",
145+
logical1, logical1 + len1);
146+
goto out;
147+
}
148+
149+
if (io_stripe.physical != logical1) {
150+
test_err("invalid physical address, expected %llu, got %llu",
151+
logical1, io_stripe.physical);
152+
ret = -EINVAL;
153+
goto out;
154+
}
155+
156+
if (len1 != SZ_256K) {
157+
test_err("invalid stripe length, expected %llu, got %llu",
158+
(u64)SZ_256K, len1);
159+
ret = -EINVAL;
160+
goto out;
161+
}
162+
163+
/* Get the second extent and check it's absent. */
164+
ret = btrfs_get_raid_extent_offset(fs_info, logical2, &len2, map_type,
165+
0, &io_stripe);
166+
if (ret != -ENODATA) {
167+
test_err("lookup of RAID extent [%llu, %llu] succeeded should fail",
168+
logical2, logical2 + len2);
169+
ret = -EINVAL;
170+
goto out;
171+
}
172+
173+
/* Get the third extent and check its size. */
174+
logical3 += SZ_256K;
175+
ret = btrfs_get_raid_extent_offset(fs_info, logical3, &len3, map_type,
176+
0, &io_stripe);
177+
if (ret) {
178+
test_err("lookup of RAID extent [%llu, %llu] failed",
179+
logical3, logical3 + len3);
180+
goto out;
181+
}
182+
183+
if (io_stripe.physical != logical3) {
184+
test_err("invalid physical address, expected %llu, got %llu",
185+
logical3 + SZ_256K, io_stripe.physical);
186+
ret = -EINVAL;
187+
goto out;
188+
}
189+
190+
if (len3 != SZ_1M - SZ_256K) {
191+
test_err("invalid stripe length, expected %llu, got %llu",
192+
(u64)SZ_1M - SZ_256K, len3);
193+
ret = -EINVAL;
194+
goto out;
195+
}
196+
197+
ret = btrfs_delete_raid_extent(trans, logical1, len1);
198+
if (ret) {
199+
test_err("deleting RAID extent [%llu, %llu] failed",
200+
logical1, logical1 + len1);
201+
goto out;
202+
}
203+
204+
ret = btrfs_delete_raid_extent(trans, logical3, len3);
205+
if (ret) {
206+
test_err("deleting RAID extent [%llu, %llu] failed",
207+
logical1, logical1 + len1);
208+
goto out;
209+
}
210+
211+
out:
212+
btrfs_put_bioc(bioc);
213+
return ret;
214+
}
215+
34216
/* Test punching a hole into a single RAID stripe-extent. */
35217
static int test_punch_hole(struct btrfs_trans_handle *trans)
36218
{
@@ -752,6 +934,7 @@ static const test_func_t tests[] = {
752934
test_front_delete,
753935
test_front_delete_prev_item,
754936
test_punch_hole,
937+
test_punch_hole_3extents,
755938
};
756939

757940
static int run_test(test_func_t test, u32 sectorsize, u32 nodesize)

0 commit comments

Comments
 (0)