0001
0002
0003
0004
0005
0006 #include <linux/pagemap.h>
0007 #include <linux/sched.h>
0008 #include <linux/slab.h>
0009 #include <linux/sizes.h>
0010 #include "btrfs-tests.h"
0011 #include "../ctree.h"
0012 #include "../extent_io.h"
0013 #include "../btrfs_inode.h"
0014
0015 #define PROCESS_UNLOCK (1 << 0)
0016 #define PROCESS_RELEASE (1 << 1)
0017 #define PROCESS_TEST_LOCKED (1 << 2)
0018
0019 static noinline int process_page_range(struct inode *inode, u64 start, u64 end,
0020 unsigned long flags)
0021 {
0022 int ret;
0023 struct page *pages[16];
0024 unsigned long index = start >> PAGE_SHIFT;
0025 unsigned long end_index = end >> PAGE_SHIFT;
0026 unsigned long nr_pages = end_index - index + 1;
0027 int i;
0028 int count = 0;
0029 int loops = 0;
0030
0031 while (nr_pages > 0) {
0032 ret = find_get_pages_contig(inode->i_mapping, index,
0033 min_t(unsigned long, nr_pages,
0034 ARRAY_SIZE(pages)), pages);
0035 for (i = 0; i < ret; i++) {
0036 if (flags & PROCESS_TEST_LOCKED &&
0037 !PageLocked(pages[i]))
0038 count++;
0039 if (flags & PROCESS_UNLOCK && PageLocked(pages[i]))
0040 unlock_page(pages[i]);
0041 put_page(pages[i]);
0042 if (flags & PROCESS_RELEASE)
0043 put_page(pages[i]);
0044 }
0045 nr_pages -= ret;
0046 index += ret;
0047 cond_resched();
0048 loops++;
0049 if (loops > 100000) {
0050 printk(KERN_ERR
0051 "stuck in a loop, start %llu, end %llu, nr_pages %lu, ret %d\n",
0052 start, end, nr_pages, ret);
0053 break;
0054 }
0055 }
0056 return count;
0057 }
0058
0059 #define STATE_FLAG_STR_LEN 256
0060
0061 #define PRINT_ONE_FLAG(state, dest, cur, name) \
0062 ({ \
0063 if (state->state & EXTENT_##name) \
0064 cur += scnprintf(dest + cur, STATE_FLAG_STR_LEN - cur, \
0065 "%s" #name, cur == 0 ? "" : "|"); \
0066 })
0067
0068 static void extent_flag_to_str(const struct extent_state *state, char *dest)
0069 {
0070 int cur = 0;
0071
0072 dest[0] = 0;
0073 PRINT_ONE_FLAG(state, dest, cur, DIRTY);
0074 PRINT_ONE_FLAG(state, dest, cur, UPTODATE);
0075 PRINT_ONE_FLAG(state, dest, cur, LOCKED);
0076 PRINT_ONE_FLAG(state, dest, cur, NEW);
0077 PRINT_ONE_FLAG(state, dest, cur, DELALLOC);
0078 PRINT_ONE_FLAG(state, dest, cur, DEFRAG);
0079 PRINT_ONE_FLAG(state, dest, cur, BOUNDARY);
0080 PRINT_ONE_FLAG(state, dest, cur, NODATASUM);
0081 PRINT_ONE_FLAG(state, dest, cur, CLEAR_META_RESV);
0082 PRINT_ONE_FLAG(state, dest, cur, NEED_WAIT);
0083 PRINT_ONE_FLAG(state, dest, cur, DAMAGED);
0084 PRINT_ONE_FLAG(state, dest, cur, NORESERVE);
0085 PRINT_ONE_FLAG(state, dest, cur, QGROUP_RESERVED);
0086 PRINT_ONE_FLAG(state, dest, cur, CLEAR_DATA_RESV);
0087 }
0088
0089 static void dump_extent_io_tree(const struct extent_io_tree *tree)
0090 {
0091 struct rb_node *node;
0092 char flags_str[STATE_FLAG_STR_LEN];
0093
0094 node = rb_first(&tree->state);
0095 test_msg("io tree content:");
0096 while (node) {
0097 struct extent_state *state;
0098
0099 state = rb_entry(node, struct extent_state, rb_node);
0100 extent_flag_to_str(state, flags_str);
0101 test_msg(" start=%llu len=%llu flags=%s", state->start,
0102 state->end + 1 - state->start, flags_str);
0103 node = rb_next(node);
0104 }
0105 }
0106
0107 static int test_find_delalloc(u32 sectorsize)
0108 {
0109 struct inode *inode;
0110 struct extent_io_tree *tmp;
0111 struct page *page;
0112 struct page *locked_page = NULL;
0113 unsigned long index = 0;
0114
0115 u64 max_bytes = BTRFS_MAX_EXTENT_SIZE;
0116 u64 total_dirty = 2 * max_bytes;
0117 u64 start, end, test_start;
0118 bool found;
0119 int ret = -EINVAL;
0120
0121 test_msg("running find delalloc tests");
0122
0123 inode = btrfs_new_test_inode();
0124 if (!inode) {
0125 test_std_err(TEST_ALLOC_INODE);
0126 return -ENOMEM;
0127 }
0128 tmp = &BTRFS_I(inode)->io_tree;
0129
0130
0131
0132
0133
0134 extent_io_tree_init(NULL, tmp, IO_TREE_SELFTEST, NULL);
0135
0136
0137
0138
0139
0140
0141 for (index = 0; index < (total_dirty >> PAGE_SHIFT); index++) {
0142 page = find_or_create_page(inode->i_mapping, index, GFP_KERNEL);
0143 if (!page) {
0144 test_err("failed to allocate test page");
0145 ret = -ENOMEM;
0146 goto out;
0147 }
0148 SetPageDirty(page);
0149 if (index) {
0150 unlock_page(page);
0151 } else {
0152 get_page(page);
0153 locked_page = page;
0154 }
0155 }
0156
0157
0158
0159
0160
0161 set_extent_delalloc(tmp, 0, sectorsize - 1, 0, NULL);
0162 start = 0;
0163 end = start + PAGE_SIZE - 1;
0164 found = find_lock_delalloc_range(inode, locked_page, &start,
0165 &end);
0166 if (!found) {
0167 test_err("should have found at least one delalloc");
0168 goto out_bits;
0169 }
0170 if (start != 0 || end != (sectorsize - 1)) {
0171 test_err("expected start 0 end %u, got start %llu end %llu",
0172 sectorsize - 1, start, end);
0173 goto out_bits;
0174 }
0175 unlock_extent(tmp, start, end);
0176 unlock_page(locked_page);
0177 put_page(locked_page);
0178
0179
0180
0181
0182
0183
0184
0185 test_start = SZ_64M;
0186 locked_page = find_lock_page(inode->i_mapping,
0187 test_start >> PAGE_SHIFT);
0188 if (!locked_page) {
0189 test_err("couldn't find the locked page");
0190 goto out_bits;
0191 }
0192 set_extent_delalloc(tmp, sectorsize, max_bytes - 1, 0, NULL);
0193 start = test_start;
0194 end = start + PAGE_SIZE - 1;
0195 found = find_lock_delalloc_range(inode, locked_page, &start,
0196 &end);
0197 if (!found) {
0198 test_err("couldn't find delalloc in our range");
0199 goto out_bits;
0200 }
0201 if (start != test_start || end != max_bytes - 1) {
0202 test_err("expected start %llu end %llu, got start %llu, end %llu",
0203 test_start, max_bytes - 1, start, end);
0204 goto out_bits;
0205 }
0206 if (process_page_range(inode, start, end,
0207 PROCESS_TEST_LOCKED | PROCESS_UNLOCK)) {
0208 test_err("there were unlocked pages in the range");
0209 goto out_bits;
0210 }
0211 unlock_extent(tmp, start, end);
0212
0213 put_page(locked_page);
0214
0215
0216
0217
0218
0219
0220 test_start = max_bytes + sectorsize;
0221 locked_page = find_lock_page(inode->i_mapping, test_start >>
0222 PAGE_SHIFT);
0223 if (!locked_page) {
0224 test_err("couldn't find the locked page");
0225 goto out_bits;
0226 }
0227 start = test_start;
0228 end = start + PAGE_SIZE - 1;
0229 found = find_lock_delalloc_range(inode, locked_page, &start,
0230 &end);
0231 if (found) {
0232 test_err("found range when we shouldn't have");
0233 goto out_bits;
0234 }
0235 if (end != test_start + PAGE_SIZE - 1) {
0236 test_err("did not return the proper end offset");
0237 goto out_bits;
0238 }
0239
0240
0241
0242
0243
0244
0245
0246
0247 set_extent_delalloc(tmp, max_bytes, total_dirty - 1, 0, NULL);
0248 start = test_start;
0249 end = start + PAGE_SIZE - 1;
0250 found = find_lock_delalloc_range(inode, locked_page, &start,
0251 &end);
0252 if (!found) {
0253 test_err("didn't find our range");
0254 goto out_bits;
0255 }
0256 if (start != test_start || end != total_dirty - 1) {
0257 test_err("expected start %llu end %llu, got start %llu end %llu",
0258 test_start, total_dirty - 1, start, end);
0259 goto out_bits;
0260 }
0261 if (process_page_range(inode, start, end,
0262 PROCESS_TEST_LOCKED | PROCESS_UNLOCK)) {
0263 test_err("pages in range were not all locked");
0264 goto out_bits;
0265 }
0266 unlock_extent(tmp, start, end);
0267
0268
0269
0270
0271
0272 page = find_get_page(inode->i_mapping,
0273 (max_bytes + SZ_1M) >> PAGE_SHIFT);
0274 if (!page) {
0275 test_err("couldn't find our page");
0276 goto out_bits;
0277 }
0278 ClearPageDirty(page);
0279 put_page(page);
0280
0281
0282 lock_page(locked_page);
0283 start = test_start;
0284 end = start + PAGE_SIZE - 1;
0285
0286
0287
0288
0289
0290
0291 found = find_lock_delalloc_range(inode, locked_page, &start,
0292 &end);
0293 if (!found) {
0294 test_err("didn't find our range");
0295 goto out_bits;
0296 }
0297 if (start != test_start && end != test_start + PAGE_SIZE - 1) {
0298 test_err("expected start %llu end %llu, got start %llu end %llu",
0299 test_start, test_start + PAGE_SIZE - 1, start, end);
0300 goto out_bits;
0301 }
0302 if (process_page_range(inode, start, end, PROCESS_TEST_LOCKED |
0303 PROCESS_UNLOCK)) {
0304 test_err("pages in range were not all locked");
0305 goto out_bits;
0306 }
0307 ret = 0;
0308 out_bits:
0309 if (ret)
0310 dump_extent_io_tree(tmp);
0311 clear_extent_bits(tmp, 0, total_dirty - 1, (unsigned)-1);
0312 out:
0313 if (locked_page)
0314 put_page(locked_page);
0315 process_page_range(inode, 0, total_dirty - 1,
0316 PROCESS_UNLOCK | PROCESS_RELEASE);
0317 iput(inode);
0318 return ret;
0319 }
0320
0321 static int check_eb_bitmap(unsigned long *bitmap, struct extent_buffer *eb,
0322 unsigned long len)
0323 {
0324 unsigned long i;
0325
0326 for (i = 0; i < len * BITS_PER_BYTE; i++) {
0327 int bit, bit1;
0328
0329 bit = !!test_bit(i, bitmap);
0330 bit1 = !!extent_buffer_test_bit(eb, 0, i);
0331 if (bit1 != bit) {
0332 test_err("bits do not match");
0333 return -EINVAL;
0334 }
0335
0336 bit1 = !!extent_buffer_test_bit(eb, i / BITS_PER_BYTE,
0337 i % BITS_PER_BYTE);
0338 if (bit1 != bit) {
0339 test_err("offset bits do not match");
0340 return -EINVAL;
0341 }
0342 }
0343 return 0;
0344 }
0345
0346 static int __test_eb_bitmaps(unsigned long *bitmap, struct extent_buffer *eb,
0347 unsigned long len)
0348 {
0349 unsigned long i, j;
0350 u32 x;
0351 int ret;
0352
0353 memset(bitmap, 0, len);
0354 memzero_extent_buffer(eb, 0, len);
0355 if (memcmp_extent_buffer(eb, bitmap, 0, len) != 0) {
0356 test_err("bitmap was not zeroed");
0357 return -EINVAL;
0358 }
0359
0360 bitmap_set(bitmap, 0, len * BITS_PER_BYTE);
0361 extent_buffer_bitmap_set(eb, 0, 0, len * BITS_PER_BYTE);
0362 ret = check_eb_bitmap(bitmap, eb, len);
0363 if (ret) {
0364 test_err("setting all bits failed");
0365 return ret;
0366 }
0367
0368 bitmap_clear(bitmap, 0, len * BITS_PER_BYTE);
0369 extent_buffer_bitmap_clear(eb, 0, 0, len * BITS_PER_BYTE);
0370 ret = check_eb_bitmap(bitmap, eb, len);
0371 if (ret) {
0372 test_err("clearing all bits failed");
0373 return ret;
0374 }
0375
0376
0377 if (len > PAGE_SIZE) {
0378 bitmap_set(bitmap,
0379 (PAGE_SIZE - sizeof(long) / 2) * BITS_PER_BYTE,
0380 sizeof(long) * BITS_PER_BYTE);
0381 extent_buffer_bitmap_set(eb, PAGE_SIZE - sizeof(long) / 2, 0,
0382 sizeof(long) * BITS_PER_BYTE);
0383 ret = check_eb_bitmap(bitmap, eb, len);
0384 if (ret) {
0385 test_err("setting straddling pages failed");
0386 return ret;
0387 }
0388
0389 bitmap_set(bitmap, 0, len * BITS_PER_BYTE);
0390 bitmap_clear(bitmap,
0391 (PAGE_SIZE - sizeof(long) / 2) * BITS_PER_BYTE,
0392 sizeof(long) * BITS_PER_BYTE);
0393 extent_buffer_bitmap_set(eb, 0, 0, len * BITS_PER_BYTE);
0394 extent_buffer_bitmap_clear(eb, PAGE_SIZE - sizeof(long) / 2, 0,
0395 sizeof(long) * BITS_PER_BYTE);
0396 ret = check_eb_bitmap(bitmap, eb, len);
0397 if (ret) {
0398 test_err("clearing straddling pages failed");
0399 return ret;
0400 }
0401 }
0402
0403
0404
0405
0406
0407 x = 0;
0408 bitmap_clear(bitmap, 0, len * BITS_PER_BYTE);
0409 extent_buffer_bitmap_clear(eb, 0, 0, len * BITS_PER_BYTE);
0410 for (i = 0; i < len * BITS_PER_BYTE / 32; i++) {
0411 x = (0x19660dULL * (u64)x + 0x3c6ef35fULL) & 0xffffffffU;
0412 for (j = 0; j < 32; j++) {
0413 if (x & (1U << j)) {
0414 bitmap_set(bitmap, i * 32 + j, 1);
0415 extent_buffer_bitmap_set(eb, 0, i * 32 + j, 1);
0416 }
0417 }
0418 }
0419
0420 ret = check_eb_bitmap(bitmap, eb, len);
0421 if (ret) {
0422 test_err("random bit pattern failed");
0423 return ret;
0424 }
0425
0426 return 0;
0427 }
0428
0429 static int test_eb_bitmaps(u32 sectorsize, u32 nodesize)
0430 {
0431 struct btrfs_fs_info *fs_info;
0432 unsigned long *bitmap = NULL;
0433 struct extent_buffer *eb = NULL;
0434 int ret;
0435
0436 test_msg("running extent buffer bitmap tests");
0437
0438 fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
0439 if (!fs_info) {
0440 test_std_err(TEST_ALLOC_FS_INFO);
0441 return -ENOMEM;
0442 }
0443
0444 bitmap = kmalloc(nodesize, GFP_KERNEL);
0445 if (!bitmap) {
0446 test_err("couldn't allocate test bitmap");
0447 ret = -ENOMEM;
0448 goto out;
0449 }
0450
0451 eb = __alloc_dummy_extent_buffer(fs_info, 0, nodesize);
0452 if (!eb) {
0453 test_std_err(TEST_ALLOC_ROOT);
0454 ret = -ENOMEM;
0455 goto out;
0456 }
0457
0458 ret = __test_eb_bitmaps(bitmap, eb, nodesize);
0459 if (ret)
0460 goto out;
0461
0462 free_extent_buffer(eb);
0463
0464
0465
0466
0467
0468 eb = __alloc_dummy_extent_buffer(fs_info, sectorsize, nodesize);
0469 if (!eb) {
0470 test_std_err(TEST_ALLOC_ROOT);
0471 ret = -ENOMEM;
0472 goto out;
0473 }
0474
0475 ret = __test_eb_bitmaps(bitmap, eb, nodesize);
0476 out:
0477 free_extent_buffer(eb);
0478 kfree(bitmap);
0479 btrfs_free_dummy_fs_info(fs_info);
0480 return ret;
0481 }
0482
0483 static int test_find_first_clear_extent_bit(void)
0484 {
0485 struct extent_io_tree tree;
0486 u64 start, end;
0487 int ret = -EINVAL;
0488
0489 test_msg("running find_first_clear_extent_bit test");
0490
0491 extent_io_tree_init(NULL, &tree, IO_TREE_SELFTEST, NULL);
0492
0493
0494 find_first_clear_extent_bit(&tree, 0, &start, &end, CHUNK_TRIMMED);
0495 if (start != 0 || end != -1) {
0496 test_err(
0497 "error getting a range from completely empty tree: start %llu end %llu",
0498 start, end);
0499 goto out;
0500 }
0501
0502
0503
0504
0505 set_extent_bits(&tree, SZ_1M, SZ_4M - 1,
0506 CHUNK_TRIMMED | CHUNK_ALLOCATED);
0507
0508 find_first_clear_extent_bit(&tree, SZ_512K, &start, &end,
0509 CHUNK_TRIMMED | CHUNK_ALLOCATED);
0510
0511 if (start != 0 || end != SZ_1M - 1) {
0512 test_err("error finding beginning range: start %llu end %llu",
0513 start, end);
0514 goto out;
0515 }
0516
0517
0518 set_extent_bits(&tree, SZ_32M, SZ_64M - 1,
0519 CHUNK_TRIMMED | CHUNK_ALLOCATED);
0520
0521
0522
0523
0524 find_first_clear_extent_bit(&tree, 12 * SZ_1M, &start, &end,
0525 CHUNK_TRIMMED | CHUNK_ALLOCATED);
0526
0527 if (start != SZ_4M || end != SZ_32M - 1) {
0528 test_err("error finding trimmed range: start %llu end %llu",
0529 start, end);
0530 goto out;
0531 }
0532
0533
0534
0535
0536
0537 find_first_clear_extent_bit(&tree, SZ_2M, &start, &end,
0538 CHUNK_TRIMMED | CHUNK_ALLOCATED);
0539
0540 if (start != SZ_4M || end != SZ_32M - 1) {
0541 test_err("error finding next unalloc range: start %llu end %llu",
0542 start, end);
0543 goto out;
0544 }
0545
0546
0547
0548
0549
0550 set_extent_bits(&tree, SZ_64M, SZ_64M + SZ_8M - 1, CHUNK_ALLOCATED);
0551 find_first_clear_extent_bit(&tree, SZ_64M + SZ_1M, &start, &end,
0552 CHUNK_TRIMMED);
0553
0554 if (start != SZ_64M || end != SZ_64M + SZ_8M - 1) {
0555 test_err("error finding exact range: start %llu end %llu",
0556 start, end);
0557 goto out;
0558 }
0559
0560 find_first_clear_extent_bit(&tree, SZ_64M - SZ_8M, &start, &end,
0561 CHUNK_TRIMMED);
0562
0563
0564
0565
0566
0567 if (start != SZ_64M || end != SZ_64M + SZ_8M - 1) {
0568 test_err("error finding next alloc range: start %llu end %llu",
0569 start, end);
0570 goto out;
0571 }
0572
0573
0574
0575
0576
0577 find_first_clear_extent_bit(&tree, -1, &start, &end, CHUNK_TRIMMED);
0578 if (start != SZ_64M + SZ_8M || end != -1) {
0579 test_err(
0580 "error handling beyond end of range search: start %llu end %llu",
0581 start, end);
0582 goto out;
0583 }
0584
0585 ret = 0;
0586 out:
0587 if (ret)
0588 dump_extent_io_tree(&tree);
0589 clear_extent_bits(&tree, 0, (u64)-1, CHUNK_TRIMMED | CHUNK_ALLOCATED);
0590
0591 return ret;
0592 }
0593
0594 int btrfs_test_extent_io(u32 sectorsize, u32 nodesize)
0595 {
0596 int ret;
0597
0598 test_msg("running extent I/O tests");
0599
0600 ret = test_find_delalloc(sectorsize);
0601 if (ret)
0602 goto out;
0603
0604 ret = test_find_first_clear_extent_bit();
0605 if (ret)
0606 goto out;
0607
0608 ret = test_eb_bitmaps(sectorsize, nodesize);
0609 out:
0610 return ret;
0611 }