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