@@ -213,6 +213,149 @@ static int test_punch_hole_3extents(struct btrfs_trans_handle *trans)
213
213
return ret ;
214
214
}
215
215
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
+
216
359
/* Test punching a hole into a single RAID stripe-extent. */
217
360
static int test_punch_hole (struct btrfs_trans_handle * trans )
218
361
{
@@ -935,6 +1078,7 @@ static const test_func_t tests[] = {
935
1078
test_front_delete_prev_item ,
936
1079
test_punch_hole ,
937
1080
test_punch_hole_3extents ,
1081
+ test_delete_two_extents ,
938
1082
};
939
1083
940
1084
static int run_test (test_func_t test , u32 sectorsize , u32 nodesize )
0 commit comments