1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2017 Oracle. All rights reserved. 4 */ 5 6 #include <linux/types.h> 7 #include "btrfs-tests.h" 8 #include "../ctree.h" 9 #include "../btrfs_inode.h" 10 #include "../volumes.h" 11 #include "../disk-io.h" 12 #include "../block-group.h" 13 14 static void free_extent_map_tree(struct extent_map_tree *em_tree) 15 { 16 struct extent_map *em; 17 struct rb_node *node; 18 19 write_lock(&em_tree->lock); 20 while (!RB_EMPTY_ROOT(&em_tree->map.rb_root)) { 21 node = rb_first_cached(&em_tree->map); 22 em = rb_entry(node, struct extent_map, rb_node); 23 remove_extent_mapping(em_tree, em); 24 25 #ifdef CONFIG_BTRFS_DEBUG 26 if (refcount_read(&em->refs) != 1) { 27 test_err( 28 "em leak: em (start 0x%llx len 0x%llx block_start 0x%llx block_len 0x%llx) refs %d", 29 em->start, em->len, em->block_start, 30 em->block_len, refcount_read(&em->refs)); 31 32 refcount_set(&em->refs, 1); 33 } 34 #endif 35 free_extent_map(em); 36 } 37 write_unlock(&em_tree->lock); 38 } 39 40 /* 41 * Test scenario: 42 * 43 * Suppose that no extent map has been loaded into memory yet, there is a file 44 * extent [0, 16K), followed by another file extent [16K, 20K), two dio reads 45 * are entering btrfs_get_extent() concurrently, t1 is reading [8K, 16K), t2 is 46 * reading [0, 8K) 47 * 48 * t1 t2 49 * btrfs_get_extent() btrfs_get_extent() 50 * -> lookup_extent_mapping() ->lookup_extent_mapping() 51 * -> add_extent_mapping(0, 16K) 52 * -> return em 53 * ->add_extent_mapping(0, 16K) 54 * -> #handle -EEXIST 55 */ 56 static int test_case_1(struct btrfs_fs_info *fs_info, 57 struct extent_map_tree *em_tree) 58 { 59 struct extent_map *em; 60 u64 start = 0; 61 u64 len = SZ_8K; 62 int ret; 63 64 em = alloc_extent_map(); 65 if (!em) { 66 test_std_err(TEST_ALLOC_EXTENT_MAP); 67 return -ENOMEM; 68 } 69 70 /* Add [0, 16K) */ 71 em->start = 0; 72 em->len = SZ_16K; 73 em->block_start = 0; 74 em->block_len = SZ_16K; 75 write_lock(&em_tree->lock); 76 ret = add_extent_mapping(em_tree, em, 0); 77 write_unlock(&em_tree->lock); 78 if (ret < 0) { 79 test_err("cannot add extent range [0, 16K)"); 80 goto out; 81 } 82 free_extent_map(em); 83 84 /* Add [16K, 20K) following [0, 16K) */ 85 em = alloc_extent_map(); 86 if (!em) { 87 test_std_err(TEST_ALLOC_EXTENT_MAP); 88 ret = -ENOMEM; 89 goto out; 90 } 91 92 em->start = SZ_16K; 93 em->len = SZ_4K; 94 em->block_start = SZ_32K; /* avoid merging */ 95 em->block_len = SZ_4K; 96 write_lock(&em_tree->lock); 97 ret = add_extent_mapping(em_tree, em, 0); 98 write_unlock(&em_tree->lock); 99 if (ret < 0) { 100 test_err("cannot add extent range [16K, 20K)"); 101 goto out; 102 } 103 free_extent_map(em); 104 105 em = alloc_extent_map(); 106 if (!em) { 107 test_std_err(TEST_ALLOC_EXTENT_MAP); 108 ret = -ENOMEM; 109 goto out; 110 } 111 112 /* Add [0, 8K), should return [0, 16K) instead. */ 113 em->start = start; 114 em->len = len; 115 em->block_start = start; 116 em->block_len = len; 117 write_lock(&em_tree->lock); 118 ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len); 119 write_unlock(&em_tree->lock); 120 if (ret) { 121 test_err("case1 [%llu %llu]: ret %d", start, start + len, ret); 122 goto out; 123 } 124 if (em && 125 (em->start != 0 || extent_map_end(em) != SZ_16K || 126 em->block_start != 0 || em->block_len != SZ_16K)) { 127 test_err( 128 "case1 [%llu %llu]: ret %d return a wrong em (start %llu len %llu block_start %llu block_len %llu", 129 start, start + len, ret, em->start, em->len, 130 em->block_start, em->block_len); 131 ret = -EINVAL; 132 } 133 free_extent_map(em); 134 out: 135 free_extent_map_tree(em_tree); 136 137 return ret; 138 } 139 140 /* 141 * Test scenario: 142 * 143 * Reading the inline ending up with EEXIST, ie. read an inline 144 * extent and discard page cache and read it again. 145 */ 146 static int test_case_2(struct btrfs_fs_info *fs_info, 147 struct extent_map_tree *em_tree) 148 { 149 struct extent_map *em; 150 int ret; 151 152 em = alloc_extent_map(); 153 if (!em) { 154 test_std_err(TEST_ALLOC_EXTENT_MAP); 155 return -ENOMEM; 156 } 157 158 /* Add [0, 1K) */ 159 em->start = 0; 160 em->len = SZ_1K; 161 em->block_start = EXTENT_MAP_INLINE; 162 em->block_len = (u64)-1; 163 write_lock(&em_tree->lock); 164 ret = add_extent_mapping(em_tree, em, 0); 165 write_unlock(&em_tree->lock); 166 if (ret < 0) { 167 test_err("cannot add extent range [0, 1K)"); 168 goto out; 169 } 170 free_extent_map(em); 171 172 /* Add [4K, 8K) following [0, 1K) */ 173 em = alloc_extent_map(); 174 if (!em) { 175 test_std_err(TEST_ALLOC_EXTENT_MAP); 176 ret = -ENOMEM; 177 goto out; 178 } 179 180 em->start = SZ_4K; 181 em->len = SZ_4K; 182 em->block_start = SZ_4K; 183 em->block_len = SZ_4K; 184 write_lock(&em_tree->lock); 185 ret = add_extent_mapping(em_tree, em, 0); 186 write_unlock(&em_tree->lock); 187 if (ret < 0) { 188 test_err("cannot add extent range [4K, 8K)"); 189 goto out; 190 } 191 free_extent_map(em); 192 193 em = alloc_extent_map(); 194 if (!em) { 195 test_std_err(TEST_ALLOC_EXTENT_MAP); 196 ret = -ENOMEM; 197 goto out; 198 } 199 200 /* Add [0, 1K) */ 201 em->start = 0; 202 em->len = SZ_1K; 203 em->block_start = EXTENT_MAP_INLINE; 204 em->block_len = (u64)-1; 205 write_lock(&em_tree->lock); 206 ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, em->start, em->len); 207 write_unlock(&em_tree->lock); 208 if (ret) { 209 test_err("case2 [0 1K]: ret %d", ret); 210 goto out; 211 } 212 if (em && 213 (em->start != 0 || extent_map_end(em) != SZ_1K || 214 em->block_start != EXTENT_MAP_INLINE || em->block_len != (u64)-1)) { 215 test_err( 216 "case2 [0 1K]: ret %d return a wrong em (start %llu len %llu block_start %llu block_len %llu", 217 ret, em->start, em->len, em->block_start, 218 em->block_len); 219 ret = -EINVAL; 220 } 221 free_extent_map(em); 222 out: 223 free_extent_map_tree(em_tree); 224 225 return ret; 226 } 227 228 static int __test_case_3(struct btrfs_fs_info *fs_info, 229 struct extent_map_tree *em_tree, u64 start) 230 { 231 struct extent_map *em; 232 u64 len = SZ_4K; 233 int ret; 234 235 em = alloc_extent_map(); 236 if (!em) { 237 test_std_err(TEST_ALLOC_EXTENT_MAP); 238 return -ENOMEM; 239 } 240 241 /* Add [4K, 8K) */ 242 em->start = SZ_4K; 243 em->len = SZ_4K; 244 em->block_start = SZ_4K; 245 em->block_len = SZ_4K; 246 write_lock(&em_tree->lock); 247 ret = add_extent_mapping(em_tree, em, 0); 248 write_unlock(&em_tree->lock); 249 if (ret < 0) { 250 test_err("cannot add extent range [4K, 8K)"); 251 goto out; 252 } 253 free_extent_map(em); 254 255 em = alloc_extent_map(); 256 if (!em) { 257 test_std_err(TEST_ALLOC_EXTENT_MAP); 258 ret = -ENOMEM; 259 goto out; 260 } 261 262 /* Add [0, 16K) */ 263 em->start = 0; 264 em->len = SZ_16K; 265 em->block_start = 0; 266 em->block_len = SZ_16K; 267 write_lock(&em_tree->lock); 268 ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, start, len); 269 write_unlock(&em_tree->lock); 270 if (ret) { 271 test_err("case3 [0x%llx 0x%llx): ret %d", 272 start, start + len, ret); 273 goto out; 274 } 275 /* 276 * Since bytes within em are contiguous, em->block_start is identical to 277 * em->start. 278 */ 279 if (em && 280 (start < em->start || start + len > extent_map_end(em) || 281 em->start != em->block_start || em->len != em->block_len)) { 282 test_err( 283 "case3 [0x%llx 0x%llx): ret %d em (start 0x%llx len 0x%llx block_start 0x%llx block_len 0x%llx)", 284 start, start + len, ret, em->start, em->len, 285 em->block_start, em->block_len); 286 ret = -EINVAL; 287 } 288 free_extent_map(em); 289 out: 290 free_extent_map_tree(em_tree); 291 292 return ret; 293 } 294 295 /* 296 * Test scenario: 297 * 298 * Suppose that no extent map has been loaded into memory yet. 299 * There is a file extent [0, 16K), two jobs are running concurrently 300 * against it, t1 is buffered writing to [4K, 8K) and t2 is doing dio 301 * read from [0, 4K) or [8K, 12K) or [12K, 16K). 302 * 303 * t1 goes ahead of t2 and adds em [4K, 8K) into tree. 304 * 305 * t1 t2 306 * cow_file_range() btrfs_get_extent() 307 * -> lookup_extent_mapping() 308 * -> add_extent_mapping() 309 * -> add_extent_mapping() 310 */ 311 static int test_case_3(struct btrfs_fs_info *fs_info, 312 struct extent_map_tree *em_tree) 313 { 314 int ret; 315 316 ret = __test_case_3(fs_info, em_tree, 0); 317 if (ret) 318 return ret; 319 ret = __test_case_3(fs_info, em_tree, SZ_8K); 320 if (ret) 321 return ret; 322 ret = __test_case_3(fs_info, em_tree, (12 * SZ_1K)); 323 324 return ret; 325 } 326 327 static int __test_case_4(struct btrfs_fs_info *fs_info, 328 struct extent_map_tree *em_tree, u64 start) 329 { 330 struct extent_map *em; 331 u64 len = SZ_4K; 332 int ret; 333 334 em = alloc_extent_map(); 335 if (!em) { 336 test_std_err(TEST_ALLOC_EXTENT_MAP); 337 return -ENOMEM; 338 } 339 340 /* Add [0K, 8K) */ 341 em->start = 0; 342 em->len = SZ_8K; 343 em->block_start = 0; 344 em->block_len = SZ_8K; 345 write_lock(&em_tree->lock); 346 ret = add_extent_mapping(em_tree, em, 0); 347 write_unlock(&em_tree->lock); 348 if (ret < 0) { 349 test_err("cannot add extent range [0, 8K)"); 350 goto out; 351 } 352 free_extent_map(em); 353 354 em = alloc_extent_map(); 355 if (!em) { 356 test_std_err(TEST_ALLOC_EXTENT_MAP); 357 ret = -ENOMEM; 358 goto out; 359 } 360 361 /* Add [8K, 32K) */ 362 em->start = SZ_8K; 363 em->len = 24 * SZ_1K; 364 em->block_start = SZ_16K; /* avoid merging */ 365 em->block_len = 24 * SZ_1K; 366 write_lock(&em_tree->lock); 367 ret = add_extent_mapping(em_tree, em, 0); 368 write_unlock(&em_tree->lock); 369 if (ret < 0) { 370 test_err("cannot add extent range [8K, 32K)"); 371 goto out; 372 } 373 free_extent_map(em); 374 375 em = alloc_extent_map(); 376 if (!em) { 377 test_std_err(TEST_ALLOC_EXTENT_MAP); 378 ret = -ENOMEM; 379 goto out; 380 } 381 /* Add [0K, 32K) */ 382 em->start = 0; 383 em->len = SZ_32K; 384 em->block_start = 0; 385 em->block_len = SZ_32K; 386 write_lock(&em_tree->lock); 387 ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, start, len); 388 write_unlock(&em_tree->lock); 389 if (ret) { 390 test_err("case4 [0x%llx 0x%llx): ret %d", 391 start, len, ret); 392 goto out; 393 } 394 if (em && (start < em->start || start + len > extent_map_end(em))) { 395 test_err( 396 "case4 [0x%llx 0x%llx): ret %d, added wrong em (start 0x%llx len 0x%llx block_start 0x%llx block_len 0x%llx)", 397 start, len, ret, em->start, em->len, em->block_start, 398 em->block_len); 399 ret = -EINVAL; 400 } 401 free_extent_map(em); 402 out: 403 free_extent_map_tree(em_tree); 404 405 return ret; 406 } 407 408 /* 409 * Test scenario: 410 * 411 * Suppose that no extent map has been loaded into memory yet. 412 * There is a file extent [0, 32K), two jobs are running concurrently 413 * against it, t1 is doing dio write to [8K, 32K) and t2 is doing dio 414 * read from [0, 4K) or [4K, 8K). 415 * 416 * t1 goes ahead of t2 and splits em [0, 32K) to em [0K, 8K) and [8K 32K). 417 * 418 * t1 t2 419 * btrfs_get_blocks_direct() btrfs_get_blocks_direct() 420 * -> btrfs_get_extent() -> btrfs_get_extent() 421 * -> lookup_extent_mapping() 422 * -> add_extent_mapping() -> lookup_extent_mapping() 423 * # load [0, 32K) 424 * -> btrfs_new_extent_direct() 425 * -> btrfs_drop_extent_cache() 426 * # split [0, 32K) 427 * -> add_extent_mapping() 428 * # add [8K, 32K) 429 * -> add_extent_mapping() 430 * # handle -EEXIST when adding 431 * # [0, 32K) 432 */ 433 static int test_case_4(struct btrfs_fs_info *fs_info, 434 struct extent_map_tree *em_tree) 435 { 436 int ret; 437 438 ret = __test_case_4(fs_info, em_tree, 0); 439 if (ret) 440 return ret; 441 ret = __test_case_4(fs_info, em_tree, SZ_4K); 442 443 return ret; 444 } 445 446 static int add_compressed_extent(struct extent_map_tree *em_tree, 447 u64 start, u64 len, u64 block_start) 448 { 449 struct extent_map *em; 450 int ret; 451 452 em = alloc_extent_map(); 453 if (!em) { 454 test_std_err(TEST_ALLOC_EXTENT_MAP); 455 return -ENOMEM; 456 } 457 458 em->start = start; 459 em->len = len; 460 em->block_start = block_start; 461 em->block_len = SZ_4K; 462 set_bit(EXTENT_FLAG_COMPRESSED, &em->flags); 463 write_lock(&em_tree->lock); 464 ret = add_extent_mapping(em_tree, em, 0); 465 write_unlock(&em_tree->lock); 466 free_extent_map(em); 467 if (ret < 0) { 468 test_err("cannot add extent map [%llu, %llu)", start, start + len); 469 return ret; 470 } 471 472 return 0; 473 } 474 475 struct extent_range { 476 u64 start; 477 u64 len; 478 }; 479 480 /* The valid states of the tree after every drop, as described below. */ 481 struct extent_range valid_ranges[][7] = { 482 { 483 { .start = 0, .len = SZ_8K }, /* [0, 8K) */ 484 { .start = SZ_4K * 3, .len = SZ_4K * 3}, /* [12k, 24k) */ 485 { .start = SZ_4K * 6, .len = SZ_4K * 3}, /* [24k, 36k) */ 486 { .start = SZ_32K + SZ_4K, .len = SZ_4K}, /* [36k, 40k) */ 487 { .start = SZ_4K * 10, .len = SZ_4K * 6}, /* [40k, 64k) */ 488 }, 489 { 490 { .start = 0, .len = SZ_8K }, /* [0, 8K) */ 491 { .start = SZ_4K * 5, .len = SZ_4K}, /* [20k, 24k) */ 492 { .start = SZ_4K * 6, .len = SZ_4K * 3}, /* [24k, 36k) */ 493 { .start = SZ_32K + SZ_4K, .len = SZ_4K}, /* [36k, 40k) */ 494 { .start = SZ_4K * 10, .len = SZ_4K * 6}, /* [40k, 64k) */ 495 }, 496 { 497 { .start = 0, .len = SZ_8K }, /* [0, 8K) */ 498 { .start = SZ_4K * 5, .len = SZ_4K}, /* [20k, 24k) */ 499 { .start = SZ_4K * 6, .len = SZ_4K}, /* [24k, 28k) */ 500 { .start = SZ_32K, .len = SZ_4K}, /* [32k, 36k) */ 501 { .start = SZ_32K + SZ_4K, .len = SZ_4K}, /* [36k, 40k) */ 502 { .start = SZ_4K * 10, .len = SZ_4K * 6}, /* [40k, 64k) */ 503 }, 504 { 505 { .start = 0, .len = SZ_8K}, /* [0, 8K) */ 506 { .start = SZ_4K * 5, .len = SZ_4K}, /* [20k, 24k) */ 507 { .start = SZ_4K * 6, .len = SZ_4K}, /* [24k, 28k) */ 508 } 509 }; 510 511 static int validate_range(struct extent_map_tree *em_tree, int index) 512 { 513 struct rb_node *n; 514 int i; 515 516 for (i = 0, n = rb_first_cached(&em_tree->map); 517 valid_ranges[index][i].len && n; 518 i++, n = rb_next(n)) { 519 struct extent_map *entry = rb_entry(n, struct extent_map, rb_node); 520 521 if (entry->start != valid_ranges[index][i].start) { 522 test_err("mapping has start %llu expected %llu", 523 entry->start, valid_ranges[index][i].start); 524 return -EINVAL; 525 } 526 527 if (entry->len != valid_ranges[index][i].len) { 528 test_err("mapping has len %llu expected %llu", 529 entry->len, valid_ranges[index][i].len); 530 return -EINVAL; 531 } 532 } 533 534 /* 535 * We exited because we don't have any more entries in the extent_map 536 * but we still expect more valid entries. 537 */ 538 if (valid_ranges[index][i].len) { 539 test_err("missing an entry"); 540 return -EINVAL; 541 } 542 543 /* We exited the loop but still have entries in the extent map. */ 544 if (n) { 545 test_err("we have a left over entry in the extent map we didn't expect"); 546 return -EINVAL; 547 } 548 549 return 0; 550 } 551 552 /* 553 * Test scenario: 554 * 555 * Test the various edge cases of btrfs_drop_extent_map_range, create the 556 * following ranges 557 * 558 * [0, 12k)[12k, 24k)[24k, 36k)[36k, 40k)[40k,64k) 559 * 560 * And then we'll drop: 561 * 562 * [8k, 12k) - test the single front split 563 * [12k, 20k) - test the single back split 564 * [28k, 32k) - test the double split 565 * [32k, 64k) - test whole em dropping 566 * 567 * They'll have the EXTENT_FLAG_COMPRESSED flag set to keep the em tree from 568 * merging the em's. 569 */ 570 static int test_case_5(void) 571 { 572 struct extent_map_tree *em_tree; 573 struct inode *inode; 574 u64 start, end; 575 int ret; 576 577 test_msg("Running btrfs_drop_extent_map_range tests"); 578 579 inode = btrfs_new_test_inode(); 580 if (!inode) { 581 test_std_err(TEST_ALLOC_INODE); 582 return -ENOMEM; 583 } 584 585 em_tree = &BTRFS_I(inode)->extent_tree; 586 587 /* [0, 12k) */ 588 ret = add_compressed_extent(em_tree, 0, SZ_4K * 3, 0); 589 if (ret) { 590 test_err("cannot add extent range [0, 12K)"); 591 goto out; 592 } 593 594 /* [12k, 24k) */ 595 ret = add_compressed_extent(em_tree, SZ_4K * 3, SZ_4K * 3, SZ_4K); 596 if (ret) { 597 test_err("cannot add extent range [12k, 24k)"); 598 goto out; 599 } 600 601 /* [24k, 36k) */ 602 ret = add_compressed_extent(em_tree, SZ_4K * 6, SZ_4K * 3, SZ_8K); 603 if (ret) { 604 test_err("cannot add extent range [12k, 24k)"); 605 goto out; 606 } 607 608 /* [36k, 40k) */ 609 ret = add_compressed_extent(em_tree, SZ_32K + SZ_4K, SZ_4K, SZ_4K * 3); 610 if (ret) { 611 test_err("cannot add extent range [12k, 24k)"); 612 goto out; 613 } 614 615 /* [40k, 64k) */ 616 ret = add_compressed_extent(em_tree, SZ_4K * 10, SZ_4K * 6, SZ_16K); 617 if (ret) { 618 test_err("cannot add extent range [12k, 24k)"); 619 goto out; 620 } 621 622 /* Drop [8k, 12k) */ 623 start = SZ_8K; 624 end = (3 * SZ_4K) - 1; 625 btrfs_drop_extent_map_range(BTRFS_I(inode), start, end, false); 626 ret = validate_range(&BTRFS_I(inode)->extent_tree, 0); 627 if (ret) 628 goto out; 629 630 /* Drop [12k, 20k) */ 631 start = SZ_4K * 3; 632 end = SZ_16K + SZ_4K - 1; 633 btrfs_drop_extent_map_range(BTRFS_I(inode), start, end, false); 634 ret = validate_range(&BTRFS_I(inode)->extent_tree, 1); 635 if (ret) 636 goto out; 637 638 /* Drop [28k, 32k) */ 639 start = SZ_32K - SZ_4K; 640 end = SZ_32K - 1; 641 btrfs_drop_extent_map_range(BTRFS_I(inode), start, end, false); 642 ret = validate_range(&BTRFS_I(inode)->extent_tree, 2); 643 if (ret) 644 goto out; 645 646 /* Drop [32k, 64k) */ 647 start = SZ_32K; 648 end = SZ_64K - 1; 649 btrfs_drop_extent_map_range(BTRFS_I(inode), start, end, false); 650 ret = validate_range(&BTRFS_I(inode)->extent_tree, 3); 651 if (ret) 652 goto out; 653 out: 654 iput(inode); 655 return ret; 656 } 657 658 /* 659 * Test the btrfs_add_extent_mapping helper which will attempt to create an em 660 * for areas between two existing ems. Validate it doesn't do this when there 661 * are two unmerged em's side by side. 662 */ 663 static int test_case_6(struct btrfs_fs_info *fs_info, struct extent_map_tree *em_tree) 664 { 665 struct extent_map *em = NULL; 666 int ret; 667 668 ret = add_compressed_extent(em_tree, 0, SZ_4K, 0); 669 if (ret) 670 goto out; 671 672 ret = add_compressed_extent(em_tree, SZ_4K, SZ_4K, 0); 673 if (ret) 674 goto out; 675 676 em = alloc_extent_map(); 677 if (!em) { 678 test_std_err(TEST_ALLOC_EXTENT_MAP); 679 return -ENOMEM; 680 } 681 682 em->start = SZ_4K; 683 em->len = SZ_4K; 684 em->block_start = SZ_16K; 685 em->block_len = SZ_16K; 686 write_lock(&em_tree->lock); 687 ret = btrfs_add_extent_mapping(fs_info, em_tree, &em, 0, SZ_8K); 688 write_unlock(&em_tree->lock); 689 690 if (ret != 0) { 691 test_err("got an error when adding our em: %d", ret); 692 goto out; 693 } 694 695 ret = -EINVAL; 696 if (em->start != 0) { 697 test_err("unexpected em->start at %llu, wanted 0", em->start); 698 goto out; 699 } 700 if (em->len != SZ_4K) { 701 test_err("unexpected em->len %llu, expected 4K", em->len); 702 goto out; 703 } 704 ret = 0; 705 out: 706 free_extent_map(em); 707 free_extent_map_tree(em_tree); 708 return ret; 709 } 710 711 /* 712 * Regression test for btrfs_drop_extent_map_range. Calling with skip_pinned == 713 * true would mess up the start/end calculations and subsequent splits would be 714 * incorrect. 715 */ 716 static int test_case_7(void) 717 { 718 struct extent_map_tree *em_tree; 719 struct extent_map *em; 720 struct inode *inode; 721 int ret; 722 723 test_msg("Running btrfs_drop_extent_cache with pinned"); 724 725 inode = btrfs_new_test_inode(); 726 if (!inode) { 727 test_std_err(TEST_ALLOC_INODE); 728 return -ENOMEM; 729 } 730 731 em_tree = &BTRFS_I(inode)->extent_tree; 732 733 em = alloc_extent_map(); 734 if (!em) { 735 test_std_err(TEST_ALLOC_EXTENT_MAP); 736 ret = -ENOMEM; 737 goto out; 738 } 739 740 /* [0, 16K), pinned */ 741 em->start = 0; 742 em->len = SZ_16K; 743 em->block_start = 0; 744 em->block_len = SZ_4K; 745 set_bit(EXTENT_FLAG_PINNED, &em->flags); 746 write_lock(&em_tree->lock); 747 ret = add_extent_mapping(em_tree, em, 0); 748 write_unlock(&em_tree->lock); 749 if (ret < 0) { 750 test_err("couldn't add extent map"); 751 goto out; 752 } 753 free_extent_map(em); 754 755 em = alloc_extent_map(); 756 if (!em) { 757 test_std_err(TEST_ALLOC_EXTENT_MAP); 758 ret = -ENOMEM; 759 goto out; 760 } 761 762 /* [32K, 48K), not pinned */ 763 em->start = SZ_32K; 764 em->len = SZ_16K; 765 em->block_start = SZ_32K; 766 em->block_len = SZ_16K; 767 write_lock(&em_tree->lock); 768 ret = add_extent_mapping(em_tree, em, 0); 769 write_unlock(&em_tree->lock); 770 if (ret < 0) { 771 test_err("couldn't add extent map"); 772 goto out; 773 } 774 free_extent_map(em); 775 776 /* 777 * Drop [0, 36K) This should skip the [0, 4K) extent and then split the 778 * [32K, 48K) extent. 779 */ 780 btrfs_drop_extent_map_range(BTRFS_I(inode), 0, (36 * SZ_1K) - 1, true); 781 782 /* Make sure our extent maps look sane. */ 783 ret = -EINVAL; 784 785 em = lookup_extent_mapping(em_tree, 0, SZ_16K); 786 if (!em) { 787 test_err("didn't find an em at 0 as expected"); 788 goto out; 789 } 790 791 if (em->start != 0) { 792 test_err("em->start is %llu, expected 0", em->start); 793 goto out; 794 } 795 796 if (em->len != SZ_16K) { 797 test_err("em->len is %llu, expected 16K", em->len); 798 goto out; 799 } 800 801 free_extent_map(em); 802 803 read_lock(&em_tree->lock); 804 em = lookup_extent_mapping(em_tree, SZ_16K, SZ_16K); 805 read_unlock(&em_tree->lock); 806 if (em) { 807 test_err("found an em when we weren't expecting one"); 808 goto out; 809 } 810 811 read_lock(&em_tree->lock); 812 em = lookup_extent_mapping(em_tree, SZ_32K, SZ_16K); 813 read_unlock(&em_tree->lock); 814 if (!em) { 815 test_err("didn't find an em at 32K as expected"); 816 goto out; 817 } 818 819 if (em->start != (36 * SZ_1K)) { 820 test_err("em->start is %llu, expected 36K", em->start); 821 goto out; 822 } 823 824 if (em->len != (12 * SZ_1K)) { 825 test_err("em->len is %llu, expected 12K", em->len); 826 goto out; 827 } 828 829 if (em->block_start != SZ_32K + SZ_4K) { 830 test_err("em->block_start is %llu, expected 36K", em->block_start); 831 goto out; 832 } 833 834 free_extent_map(em); 835 836 read_lock(&em_tree->lock); 837 em = lookup_extent_mapping(em_tree, 48 * SZ_1K, (u64)-1); 838 read_unlock(&em_tree->lock); 839 if (em) { 840 test_err("found an unexpected em above 48K"); 841 goto out; 842 } 843 844 ret = 0; 845 out: 846 free_extent_map(em); 847 iput(inode); 848 return ret; 849 } 850 851 struct rmap_test_vector { 852 u64 raid_type; 853 u64 physical_start; 854 u64 data_stripe_size; 855 u64 num_data_stripes; 856 u64 num_stripes; 857 /* Assume we won't have more than 5 physical stripes */ 858 u64 data_stripe_phys_start[5]; 859 bool expected_mapped_addr; 860 /* Physical to logical addresses */ 861 u64 mapped_logical[5]; 862 }; 863 864 static int test_rmap_block(struct btrfs_fs_info *fs_info, 865 struct rmap_test_vector *test) 866 { 867 struct extent_map *em; 868 struct map_lookup *map = NULL; 869 u64 *logical = NULL; 870 int i, out_ndaddrs, out_stripe_len; 871 int ret; 872 873 em = alloc_extent_map(); 874 if (!em) { 875 test_std_err(TEST_ALLOC_EXTENT_MAP); 876 return -ENOMEM; 877 } 878 879 map = kmalloc(map_lookup_size(test->num_stripes), GFP_KERNEL); 880 if (!map) { 881 kfree(em); 882 test_std_err(TEST_ALLOC_EXTENT_MAP); 883 return -ENOMEM; 884 } 885 886 set_bit(EXTENT_FLAG_FS_MAPPING, &em->flags); 887 /* Start at 4GiB logical address */ 888 em->start = SZ_4G; 889 em->len = test->data_stripe_size * test->num_data_stripes; 890 em->block_len = em->len; 891 em->orig_block_len = test->data_stripe_size; 892 em->map_lookup = map; 893 894 map->num_stripes = test->num_stripes; 895 map->type = test->raid_type; 896 897 for (i = 0; i < map->num_stripes; i++) { 898 struct btrfs_device *dev = btrfs_alloc_dummy_device(fs_info); 899 900 if (IS_ERR(dev)) { 901 test_err("cannot allocate device"); 902 ret = PTR_ERR(dev); 903 goto out; 904 } 905 map->stripes[i].dev = dev; 906 map->stripes[i].physical = test->data_stripe_phys_start[i]; 907 } 908 909 write_lock(&fs_info->mapping_tree.lock); 910 ret = add_extent_mapping(&fs_info->mapping_tree, em, 0); 911 write_unlock(&fs_info->mapping_tree.lock); 912 if (ret) { 913 test_err("error adding block group mapping to mapping tree"); 914 goto out_free; 915 } 916 917 ret = btrfs_rmap_block(fs_info, em->start, btrfs_sb_offset(1), 918 &logical, &out_ndaddrs, &out_stripe_len); 919 if (ret || (out_ndaddrs == 0 && test->expected_mapped_addr)) { 920 test_err("didn't rmap anything but expected %d", 921 test->expected_mapped_addr); 922 goto out; 923 } 924 925 if (out_stripe_len != BTRFS_STRIPE_LEN) { 926 test_err("calculated stripe length doesn't match"); 927 goto out; 928 } 929 930 if (out_ndaddrs != test->expected_mapped_addr) { 931 for (i = 0; i < out_ndaddrs; i++) 932 test_msg("mapped %llu", logical[i]); 933 test_err("unexpected number of mapped addresses: %d", out_ndaddrs); 934 goto out; 935 } 936 937 for (i = 0; i < out_ndaddrs; i++) { 938 if (logical[i] != test->mapped_logical[i]) { 939 test_err("unexpected logical address mapped"); 940 goto out; 941 } 942 } 943 944 ret = 0; 945 out: 946 write_lock(&fs_info->mapping_tree.lock); 947 remove_extent_mapping(&fs_info->mapping_tree, em); 948 write_unlock(&fs_info->mapping_tree.lock); 949 /* For us */ 950 free_extent_map(em); 951 out_free: 952 /* For the tree */ 953 free_extent_map(em); 954 kfree(logical); 955 return ret; 956 } 957 958 int btrfs_test_extent_map(void) 959 { 960 struct btrfs_fs_info *fs_info = NULL; 961 struct extent_map_tree *em_tree; 962 int ret = 0, i; 963 struct rmap_test_vector rmap_tests[] = { 964 { 965 /* 966 * Test a chunk with 2 data stripes one of which 967 * intersects the physical address of the super block 968 * is correctly recognised. 969 */ 970 .raid_type = BTRFS_BLOCK_GROUP_RAID1, 971 .physical_start = SZ_64M - SZ_4M, 972 .data_stripe_size = SZ_256M, 973 .num_data_stripes = 2, 974 .num_stripes = 2, 975 .data_stripe_phys_start = 976 {SZ_64M - SZ_4M, SZ_64M - SZ_4M + SZ_256M}, 977 .expected_mapped_addr = true, 978 .mapped_logical= {SZ_4G + SZ_4M} 979 }, 980 { 981 /* 982 * Test that out-of-range physical addresses are 983 * ignored 984 */ 985 986 /* SINGLE chunk type */ 987 .raid_type = 0, 988 .physical_start = SZ_4G, 989 .data_stripe_size = SZ_256M, 990 .num_data_stripes = 1, 991 .num_stripes = 1, 992 .data_stripe_phys_start = {SZ_256M}, 993 .expected_mapped_addr = false, 994 .mapped_logical = {0} 995 } 996 }; 997 998 test_msg("running extent_map tests"); 999 1000 /* 1001 * Note: the fs_info is not set up completely, we only need 1002 * fs_info::fsid for the tracepoint. 1003 */ 1004 fs_info = btrfs_alloc_dummy_fs_info(PAGE_SIZE, PAGE_SIZE); 1005 if (!fs_info) { 1006 test_std_err(TEST_ALLOC_FS_INFO); 1007 return -ENOMEM; 1008 } 1009 1010 em_tree = kzalloc(sizeof(*em_tree), GFP_KERNEL); 1011 if (!em_tree) { 1012 ret = -ENOMEM; 1013 goto out; 1014 } 1015 1016 extent_map_tree_init(em_tree); 1017 1018 ret = test_case_1(fs_info, em_tree); 1019 if (ret) 1020 goto out; 1021 ret = test_case_2(fs_info, em_tree); 1022 if (ret) 1023 goto out; 1024 ret = test_case_3(fs_info, em_tree); 1025 if (ret) 1026 goto out; 1027 ret = test_case_4(fs_info, em_tree); 1028 if (ret) 1029 goto out; 1030 ret = test_case_5(); 1031 if (ret) 1032 goto out; 1033 ret = test_case_6(fs_info, em_tree); 1034 if (ret) 1035 goto out; 1036 ret = test_case_7(); 1037 if (ret) 1038 goto out; 1039 1040 test_msg("running rmap tests"); 1041 for (i = 0; i < ARRAY_SIZE(rmap_tests); i++) { 1042 ret = test_rmap_block(fs_info, &rmap_tests[i]); 1043 if (ret) 1044 goto out; 1045 } 1046 1047 out: 1048 kfree(em_tree); 1049 btrfs_free_dummy_fs_info(fs_info); 1050 1051 return ret; 1052 } 1053