Skip to content

Commit 27ae15b

Browse files
morbidrsakdave
authored andcommitted
btrfs: selftests: add selftest for punching holes into the RAID stripe extents
Add a selftest for punching a hole into a RAID stripe extent. The test create an 1M extent and punches a 64k bytes long hole at offset of 32k from the start of the extent. Afterwards it verifies the start and length of both resulting new extents "left" and "right" as well as the absence of the hole. Reviewed-by: Filipe Manana <[email protected]> Signed-off-by: Johannes Thumshirn <[email protected]> Signed-off-by: David Sterba <[email protected]>
1 parent 1d395c3 commit 27ae15b

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed

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

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

34+
/* Test punching a hole into a single RAID stripe-extent. */
35+
static int test_punch_hole(struct btrfs_trans_handle *trans)
36+
{
37+
struct btrfs_fs_info *fs_info = trans->fs_info;
38+
struct btrfs_io_context *bioc;
39+
struct btrfs_io_stripe io_stripe = { 0 };
40+
u64 map_type = RST_TEST_RAID1_TYPE;
41+
u64 logical1 = SZ_1M;
42+
u64 hole_start = logical1 + SZ_32K;
43+
u64 hole_len = SZ_64K;
44+
u64 logical2 = hole_start + hole_len;
45+
u64 len = SZ_1M;
46+
u64 len1 = SZ_32K;
47+
u64 len2 = len - len1 - hole_len;
48+
int ret;
49+
50+
bioc = alloc_btrfs_io_context(fs_info, logical1, RST_TEST_NUM_DEVICES);
51+
if (!bioc) {
52+
test_std_err(TEST_ALLOC_IO_CONTEXT);
53+
ret = -ENOMEM;
54+
goto out;
55+
}
56+
57+
io_stripe.dev = btrfs_device_by_devid(fs_info->fs_devices, 0);
58+
bioc->map_type = map_type;
59+
bioc->size = len;
60+
61+
for (int i = 0; i < RST_TEST_NUM_DEVICES; i++) {
62+
struct btrfs_io_stripe *stripe = &bioc->stripes[i];
63+
64+
stripe->dev = btrfs_device_by_devid(fs_info->fs_devices, i);
65+
if (!stripe->dev) {
66+
test_err("cannot find device with devid %d", i);
67+
ret = -EINVAL;
68+
goto out;
69+
}
70+
71+
stripe->physical = logical1 + i * SZ_1G;
72+
}
73+
74+
ret = btrfs_insert_one_raid_extent(trans, bioc);
75+
if (ret) {
76+
test_err("inserting RAID extent failed: %d", ret);
77+
goto out;
78+
}
79+
80+
ret = btrfs_get_raid_extent_offset(fs_info, logical1, &len, map_type, 0,
81+
&io_stripe);
82+
if (ret) {
83+
test_err("lookup of RAID extent [%llu, %llu] failed", logical1,
84+
logical1 + len);
85+
goto out;
86+
}
87+
88+
if (io_stripe.physical != logical1) {
89+
test_err("invalid physical address, expected %llu got %llu",
90+
logical1, io_stripe.physical);
91+
ret = -EINVAL;
92+
goto out;
93+
}
94+
95+
if (len != SZ_1M) {
96+
test_err("invalid stripe length, expected %llu got %llu",
97+
(u64)SZ_1M, len);
98+
ret = -EINVAL;
99+
goto out;
100+
}
101+
102+
ret = btrfs_delete_raid_extent(trans, hole_start, hole_len);
103+
if (ret) {
104+
test_err("deleting RAID extent [%llu, %llu] failed",
105+
hole_start, hole_start + hole_len);
106+
goto out;
107+
}
108+
109+
ret = btrfs_get_raid_extent_offset(fs_info, logical1, &len1, map_type,
110+
0, &io_stripe);
111+
if (ret) {
112+
test_err("lookup of RAID extent [%llu, %llu] failed",
113+
logical1, logical1 + len1);
114+
goto out;
115+
}
116+
117+
if (io_stripe.physical != logical1) {
118+
test_err("invalid physical address, expected %llu, got %llu",
119+
logical1, io_stripe.physical);
120+
ret = -EINVAL;
121+
goto out;
122+
}
123+
124+
if (len1 != SZ_32K) {
125+
test_err("invalid stripe length, expected %llu, got %llu",
126+
(u64)SZ_32K, len1);
127+
ret = -EINVAL;
128+
goto out;
129+
}
130+
131+
ret = btrfs_get_raid_extent_offset(fs_info, logical2, &len2, map_type,
132+
0, &io_stripe);
133+
if (ret) {
134+
test_err("lookup of RAID extent [%llu, %llu] failed", logical2,
135+
logical2 + len2);
136+
goto out;
137+
}
138+
139+
if (io_stripe.physical != logical2) {
140+
test_err("invalid physical address, expected %llu, got %llu",
141+
logical2, io_stripe.physical);
142+
ret = -EINVAL;
143+
goto out;
144+
}
145+
146+
if (len2 != len - len1 - hole_len) {
147+
test_err("invalid length, expected %llu, got %llu",
148+
len - len1 - hole_len, len2);
149+
ret = -EINVAL;
150+
goto out;
151+
}
152+
153+
/* Check for the absence of the hole. */
154+
ret = btrfs_get_raid_extent_offset(fs_info, hole_start, &hole_len,
155+
map_type, 0, &io_stripe);
156+
if (ret != -ENODATA) {
157+
ret = -EINVAL;
158+
test_err("lookup of RAID extent [%llu, %llu] succeeded, should fail",
159+
hole_start, hole_start + SZ_64K);
160+
goto out;
161+
}
162+
163+
ret = btrfs_delete_raid_extent(trans, logical1, len1);
164+
if (ret)
165+
goto out;
166+
167+
ret = btrfs_delete_raid_extent(trans, logical2, len2);
168+
out:
169+
btrfs_put_bioc(bioc);
170+
return ret;
171+
}
172+
34173
/*
35174
* Test a 1M RST write that spans two adjacent RST items on disk and then
36175
* delete a portion starting in the first item and spanning into the second
@@ -612,6 +751,7 @@ static const test_func_t tests[] = {
612751
test_tail_delete,
613752
test_front_delete,
614753
test_front_delete_prev_item,
754+
test_punch_hole,
615755
};
616756

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

0 commit comments

Comments
 (0)