@@ -213,6 +213,149 @@ static int test_punch_hole_3extents(struct btrfs_trans_handle *trans)
213213 return ret ;
214214}
215215
216+ static int test_delete_two_extents (struct btrfs_trans_handle * trans )
217+ {
218+ struct btrfs_fs_info * fs_info = trans -> fs_info ;
219+ struct btrfs_io_context * bioc ;
220+ struct btrfs_io_stripe io_stripe = { 0 };
221+ u64 map_type = RST_TEST_RAID1_TYPE ;
222+ u64 logical1 = SZ_1M ;
223+ u64 len1 = SZ_1M ;
224+ u64 logical2 = logical1 + len1 ;
225+ u64 len2 = SZ_1M ;
226+ u64 logical3 = logical2 + len2 ;
227+ u64 len3 = SZ_1M ;
228+ int ret ;
229+
230+ bioc = alloc_btrfs_io_context (fs_info , logical1 , RST_TEST_NUM_DEVICES );
231+ if (!bioc ) {
232+ test_std_err (TEST_ALLOC_IO_CONTEXT );
233+ ret = - ENOMEM ;
234+ goto out ;
235+ }
236+
237+ io_stripe .dev = btrfs_device_by_devid (fs_info -> fs_devices , 0 );
238+
239+ /* Prepare for the test, 1st create 3 x 1M extents. */
240+ bioc -> map_type = map_type ;
241+ bioc -> size = len1 ;
242+
243+ for (int i = 0 ; i < RST_TEST_NUM_DEVICES ; i ++ ) {
244+ struct btrfs_io_stripe * stripe = & bioc -> stripes [i ];
245+
246+ stripe -> dev = btrfs_device_by_devid (fs_info -> fs_devices , i );
247+ if (!stripe -> dev ) {
248+ test_err ("cannot find device with devid %d" , i );
249+ ret = - EINVAL ;
250+ goto out ;
251+ }
252+
253+ stripe -> physical = logical1 + i * SZ_1G ;
254+ }
255+
256+ ret = btrfs_insert_one_raid_extent (trans , bioc );
257+ if (ret ) {
258+ test_err ("inserting RAID extent failed: %d" , ret );
259+ goto out ;
260+ }
261+
262+ bioc -> logical = logical2 ;
263+ bioc -> size = len2 ;
264+ for (int i = 0 ; i < RST_TEST_NUM_DEVICES ; i ++ ) {
265+ struct btrfs_io_stripe * stripe = & bioc -> stripes [i ];
266+
267+ stripe -> dev = btrfs_device_by_devid (fs_info -> fs_devices , i );
268+ if (!stripe -> dev ) {
269+ test_err ("cannot find device with devid %d" , i );
270+ ret = - EINVAL ;
271+ goto out ;
272+ }
273+
274+ stripe -> physical = logical2 + i * SZ_1G ;
275+ }
276+
277+ ret = btrfs_insert_one_raid_extent (trans , bioc );
278+ if (ret ) {
279+ test_err ("inserting RAID extent failed: %d" , ret );
280+ goto out ;
281+ }
282+
283+ bioc -> logical = logical3 ;
284+ bioc -> size = len3 ;
285+ for (int i = 0 ; i < RST_TEST_NUM_DEVICES ; i ++ ) {
286+ struct btrfs_io_stripe * stripe = & bioc -> stripes [i ];
287+
288+ stripe -> dev = btrfs_device_by_devid (fs_info -> fs_devices , i );
289+ if (!stripe -> dev ) {
290+ test_err ("cannot find device with devid %d" , i );
291+ ret = - EINVAL ;
292+ goto out ;
293+ }
294+
295+ stripe -> physical = logical3 + i * SZ_1G ;
296+ }
297+
298+ ret = btrfs_insert_one_raid_extent (trans , bioc );
299+ if (ret ) {
300+ test_err ("inserting RAID extent failed: %d" , ret );
301+ goto out ;
302+ }
303+
304+ /*
305+ * Delete a range starting at logical1 and 2M in length. Extents 1
306+ * and 2 are dropped and extent 3 is kept as is.
307+ */
308+ ret = btrfs_delete_raid_extent (trans , logical1 , len1 + len2 );
309+ if (ret ) {
310+ test_err ("deleting RAID extent [%llu, %llu] failed" ,
311+ logical1 , logical1 + len1 + len2 );
312+ goto out ;
313+ }
314+
315+ ret = btrfs_get_raid_extent_offset (fs_info , logical1 , & len1 , map_type ,
316+ 0 , & io_stripe );
317+ if (ret != - ENODATA ) {
318+ test_err ("lookup of RAID extent [%llu, %llu] succeeded, should fail" ,
319+ logical1 , len1 );
320+ goto out ;
321+ }
322+
323+ ret = btrfs_get_raid_extent_offset (fs_info , logical2 , & len2 , map_type ,
324+ 0 , & io_stripe );
325+ if (ret != - ENODATA ) {
326+ test_err ("lookup of RAID extent [%llu, %llu] succeeded, should fail" ,
327+ logical2 , len2 );
328+ goto out ;
329+ }
330+
331+ ret = btrfs_get_raid_extent_offset (fs_info , logical3 , & len3 , map_type ,
332+ 0 , & io_stripe );
333+ if (ret ) {
334+ test_err ("lookup of RAID extent [%llu, %llu] failed" ,
335+ logical3 , len3 );
336+ goto out ;
337+ }
338+
339+ if (io_stripe .physical != logical3 ) {
340+ test_err ("invalid physical address, expected %llu, got %llu" ,
341+ logical3 , io_stripe .physical );
342+ ret = - EINVAL ;
343+ goto out ;
344+ }
345+
346+ if (len3 != SZ_1M ) {
347+ test_err ("invalid stripe length, expected %llu, got %llu" ,
348+ (u64 )SZ_1M , len3 );
349+ ret = - EINVAL ;
350+ goto out ;
351+ }
352+
353+ ret = btrfs_delete_raid_extent (trans , logical3 , len3 );
354+ out :
355+ btrfs_put_bioc (bioc );
356+ return ret ;
357+ }
358+
216359/* Test punching a hole into a single RAID stripe-extent. */
217360static int test_punch_hole (struct btrfs_trans_handle * trans )
218361{
@@ -935,6 +1078,7 @@ static const test_func_t tests[] = {
9351078 test_front_delete_prev_item ,
9361079 test_punch_hole ,
9371080 test_punch_hole_3extents ,
1081+ test_delete_two_extents ,
9381082};
9391083
9401084static int run_test (test_func_t test , u32 sectorsize , u32 nodesize )
0 commit comments