hc
2024-09-20 a36159eec6ca17402b0e146b86efaf76568dc353
kernel/fs/btrfs/tests/extent-io-tests.c
....@@ -10,6 +10,7 @@
1010 #include "btrfs-tests.h"
1111 #include "../ctree.h"
1212 #include "../extent_io.h"
13
+#include "../btrfs_inode.h"
1314
1415 #define PROCESS_UNLOCK (1 << 0)
1516 #define PROCESS_RELEASE (1 << 1)
....@@ -58,25 +59,31 @@
5859 static int test_find_delalloc(u32 sectorsize)
5960 {
6061 struct inode *inode;
61
- struct extent_io_tree tmp;
62
+ struct extent_io_tree *tmp;
6263 struct page *page;
6364 struct page *locked_page = NULL;
6465 unsigned long index = 0;
65
- u64 total_dirty = SZ_256M;
66
- u64 max_bytes = SZ_128M;
66
+ /* In this test we need at least 2 file extents at its maximum size */
67
+ u64 max_bytes = BTRFS_MAX_EXTENT_SIZE;
68
+ u64 total_dirty = 2 * max_bytes;
6769 u64 start, end, test_start;
68
- u64 found;
70
+ bool found;
6971 int ret = -EINVAL;
7072
7173 test_msg("running find delalloc tests");
7274
7375 inode = btrfs_new_test_inode();
7476 if (!inode) {
75
- test_err("failed to allocate test inode");
77
+ test_std_err(TEST_ALLOC_INODE);
7678 return -ENOMEM;
7779 }
80
+ tmp = &BTRFS_I(inode)->io_tree;
7881
79
- extent_io_tree_init(&tmp, inode);
82
+ /*
83
+ * Passing NULL as we don't have fs_info but tracepoints are not used
84
+ * at this point
85
+ */
86
+ extent_io_tree_init(NULL, tmp, IO_TREE_SELFTEST, NULL);
8087
8188 /*
8289 * First go through and create and mark all of our pages dirty, we pin
....@@ -103,11 +110,11 @@
103110 * |--- delalloc ---|
104111 * |--- search ---|
105112 */
106
- set_extent_delalloc(&tmp, 0, sectorsize - 1, 0, NULL);
113
+ set_extent_delalloc(tmp, 0, sectorsize - 1, 0, NULL);
107114 start = 0;
108115 end = 0;
109
- found = find_lock_delalloc_range(inode, &tmp, locked_page, &start,
110
- &end, max_bytes);
116
+ found = find_lock_delalloc_range(inode, locked_page, &start,
117
+ &end);
111118 if (!found) {
112119 test_err("should have found at least one delalloc");
113120 goto out_bits;
....@@ -117,7 +124,7 @@
117124 sectorsize - 1, start, end);
118125 goto out_bits;
119126 }
120
- unlock_extent(&tmp, start, end);
127
+ unlock_extent(tmp, start, end);
121128 unlock_page(locked_page);
122129 put_page(locked_page);
123130
....@@ -134,11 +141,11 @@
134141 test_err("couldn't find the locked page");
135142 goto out_bits;
136143 }
137
- set_extent_delalloc(&tmp, sectorsize, max_bytes - 1, 0, NULL);
144
+ set_extent_delalloc(tmp, sectorsize, max_bytes - 1, 0, NULL);
138145 start = test_start;
139146 end = 0;
140
- found = find_lock_delalloc_range(inode, &tmp, locked_page, &start,
141
- &end, max_bytes);
147
+ found = find_lock_delalloc_range(inode, locked_page, &start,
148
+ &end);
142149 if (!found) {
143150 test_err("couldn't find delalloc in our range");
144151 goto out_bits;
....@@ -153,7 +160,7 @@
153160 test_err("there were unlocked pages in the range");
154161 goto out_bits;
155162 }
156
- unlock_extent(&tmp, start, end);
163
+ unlock_extent(tmp, start, end);
157164 /* locked_page was unlocked above */
158165 put_page(locked_page);
159166
....@@ -171,8 +178,8 @@
171178 }
172179 start = test_start;
173180 end = 0;
174
- found = find_lock_delalloc_range(inode, &tmp, locked_page, &start,
175
- &end, max_bytes);
181
+ found = find_lock_delalloc_range(inode, locked_page, &start,
182
+ &end);
176183 if (found) {
177184 test_err("found range when we shouldn't have");
178185 goto out_bits;
....@@ -189,11 +196,11 @@
189196 *
190197 * We are re-using our test_start from above since it works out well.
191198 */
192
- set_extent_delalloc(&tmp, max_bytes, total_dirty - 1, 0, NULL);
199
+ set_extent_delalloc(tmp, max_bytes, total_dirty - 1, 0, NULL);
193200 start = test_start;
194201 end = 0;
195
- found = find_lock_delalloc_range(inode, &tmp, locked_page, &start,
196
- &end, max_bytes);
202
+ found = find_lock_delalloc_range(inode, locked_page, &start,
203
+ &end);
197204 if (!found) {
198205 test_err("didn't find our range");
199206 goto out_bits;
....@@ -208,7 +215,7 @@
208215 test_err("pages in range were not all locked");
209216 goto out_bits;
210217 }
211
- unlock_extent(&tmp, start, end);
218
+ unlock_extent(tmp, start, end);
212219
213220 /*
214221 * Now to test where we run into a page that is no longer dirty in the
....@@ -233,8 +240,8 @@
233240 * this changes at any point in the future we will need to fix this
234241 * tests expected behavior.
235242 */
236
- found = find_lock_delalloc_range(inode, &tmp, locked_page, &start,
237
- &end, max_bytes);
243
+ found = find_lock_delalloc_range(inode, locked_page, &start,
244
+ &end);
238245 if (!found) {
239246 test_err("didn't find our range");
240247 goto out_bits;
....@@ -251,7 +258,7 @@
251258 }
252259 ret = 0;
253260 out_bits:
254
- clear_extent_bits(&tmp, 0, total_dirty - 1, (unsigned)-1);
261
+ clear_extent_bits(tmp, 0, total_dirty - 1, (unsigned)-1);
255262 out:
256263 if (locked_page)
257264 put_page(locked_page);
....@@ -373,8 +380,8 @@
373380 {
374381 struct btrfs_fs_info *fs_info;
375382 unsigned long len;
376
- unsigned long *bitmap;
377
- struct extent_buffer *eb;
383
+ unsigned long *bitmap = NULL;
384
+ struct extent_buffer *eb = NULL;
378385 int ret;
379386
380387 test_msg("running extent buffer bitmap tests");
....@@ -387,18 +394,23 @@
387394 ? sectorsize * 4 : sectorsize;
388395
389396 fs_info = btrfs_alloc_dummy_fs_info(len, len);
397
+ if (!fs_info) {
398
+ test_std_err(TEST_ALLOC_FS_INFO);
399
+ return -ENOMEM;
400
+ }
390401
391402 bitmap = kmalloc(len, GFP_KERNEL);
392403 if (!bitmap) {
393404 test_err("couldn't allocate test bitmap");
394
- return -ENOMEM;
405
+ ret = -ENOMEM;
406
+ goto out;
395407 }
396408
397409 eb = __alloc_dummy_extent_buffer(fs_info, 0, len);
398410 if (!eb) {
399
- test_err("couldn't allocate test extent buffer");
400
- kfree(bitmap);
401
- return -ENOMEM;
411
+ test_std_err(TEST_ALLOC_ROOT);
412
+ ret = -ENOMEM;
413
+ goto out;
402414 }
403415
404416 ret = __test_eb_bitmaps(bitmap, eb, len);
....@@ -407,17 +419,127 @@
407419
408420 /* Do it over again with an extent buffer which isn't page-aligned. */
409421 free_extent_buffer(eb);
410
- eb = __alloc_dummy_extent_buffer(NULL, nodesize / 2, len);
422
+ eb = __alloc_dummy_extent_buffer(fs_info, nodesize / 2, len);
411423 if (!eb) {
412
- test_err("couldn't allocate test extent buffer");
413
- kfree(bitmap);
414
- return -ENOMEM;
424
+ test_std_err(TEST_ALLOC_ROOT);
425
+ ret = -ENOMEM;
426
+ goto out;
415427 }
416428
417429 ret = __test_eb_bitmaps(bitmap, eb, len);
418430 out:
419431 free_extent_buffer(eb);
420432 kfree(bitmap);
433
+ btrfs_free_dummy_fs_info(fs_info);
434
+ return ret;
435
+}
436
+
437
+static int test_find_first_clear_extent_bit(void)
438
+{
439
+ struct extent_io_tree tree;
440
+ u64 start, end;
441
+ int ret = -EINVAL;
442
+
443
+ test_msg("running find_first_clear_extent_bit test");
444
+
445
+ extent_io_tree_init(NULL, &tree, IO_TREE_SELFTEST, NULL);
446
+
447
+ /* Test correct handling of empty tree */
448
+ find_first_clear_extent_bit(&tree, 0, &start, &end, CHUNK_TRIMMED);
449
+ if (start != 0 || end != -1) {
450
+ test_err(
451
+ "error getting a range from completely empty tree: start %llu end %llu",
452
+ start, end);
453
+ goto out;
454
+ }
455
+ /*
456
+ * Set 1M-4M alloc/discard and 32M-64M thus leaving a hole between
457
+ * 4M-32M
458
+ */
459
+ set_extent_bits(&tree, SZ_1M, SZ_4M - 1,
460
+ CHUNK_TRIMMED | CHUNK_ALLOCATED);
461
+
462
+ find_first_clear_extent_bit(&tree, SZ_512K, &start, &end,
463
+ CHUNK_TRIMMED | CHUNK_ALLOCATED);
464
+
465
+ if (start != 0 || end != SZ_1M - 1) {
466
+ test_err("error finding beginning range: start %llu end %llu",
467
+ start, end);
468
+ goto out;
469
+ }
470
+
471
+ /* Now add 32M-64M so that we have a hole between 4M-32M */
472
+ set_extent_bits(&tree, SZ_32M, SZ_64M - 1,
473
+ CHUNK_TRIMMED | CHUNK_ALLOCATED);
474
+
475
+ /*
476
+ * Request first hole starting at 12M, we should get 4M-32M
477
+ */
478
+ find_first_clear_extent_bit(&tree, 12 * SZ_1M, &start, &end,
479
+ CHUNK_TRIMMED | CHUNK_ALLOCATED);
480
+
481
+ if (start != SZ_4M || end != SZ_32M - 1) {
482
+ test_err("error finding trimmed range: start %llu end %llu",
483
+ start, end);
484
+ goto out;
485
+ }
486
+
487
+ /*
488
+ * Search in the middle of allocated range, should get the next one
489
+ * available, which happens to be unallocated -> 4M-32M
490
+ */
491
+ find_first_clear_extent_bit(&tree, SZ_2M, &start, &end,
492
+ CHUNK_TRIMMED | CHUNK_ALLOCATED);
493
+
494
+ if (start != SZ_4M || end != SZ_32M - 1) {
495
+ test_err("error finding next unalloc range: start %llu end %llu",
496
+ start, end);
497
+ goto out;
498
+ }
499
+
500
+ /*
501
+ * Set 64M-72M with CHUNK_ALLOC flag, then search for CHUNK_TRIMMED flag
502
+ * being unset in this range, we should get the entry in range 64M-72M
503
+ */
504
+ set_extent_bits(&tree, SZ_64M, SZ_64M + SZ_8M - 1, CHUNK_ALLOCATED);
505
+ find_first_clear_extent_bit(&tree, SZ_64M + SZ_1M, &start, &end,
506
+ CHUNK_TRIMMED);
507
+
508
+ if (start != SZ_64M || end != SZ_64M + SZ_8M - 1) {
509
+ test_err("error finding exact range: start %llu end %llu",
510
+ start, end);
511
+ goto out;
512
+ }
513
+
514
+ find_first_clear_extent_bit(&tree, SZ_64M - SZ_8M, &start, &end,
515
+ CHUNK_TRIMMED);
516
+
517
+ /*
518
+ * Search in the middle of set range whose immediate neighbour doesn't
519
+ * have the bits set so it must be returned
520
+ */
521
+ if (start != SZ_64M || end != SZ_64M + SZ_8M - 1) {
522
+ test_err("error finding next alloc range: start %llu end %llu",
523
+ start, end);
524
+ goto out;
525
+ }
526
+
527
+ /*
528
+ * Search beyond any known range, shall return after last known range
529
+ * and end should be -1
530
+ */
531
+ find_first_clear_extent_bit(&tree, -1, &start, &end, CHUNK_TRIMMED);
532
+ if (start != SZ_64M + SZ_8M || end != -1) {
533
+ test_err(
534
+ "error handling beyond end of range search: start %llu end %llu",
535
+ start, end);
536
+ goto out;
537
+ }
538
+
539
+ ret = 0;
540
+out:
541
+ clear_extent_bits(&tree, 0, (u64)-1, CHUNK_TRIMMED | CHUNK_ALLOCATED);
542
+
421543 return ret;
422544 }
423545
....@@ -431,8 +553,11 @@
431553 if (ret)
432554 goto out;
433555
556
+ ret = test_find_first_clear_extent_bit();
557
+ if (ret)
558
+ goto out;
559
+
434560 ret = test_eb_bitmaps(sectorsize, nodesize);
435561 out:
436
- test_msg("extent I/O tests finished");
437562 return ret;
438563 }