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