@@ -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
617757static int run_test (test_func_t test , u32 sectorsize , u32 nodesize )
0 commit comments