1 /* 2 * Copyright (C) 2013 Fusion IO. All rights reserved. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public 6 * License v2 as published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 11 * General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public 14 * License along with this program; if not, write to the 15 * Free Software Foundation, Inc., 59 Temple Place - Suite 330, 16 * Boston, MA 021110-1307, USA. 17 */ 18 19 #include <linux/types.h> 20 #include "btrfs-tests.h" 21 #include "../ctree.h" 22 #include "../btrfs_inode.h" 23 #include "../disk-io.h" 24 #include "../extent_io.h" 25 #include "../volumes.h" 26 #include "../compression.h" 27 28 static void insert_extent(struct btrfs_root *root, u64 start, u64 len, 29 u64 ram_bytes, u64 offset, u64 disk_bytenr, 30 u64 disk_len, u32 type, u8 compression, int slot) 31 { 32 struct btrfs_path path; 33 struct btrfs_file_extent_item *fi; 34 struct extent_buffer *leaf = root->node; 35 struct btrfs_key key; 36 u32 value_len = sizeof(struct btrfs_file_extent_item); 37 38 if (type == BTRFS_FILE_EXTENT_INLINE) 39 value_len += len; 40 memset(&path, 0, sizeof(path)); 41 42 path.nodes[0] = leaf; 43 path.slots[0] = slot; 44 45 key.objectid = BTRFS_FIRST_FREE_OBJECTID; 46 key.type = BTRFS_EXTENT_DATA_KEY; 47 key.offset = start; 48 49 setup_items_for_insert(root, &path, &key, &value_len, value_len, 50 value_len + sizeof(struct btrfs_item), 1); 51 fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item); 52 btrfs_set_file_extent_generation(leaf, fi, 1); 53 btrfs_set_file_extent_type(leaf, fi, type); 54 btrfs_set_file_extent_disk_bytenr(leaf, fi, disk_bytenr); 55 btrfs_set_file_extent_disk_num_bytes(leaf, fi, disk_len); 56 btrfs_set_file_extent_offset(leaf, fi, offset); 57 btrfs_set_file_extent_num_bytes(leaf, fi, len); 58 btrfs_set_file_extent_ram_bytes(leaf, fi, ram_bytes); 59 btrfs_set_file_extent_compression(leaf, fi, compression); 60 btrfs_set_file_extent_encryption(leaf, fi, 0); 61 btrfs_set_file_extent_other_encoding(leaf, fi, 0); 62 } 63 64 static void insert_inode_item_key(struct btrfs_root *root) 65 { 66 struct btrfs_path path; 67 struct extent_buffer *leaf = root->node; 68 struct btrfs_key key; 69 u32 value_len = 0; 70 71 memset(&path, 0, sizeof(path)); 72 73 path.nodes[0] = leaf; 74 path.slots[0] = 0; 75 76 key.objectid = BTRFS_INODE_ITEM_KEY; 77 key.type = BTRFS_INODE_ITEM_KEY; 78 key.offset = 0; 79 80 setup_items_for_insert(root, &path, &key, &value_len, value_len, 81 value_len + sizeof(struct btrfs_item), 1); 82 } 83 84 /* 85 * Build the most complicated map of extents the earth has ever seen. We want 86 * this so we can test all of the corner cases of btrfs_get_extent. Here is a 87 * diagram of how the extents will look though this may not be possible we still 88 * want to make sure everything acts normally (the last number is not inclusive) 89 * 90 * [0 - 5][5 - 6][ 6 - 4096 ][ 4096 - 4100][4100 - 8195][8195 - 12291] 91 * [hole ][inline][hole but no extent][ hole ][ regular ][regular1 split] 92 * 93 * [12291 - 16387][16387 - 24579][24579 - 28675][ 28675 - 32771][32771 - 36867 ] 94 * [ hole ][regular1 split][ prealloc ][ prealloc1 ][prealloc1 written] 95 * 96 * [36867 - 45059][45059 - 53251][53251 - 57347][57347 - 61443][61443- 69635] 97 * [ prealloc1 ][ compressed ][ compressed1 ][ regular ][ compressed1] 98 * 99 * [69635-73731][ 73731 - 86019 ][86019-90115] 100 * [ regular ][ hole but no extent][ regular ] 101 */ 102 static void setup_file_extents(struct btrfs_root *root, u32 sectorsize) 103 { 104 int slot = 0; 105 u64 disk_bytenr = SZ_1M; 106 u64 offset = 0; 107 108 /* First we want a hole */ 109 insert_extent(root, offset, 5, 5, 0, 0, 0, BTRFS_FILE_EXTENT_REG, 0, 110 slot); 111 slot++; 112 offset += 5; 113 114 /* 115 * Now we want an inline extent, I don't think this is possible but hey 116 * why not? Also keep in mind if we have an inline extent it counts as 117 * the whole first page. If we were to expand it we would have to cow 118 * and we wouldn't have an inline extent anymore. 119 */ 120 insert_extent(root, offset, 1, 1, 0, 0, 0, BTRFS_FILE_EXTENT_INLINE, 0, 121 slot); 122 slot++; 123 offset = sectorsize; 124 125 /* Now another hole */ 126 insert_extent(root, offset, 4, 4, 0, 0, 0, BTRFS_FILE_EXTENT_REG, 0, 127 slot); 128 slot++; 129 offset += 4; 130 131 /* Now for a regular extent */ 132 insert_extent(root, offset, sectorsize - 1, sectorsize - 1, 0, 133 disk_bytenr, sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot); 134 slot++; 135 disk_bytenr += sectorsize; 136 offset += sectorsize - 1; 137 138 /* 139 * Now for 3 extents that were split from a hole punch so we test 140 * offsets properly. 141 */ 142 insert_extent(root, offset, sectorsize, 4 * sectorsize, 0, disk_bytenr, 143 4 * sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot); 144 slot++; 145 offset += sectorsize; 146 insert_extent(root, offset, sectorsize, sectorsize, 0, 0, 0, 147 BTRFS_FILE_EXTENT_REG, 0, slot); 148 slot++; 149 offset += sectorsize; 150 insert_extent(root, offset, 2 * sectorsize, 4 * sectorsize, 151 2 * sectorsize, disk_bytenr, 4 * sectorsize, 152 BTRFS_FILE_EXTENT_REG, 0, slot); 153 slot++; 154 offset += 2 * sectorsize; 155 disk_bytenr += 4 * sectorsize; 156 157 /* Now for a unwritten prealloc extent */ 158 insert_extent(root, offset, sectorsize, sectorsize, 0, disk_bytenr, 159 sectorsize, BTRFS_FILE_EXTENT_PREALLOC, 0, slot); 160 slot++; 161 offset += sectorsize; 162 163 /* 164 * We want to jack up disk_bytenr a little more so the em stuff doesn't 165 * merge our records. 166 */ 167 disk_bytenr += 2 * sectorsize; 168 169 /* 170 * Now for a partially written prealloc extent, basically the same as 171 * the hole punch example above. Ram_bytes never changes when you mark 172 * extents written btw. 173 */ 174 insert_extent(root, offset, sectorsize, 4 * sectorsize, 0, disk_bytenr, 175 4 * sectorsize, BTRFS_FILE_EXTENT_PREALLOC, 0, slot); 176 slot++; 177 offset += sectorsize; 178 insert_extent(root, offset, sectorsize, 4 * sectorsize, sectorsize, 179 disk_bytenr, 4 * sectorsize, BTRFS_FILE_EXTENT_REG, 0, 180 slot); 181 slot++; 182 offset += sectorsize; 183 insert_extent(root, offset, 2 * sectorsize, 4 * sectorsize, 184 2 * sectorsize, disk_bytenr, 4 * sectorsize, 185 BTRFS_FILE_EXTENT_PREALLOC, 0, slot); 186 slot++; 187 offset += 2 * sectorsize; 188 disk_bytenr += 4 * sectorsize; 189 190 /* Now a normal compressed extent */ 191 insert_extent(root, offset, 2 * sectorsize, 2 * sectorsize, 0, 192 disk_bytenr, sectorsize, BTRFS_FILE_EXTENT_REG, 193 BTRFS_COMPRESS_ZLIB, slot); 194 slot++; 195 offset += 2 * sectorsize; 196 /* No merges */ 197 disk_bytenr += 2 * sectorsize; 198 199 /* Now a split compressed extent */ 200 insert_extent(root, offset, sectorsize, 4 * sectorsize, 0, disk_bytenr, 201 sectorsize, BTRFS_FILE_EXTENT_REG, 202 BTRFS_COMPRESS_ZLIB, slot); 203 slot++; 204 offset += sectorsize; 205 insert_extent(root, offset, sectorsize, sectorsize, 0, 206 disk_bytenr + sectorsize, sectorsize, 207 BTRFS_FILE_EXTENT_REG, 0, slot); 208 slot++; 209 offset += sectorsize; 210 insert_extent(root, offset, 2 * sectorsize, 4 * sectorsize, 211 2 * sectorsize, disk_bytenr, sectorsize, 212 BTRFS_FILE_EXTENT_REG, BTRFS_COMPRESS_ZLIB, slot); 213 slot++; 214 offset += 2 * sectorsize; 215 disk_bytenr += 2 * sectorsize; 216 217 /* Now extents that have a hole but no hole extent */ 218 insert_extent(root, offset, sectorsize, sectorsize, 0, disk_bytenr, 219 sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot); 220 slot++; 221 offset += 4 * sectorsize; 222 disk_bytenr += sectorsize; 223 insert_extent(root, offset, sectorsize, sectorsize, 0, disk_bytenr, 224 sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot); 225 } 226 227 static unsigned long prealloc_only = 0; 228 static unsigned long compressed_only = 0; 229 static unsigned long vacancy_only = 0; 230 231 static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize) 232 { 233 struct inode *inode = NULL; 234 struct btrfs_root *root = NULL; 235 struct extent_map *em = NULL; 236 u64 orig_start; 237 u64 disk_bytenr; 238 u64 offset; 239 int ret = -ENOMEM; 240 241 inode = btrfs_new_test_inode(); 242 if (!inode) { 243 test_msg("Couldn't allocate inode\n"); 244 return ret; 245 } 246 247 BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY; 248 BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID; 249 BTRFS_I(inode)->location.offset = 0; 250 251 root = btrfs_alloc_dummy_root(sectorsize, nodesize); 252 if (IS_ERR(root)) { 253 test_msg("Couldn't allocate root\n"); 254 goto out; 255 } 256 257 /* 258 * We do this since btrfs_get_extent wants to assign em->bdev to 259 * root->fs_info->fs_devices->latest_bdev. 260 */ 261 root->fs_info = btrfs_alloc_dummy_fs_info(); 262 if (!root->fs_info) { 263 test_msg("Couldn't allocate dummy fs info\n"); 264 goto out; 265 } 266 267 root->node = alloc_dummy_extent_buffer(NULL, nodesize, nodesize); 268 if (!root->node) { 269 test_msg("Couldn't allocate dummy buffer\n"); 270 goto out; 271 } 272 273 /* 274 * We will just free a dummy node if it's ref count is 2 so we need an 275 * extra ref so our searches don't accidentally release our page. 276 */ 277 extent_buffer_get(root->node); 278 btrfs_set_header_nritems(root->node, 0); 279 btrfs_set_header_level(root->node, 0); 280 ret = -EINVAL; 281 282 /* First with no extents */ 283 BTRFS_I(inode)->root = root; 284 em = btrfs_get_extent(inode, NULL, 0, 0, sectorsize, 0); 285 if (IS_ERR(em)) { 286 em = NULL; 287 test_msg("Got an error when we shouldn't have\n"); 288 goto out; 289 } 290 if (em->block_start != EXTENT_MAP_HOLE) { 291 test_msg("Expected a hole, got %llu\n", em->block_start); 292 goto out; 293 } 294 if (!test_bit(EXTENT_FLAG_VACANCY, &em->flags)) { 295 test_msg("Vacancy flag wasn't set properly\n"); 296 goto out; 297 } 298 free_extent_map(em); 299 btrfs_drop_extent_cache(inode, 0, (u64)-1, 0); 300 301 /* 302 * All of the magic numbers are based on the mapping setup in 303 * setup_file_extents, so if you change anything there you need to 304 * update the comment and update the expected values below. 305 */ 306 setup_file_extents(root, sectorsize); 307 308 em = btrfs_get_extent(inode, NULL, 0, 0, (u64)-1, 0); 309 if (IS_ERR(em)) { 310 test_msg("Got an error when we shouldn't have\n"); 311 goto out; 312 } 313 if (em->block_start != EXTENT_MAP_HOLE) { 314 test_msg("Expected a hole, got %llu\n", em->block_start); 315 goto out; 316 } 317 if (em->start != 0 || em->len != 5) { 318 test_msg("Unexpected extent wanted start 0 len 5, got start " 319 "%llu len %llu\n", em->start, em->len); 320 goto out; 321 } 322 if (em->flags != 0) { 323 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); 324 goto out; 325 } 326 offset = em->start + em->len; 327 free_extent_map(em); 328 329 em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); 330 if (IS_ERR(em)) { 331 test_msg("Got an error when we shouldn't have\n"); 332 goto out; 333 } 334 if (em->block_start != EXTENT_MAP_INLINE) { 335 test_msg("Expected an inline, got %llu\n", em->block_start); 336 goto out; 337 } 338 339 if (em->start != offset || em->len != (sectorsize - 5)) { 340 test_msg("Unexpected extent wanted start %llu len 1, got start " 341 "%llu len %llu\n", offset, em->start, em->len); 342 goto out; 343 } 344 if (em->flags != 0) { 345 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); 346 goto out; 347 } 348 /* 349 * We don't test anything else for inline since it doesn't get set 350 * unless we have a page for it to write into. Maybe we should change 351 * this? 352 */ 353 offset = em->start + em->len; 354 free_extent_map(em); 355 356 em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); 357 if (IS_ERR(em)) { 358 test_msg("Got an error when we shouldn't have\n"); 359 goto out; 360 } 361 if (em->block_start != EXTENT_MAP_HOLE) { 362 test_msg("Expected a hole, got %llu\n", em->block_start); 363 goto out; 364 } 365 if (em->start != offset || em->len != 4) { 366 test_msg("Unexpected extent wanted start %llu len 4, got start " 367 "%llu len %llu\n", offset, em->start, em->len); 368 goto out; 369 } 370 if (em->flags != 0) { 371 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); 372 goto out; 373 } 374 offset = em->start + em->len; 375 free_extent_map(em); 376 377 /* Regular extent */ 378 em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); 379 if (IS_ERR(em)) { 380 test_msg("Got an error when we shouldn't have\n"); 381 goto out; 382 } 383 if (em->block_start >= EXTENT_MAP_LAST_BYTE) { 384 test_msg("Expected a real extent, got %llu\n", em->block_start); 385 goto out; 386 } 387 if (em->start != offset || em->len != sectorsize - 1) { 388 test_msg("Unexpected extent wanted start %llu len 4095, got " 389 "start %llu len %llu\n", offset, em->start, em->len); 390 goto out; 391 } 392 if (em->flags != 0) { 393 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); 394 goto out; 395 } 396 if (em->orig_start != em->start) { 397 test_msg("Wrong orig offset, want %llu, have %llu\n", em->start, 398 em->orig_start); 399 goto out; 400 } 401 offset = em->start + em->len; 402 free_extent_map(em); 403 404 /* The next 3 are split extents */ 405 em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); 406 if (IS_ERR(em)) { 407 test_msg("Got an error when we shouldn't have\n"); 408 goto out; 409 } 410 if (em->block_start >= EXTENT_MAP_LAST_BYTE) { 411 test_msg("Expected a real extent, got %llu\n", em->block_start); 412 goto out; 413 } 414 if (em->start != offset || em->len != sectorsize) { 415 test_msg("Unexpected extent start %llu len %u, " 416 "got start %llu len %llu\n", 417 offset, sectorsize, em->start, em->len); 418 goto out; 419 } 420 if (em->flags != 0) { 421 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); 422 goto out; 423 } 424 if (em->orig_start != em->start) { 425 test_msg("Wrong orig offset, want %llu, have %llu\n", em->start, 426 em->orig_start); 427 goto out; 428 } 429 disk_bytenr = em->block_start; 430 orig_start = em->start; 431 offset = em->start + em->len; 432 free_extent_map(em); 433 434 em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); 435 if (IS_ERR(em)) { 436 test_msg("Got an error when we shouldn't have\n"); 437 goto out; 438 } 439 if (em->block_start != EXTENT_MAP_HOLE) { 440 test_msg("Expected a hole, got %llu\n", em->block_start); 441 goto out; 442 } 443 if (em->start != offset || em->len != sectorsize) { 444 test_msg("Unexpected extent wanted start %llu len %u, " 445 "got start %llu len %llu\n", 446 offset, sectorsize, em->start, em->len); 447 goto out; 448 } 449 if (em->flags != 0) { 450 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); 451 goto out; 452 } 453 offset = em->start + em->len; 454 free_extent_map(em); 455 456 em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); 457 if (IS_ERR(em)) { 458 test_msg("Got an error when we shouldn't have\n"); 459 goto out; 460 } 461 if (em->block_start >= EXTENT_MAP_LAST_BYTE) { 462 test_msg("Expected a real extent, got %llu\n", em->block_start); 463 goto out; 464 } 465 if (em->start != offset || em->len != 2 * sectorsize) { 466 test_msg("Unexpected extent wanted start %llu len %u, " 467 "got start %llu len %llu\n", 468 offset, 2 * sectorsize, em->start, em->len); 469 goto out; 470 } 471 if (em->flags != 0) { 472 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); 473 goto out; 474 } 475 if (em->orig_start != orig_start) { 476 test_msg("Wrong orig offset, want %llu, have %llu\n", 477 orig_start, em->orig_start); 478 goto out; 479 } 480 disk_bytenr += (em->start - orig_start); 481 if (em->block_start != disk_bytenr) { 482 test_msg("Wrong block start, want %llu, have %llu\n", 483 disk_bytenr, em->block_start); 484 goto out; 485 } 486 offset = em->start + em->len; 487 free_extent_map(em); 488 489 /* Prealloc extent */ 490 em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); 491 if (IS_ERR(em)) { 492 test_msg("Got an error when we shouldn't have\n"); 493 goto out; 494 } 495 if (em->block_start >= EXTENT_MAP_LAST_BYTE) { 496 test_msg("Expected a real extent, got %llu\n", em->block_start); 497 goto out; 498 } 499 if (em->start != offset || em->len != sectorsize) { 500 test_msg("Unexpected extent wanted start %llu len %u, " 501 "got start %llu len %llu\n", 502 offset, sectorsize, em->start, em->len); 503 goto out; 504 } 505 if (em->flags != prealloc_only) { 506 test_msg("Unexpected flags set, want %lu have %lu\n", 507 prealloc_only, em->flags); 508 goto out; 509 } 510 if (em->orig_start != em->start) { 511 test_msg("Wrong orig offset, want %llu, have %llu\n", em->start, 512 em->orig_start); 513 goto out; 514 } 515 offset = em->start + em->len; 516 free_extent_map(em); 517 518 /* The next 3 are a half written prealloc extent */ 519 em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); 520 if (IS_ERR(em)) { 521 test_msg("Got an error when we shouldn't have\n"); 522 goto out; 523 } 524 if (em->block_start >= EXTENT_MAP_LAST_BYTE) { 525 test_msg("Expected a real extent, got %llu\n", em->block_start); 526 goto out; 527 } 528 if (em->start != offset || em->len != sectorsize) { 529 test_msg("Unexpected extent wanted start %llu len %u, " 530 "got start %llu len %llu\n", 531 offset, sectorsize, em->start, em->len); 532 goto out; 533 } 534 if (em->flags != prealloc_only) { 535 test_msg("Unexpected flags set, want %lu have %lu\n", 536 prealloc_only, em->flags); 537 goto out; 538 } 539 if (em->orig_start != em->start) { 540 test_msg("Wrong orig offset, want %llu, have %llu\n", em->start, 541 em->orig_start); 542 goto out; 543 } 544 disk_bytenr = em->block_start; 545 orig_start = em->start; 546 offset = em->start + em->len; 547 free_extent_map(em); 548 549 em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); 550 if (IS_ERR(em)) { 551 test_msg("Got an error when we shouldn't have\n"); 552 goto out; 553 } 554 if (em->block_start >= EXTENT_MAP_HOLE) { 555 test_msg("Expected a real extent, got %llu\n", em->block_start); 556 goto out; 557 } 558 if (em->start != offset || em->len != sectorsize) { 559 test_msg("Unexpected extent wanted start %llu len %u, " 560 "got start %llu len %llu\n", 561 offset, sectorsize, em->start, em->len); 562 goto out; 563 } 564 if (em->flags != 0) { 565 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); 566 goto out; 567 } 568 if (em->orig_start != orig_start) { 569 test_msg("Unexpected orig offset, wanted %llu, have %llu\n", 570 orig_start, em->orig_start); 571 goto out; 572 } 573 if (em->block_start != (disk_bytenr + (em->start - em->orig_start))) { 574 test_msg("Unexpected block start, wanted %llu, have %llu\n", 575 disk_bytenr + (em->start - em->orig_start), 576 em->block_start); 577 goto out; 578 } 579 offset = em->start + em->len; 580 free_extent_map(em); 581 582 em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); 583 if (IS_ERR(em)) { 584 test_msg("Got an error when we shouldn't have\n"); 585 goto out; 586 } 587 if (em->block_start >= EXTENT_MAP_LAST_BYTE) { 588 test_msg("Expected a real extent, got %llu\n", em->block_start); 589 goto out; 590 } 591 if (em->start != offset || em->len != 2 * sectorsize) { 592 test_msg("Unexpected extent wanted start %llu len %u, " 593 "got start %llu len %llu\n", 594 offset, 2 * sectorsize, em->start, em->len); 595 goto out; 596 } 597 if (em->flags != prealloc_only) { 598 test_msg("Unexpected flags set, want %lu have %lu\n", 599 prealloc_only, em->flags); 600 goto out; 601 } 602 if (em->orig_start != orig_start) { 603 test_msg("Wrong orig offset, want %llu, have %llu\n", orig_start, 604 em->orig_start); 605 goto out; 606 } 607 if (em->block_start != (disk_bytenr + (em->start - em->orig_start))) { 608 test_msg("Unexpected block start, wanted %llu, have %llu\n", 609 disk_bytenr + (em->start - em->orig_start), 610 em->block_start); 611 goto out; 612 } 613 offset = em->start + em->len; 614 free_extent_map(em); 615 616 /* Now for the compressed extent */ 617 em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); 618 if (IS_ERR(em)) { 619 test_msg("Got an error when we shouldn't have\n"); 620 goto out; 621 } 622 if (em->block_start >= EXTENT_MAP_LAST_BYTE) { 623 test_msg("Expected a real extent, got %llu\n", em->block_start); 624 goto out; 625 } 626 if (em->start != offset || em->len != 2 * sectorsize) { 627 test_msg("Unexpected extent wanted start %llu len %u," 628 "got start %llu len %llu\n", 629 offset, 2 * sectorsize, em->start, em->len); 630 goto out; 631 } 632 if (em->flags != compressed_only) { 633 test_msg("Unexpected flags set, want %lu have %lu\n", 634 compressed_only, em->flags); 635 goto out; 636 } 637 if (em->orig_start != em->start) { 638 test_msg("Wrong orig offset, want %llu, have %llu\n", 639 em->start, em->orig_start); 640 goto out; 641 } 642 if (em->compress_type != BTRFS_COMPRESS_ZLIB) { 643 test_msg("Unexpected compress type, wanted %d, got %d\n", 644 BTRFS_COMPRESS_ZLIB, em->compress_type); 645 goto out; 646 } 647 offset = em->start + em->len; 648 free_extent_map(em); 649 650 /* Split compressed extent */ 651 em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); 652 if (IS_ERR(em)) { 653 test_msg("Got an error when we shouldn't have\n"); 654 goto out; 655 } 656 if (em->block_start >= EXTENT_MAP_LAST_BYTE) { 657 test_msg("Expected a real extent, got %llu\n", em->block_start); 658 goto out; 659 } 660 if (em->start != offset || em->len != sectorsize) { 661 test_msg("Unexpected extent wanted start %llu len %u," 662 "got start %llu len %llu\n", 663 offset, sectorsize, em->start, em->len); 664 goto out; 665 } 666 if (em->flags != compressed_only) { 667 test_msg("Unexpected flags set, want %lu have %lu\n", 668 compressed_only, em->flags); 669 goto out; 670 } 671 if (em->orig_start != em->start) { 672 test_msg("Wrong orig offset, want %llu, have %llu\n", 673 em->start, em->orig_start); 674 goto out; 675 } 676 if (em->compress_type != BTRFS_COMPRESS_ZLIB) { 677 test_msg("Unexpected compress type, wanted %d, got %d\n", 678 BTRFS_COMPRESS_ZLIB, em->compress_type); 679 goto out; 680 } 681 disk_bytenr = em->block_start; 682 orig_start = em->start; 683 offset = em->start + em->len; 684 free_extent_map(em); 685 686 em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); 687 if (IS_ERR(em)) { 688 test_msg("Got an error when we shouldn't have\n"); 689 goto out; 690 } 691 if (em->block_start >= EXTENT_MAP_LAST_BYTE) { 692 test_msg("Expected a real extent, got %llu\n", em->block_start); 693 goto out; 694 } 695 if (em->start != offset || em->len != sectorsize) { 696 test_msg("Unexpected extent wanted start %llu len %u, " 697 "got start %llu len %llu\n", 698 offset, sectorsize, em->start, em->len); 699 goto out; 700 } 701 if (em->flags != 0) { 702 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); 703 goto out; 704 } 705 if (em->orig_start != em->start) { 706 test_msg("Wrong orig offset, want %llu, have %llu\n", em->start, 707 em->orig_start); 708 goto out; 709 } 710 offset = em->start + em->len; 711 free_extent_map(em); 712 713 em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); 714 if (IS_ERR(em)) { 715 test_msg("Got an error when we shouldn't have\n"); 716 goto out; 717 } 718 if (em->block_start != disk_bytenr) { 719 test_msg("Block start does not match, want %llu got %llu\n", 720 disk_bytenr, em->block_start); 721 goto out; 722 } 723 if (em->start != offset || em->len != 2 * sectorsize) { 724 test_msg("Unexpected extent wanted start %llu len %u, " 725 "got start %llu len %llu\n", 726 offset, 2 * sectorsize, em->start, em->len); 727 goto out; 728 } 729 if (em->flags != compressed_only) { 730 test_msg("Unexpected flags set, want %lu have %lu\n", 731 compressed_only, em->flags); 732 goto out; 733 } 734 if (em->orig_start != orig_start) { 735 test_msg("Wrong orig offset, want %llu, have %llu\n", 736 em->start, orig_start); 737 goto out; 738 } 739 if (em->compress_type != BTRFS_COMPRESS_ZLIB) { 740 test_msg("Unexpected compress type, wanted %d, got %d\n", 741 BTRFS_COMPRESS_ZLIB, em->compress_type); 742 goto out; 743 } 744 offset = em->start + em->len; 745 free_extent_map(em); 746 747 /* A hole between regular extents but no hole extent */ 748 em = btrfs_get_extent(inode, NULL, 0, offset + 6, sectorsize, 0); 749 if (IS_ERR(em)) { 750 test_msg("Got an error when we shouldn't have\n"); 751 goto out; 752 } 753 if (em->block_start >= EXTENT_MAP_LAST_BYTE) { 754 test_msg("Expected a real extent, got %llu\n", em->block_start); 755 goto out; 756 } 757 if (em->start != offset || em->len != sectorsize) { 758 test_msg("Unexpected extent wanted start %llu len %u, " 759 "got start %llu len %llu\n", 760 offset, sectorsize, em->start, em->len); 761 goto out; 762 } 763 if (em->flags != 0) { 764 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); 765 goto out; 766 } 767 if (em->orig_start != em->start) { 768 test_msg("Wrong orig offset, want %llu, have %llu\n", em->start, 769 em->orig_start); 770 goto out; 771 } 772 offset = em->start + em->len; 773 free_extent_map(em); 774 775 em = btrfs_get_extent(inode, NULL, 0, offset, 4096 * 1024, 0); 776 if (IS_ERR(em)) { 777 test_msg("Got an error when we shouldn't have\n"); 778 goto out; 779 } 780 if (em->block_start != EXTENT_MAP_HOLE) { 781 test_msg("Expected a hole extent, got %llu\n", em->block_start); 782 goto out; 783 } 784 /* 785 * Currently we just return a length that we requested rather than the 786 * length of the actual hole, if this changes we'll have to change this 787 * test. 788 */ 789 if (em->start != offset || em->len != 3 * sectorsize) { 790 test_msg("Unexpected extent wanted start %llu len %u, " 791 "got start %llu len %llu\n", 792 offset, 3 * sectorsize, em->start, em->len); 793 goto out; 794 } 795 if (em->flags != vacancy_only) { 796 test_msg("Unexpected flags set, want %lu have %lu\n", 797 vacancy_only, em->flags); 798 goto out; 799 } 800 if (em->orig_start != em->start) { 801 test_msg("Wrong orig offset, want %llu, have %llu\n", em->start, 802 em->orig_start); 803 goto out; 804 } 805 offset = em->start + em->len; 806 free_extent_map(em); 807 808 em = btrfs_get_extent(inode, NULL, 0, offset, sectorsize, 0); 809 if (IS_ERR(em)) { 810 test_msg("Got an error when we shouldn't have\n"); 811 goto out; 812 } 813 if (em->block_start >= EXTENT_MAP_LAST_BYTE) { 814 test_msg("Expected a real extent, got %llu\n", em->block_start); 815 goto out; 816 } 817 if (em->start != offset || em->len != sectorsize) { 818 test_msg("Unexpected extent wanted start %llu len %u," 819 "got start %llu len %llu\n", 820 offset, sectorsize, em->start, em->len); 821 goto out; 822 } 823 if (em->flags != 0) { 824 test_msg("Unexpected flags set, want 0 have %lu\n", em->flags); 825 goto out; 826 } 827 if (em->orig_start != em->start) { 828 test_msg("Wrong orig offset, want %llu, have %llu\n", em->start, 829 em->orig_start); 830 goto out; 831 } 832 ret = 0; 833 out: 834 if (!IS_ERR(em)) 835 free_extent_map(em); 836 iput(inode); 837 btrfs_free_dummy_root(root); 838 return ret; 839 } 840 841 static int test_hole_first(u32 sectorsize, u32 nodesize) 842 { 843 struct inode *inode = NULL; 844 struct btrfs_root *root = NULL; 845 struct extent_map *em = NULL; 846 int ret = -ENOMEM; 847 848 inode = btrfs_new_test_inode(); 849 if (!inode) { 850 test_msg("Couldn't allocate inode\n"); 851 return ret; 852 } 853 854 BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY; 855 BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID; 856 BTRFS_I(inode)->location.offset = 0; 857 858 root = btrfs_alloc_dummy_root(sectorsize, nodesize); 859 if (IS_ERR(root)) { 860 test_msg("Couldn't allocate root\n"); 861 goto out; 862 } 863 864 root->fs_info = btrfs_alloc_dummy_fs_info(); 865 if (!root->fs_info) { 866 test_msg("Couldn't allocate dummy fs info\n"); 867 goto out; 868 } 869 870 root->node = alloc_dummy_extent_buffer(NULL, nodesize, nodesize); 871 if (!root->node) { 872 test_msg("Couldn't allocate dummy buffer\n"); 873 goto out; 874 } 875 876 extent_buffer_get(root->node); 877 btrfs_set_header_nritems(root->node, 0); 878 btrfs_set_header_level(root->node, 0); 879 BTRFS_I(inode)->root = root; 880 ret = -EINVAL; 881 882 /* 883 * Need a blank inode item here just so we don't confuse 884 * btrfs_get_extent. 885 */ 886 insert_inode_item_key(root); 887 insert_extent(root, sectorsize, sectorsize, sectorsize, 0, sectorsize, 888 sectorsize, BTRFS_FILE_EXTENT_REG, 0, 1); 889 em = btrfs_get_extent(inode, NULL, 0, 0, 2 * sectorsize, 0); 890 if (IS_ERR(em)) { 891 test_msg("Got an error when we shouldn't have\n"); 892 goto out; 893 } 894 if (em->block_start != EXTENT_MAP_HOLE) { 895 test_msg("Expected a hole, got %llu\n", em->block_start); 896 goto out; 897 } 898 if (em->start != 0 || em->len != sectorsize) { 899 test_msg("Unexpected extent wanted start 0 len %u, " 900 "got start %llu len %llu\n", 901 sectorsize, em->start, em->len); 902 goto out; 903 } 904 if (em->flags != vacancy_only) { 905 test_msg("Wrong flags, wanted %lu, have %lu\n", vacancy_only, 906 em->flags); 907 goto out; 908 } 909 free_extent_map(em); 910 911 em = btrfs_get_extent(inode, NULL, 0, sectorsize, 2 * sectorsize, 0); 912 if (IS_ERR(em)) { 913 test_msg("Got an error when we shouldn't have\n"); 914 goto out; 915 } 916 if (em->block_start != sectorsize) { 917 test_msg("Expected a real extent, got %llu\n", em->block_start); 918 goto out; 919 } 920 if (em->start != sectorsize || em->len != sectorsize) { 921 test_msg("Unexpected extent wanted start %u len %u, " 922 "got start %llu len %llu\n", 923 sectorsize, sectorsize, em->start, em->len); 924 goto out; 925 } 926 if (em->flags != 0) { 927 test_msg("Unexpected flags set, wanted 0 got %lu\n", 928 em->flags); 929 goto out; 930 } 931 ret = 0; 932 out: 933 if (!IS_ERR(em)) 934 free_extent_map(em); 935 iput(inode); 936 btrfs_free_dummy_root(root); 937 return ret; 938 } 939 940 static int test_extent_accounting(u32 sectorsize, u32 nodesize) 941 { 942 struct inode *inode = NULL; 943 struct btrfs_root *root = NULL; 944 int ret = -ENOMEM; 945 946 inode = btrfs_new_test_inode(); 947 if (!inode) { 948 test_msg("Couldn't allocate inode\n"); 949 return ret; 950 } 951 952 root = btrfs_alloc_dummy_root(sectorsize, nodesize); 953 if (IS_ERR(root)) { 954 test_msg("Couldn't allocate root\n"); 955 goto out; 956 } 957 958 root->fs_info = btrfs_alloc_dummy_fs_info(); 959 if (!root->fs_info) { 960 test_msg("Couldn't allocate dummy fs info\n"); 961 goto out; 962 } 963 964 BTRFS_I(inode)->root = root; 965 btrfs_test_inode_set_ops(inode); 966 967 /* [BTRFS_MAX_EXTENT_SIZE] */ 968 BTRFS_I(inode)->outstanding_extents++; 969 ret = btrfs_set_extent_delalloc(inode, 0, BTRFS_MAX_EXTENT_SIZE - 1, 970 NULL); 971 if (ret) { 972 test_msg("btrfs_set_extent_delalloc returned %d\n", ret); 973 goto out; 974 } 975 if (BTRFS_I(inode)->outstanding_extents != 1) { 976 ret = -EINVAL; 977 test_msg("Miscount, wanted 1, got %u\n", 978 BTRFS_I(inode)->outstanding_extents); 979 goto out; 980 } 981 982 /* [BTRFS_MAX_EXTENT_SIZE][sectorsize] */ 983 BTRFS_I(inode)->outstanding_extents++; 984 ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE, 985 BTRFS_MAX_EXTENT_SIZE + sectorsize - 1, 986 NULL); 987 if (ret) { 988 test_msg("btrfs_set_extent_delalloc returned %d\n", ret); 989 goto out; 990 } 991 if (BTRFS_I(inode)->outstanding_extents != 2) { 992 ret = -EINVAL; 993 test_msg("Miscount, wanted 2, got %u\n", 994 BTRFS_I(inode)->outstanding_extents); 995 goto out; 996 } 997 998 /* [BTRFS_MAX_EXTENT_SIZE/2][sectorsize HOLE][the rest] */ 999 ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, 1000 BTRFS_MAX_EXTENT_SIZE >> 1, 1001 (BTRFS_MAX_EXTENT_SIZE >> 1) + sectorsize - 1, 1002 EXTENT_DELALLOC | EXTENT_DIRTY | 1003 EXTENT_UPTODATE | EXTENT_DO_ACCOUNTING, 0, 0, 1004 NULL, GFP_KERNEL); 1005 if (ret) { 1006 test_msg("clear_extent_bit returned %d\n", ret); 1007 goto out; 1008 } 1009 if (BTRFS_I(inode)->outstanding_extents != 2) { 1010 ret = -EINVAL; 1011 test_msg("Miscount, wanted 2, got %u\n", 1012 BTRFS_I(inode)->outstanding_extents); 1013 goto out; 1014 } 1015 1016 /* [BTRFS_MAX_EXTENT_SIZE][sectorsize] */ 1017 BTRFS_I(inode)->outstanding_extents++; 1018 ret = btrfs_set_extent_delalloc(inode, BTRFS_MAX_EXTENT_SIZE >> 1, 1019 (BTRFS_MAX_EXTENT_SIZE >> 1) 1020 + sectorsize - 1, 1021 NULL); 1022 if (ret) { 1023 test_msg("btrfs_set_extent_delalloc returned %d\n", ret); 1024 goto out; 1025 } 1026 if (BTRFS_I(inode)->outstanding_extents != 2) { 1027 ret = -EINVAL; 1028 test_msg("Miscount, wanted 2, got %u\n", 1029 BTRFS_I(inode)->outstanding_extents); 1030 goto out; 1031 } 1032 1033 /* 1034 * [BTRFS_MAX_EXTENT_SIZE+sectorsize][sectorsize HOLE][BTRFS_MAX_EXTENT_SIZE+sectorsize] 1035 * 1036 * I'm artificially adding 2 to outstanding_extents because in the 1037 * buffered IO case we'd add things up as we go, but I don't feel like 1038 * doing that here, this isn't the interesting case we want to test. 1039 */ 1040 BTRFS_I(inode)->outstanding_extents += 2; 1041 ret = btrfs_set_extent_delalloc(inode, 1042 BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize, 1043 (BTRFS_MAX_EXTENT_SIZE << 1) + 3 * sectorsize - 1, 1044 NULL); 1045 if (ret) { 1046 test_msg("btrfs_set_extent_delalloc returned %d\n", ret); 1047 goto out; 1048 } 1049 if (BTRFS_I(inode)->outstanding_extents != 4) { 1050 ret = -EINVAL; 1051 test_msg("Miscount, wanted 4, got %u\n", 1052 BTRFS_I(inode)->outstanding_extents); 1053 goto out; 1054 } 1055 1056 /* 1057 * [BTRFS_MAX_EXTENT_SIZE+sectorsize][sectorsize][BTRFS_MAX_EXTENT_SIZE+sectorsize] 1058 */ 1059 BTRFS_I(inode)->outstanding_extents++; 1060 ret = btrfs_set_extent_delalloc(inode, 1061 BTRFS_MAX_EXTENT_SIZE + sectorsize, 1062 BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, NULL); 1063 if (ret) { 1064 test_msg("btrfs_set_extent_delalloc returned %d\n", ret); 1065 goto out; 1066 } 1067 if (BTRFS_I(inode)->outstanding_extents != 3) { 1068 ret = -EINVAL; 1069 test_msg("Miscount, wanted 3, got %u\n", 1070 BTRFS_I(inode)->outstanding_extents); 1071 goto out; 1072 } 1073 1074 /* [BTRFS_MAX_EXTENT_SIZE+4k][4K HOLE][BTRFS_MAX_EXTENT_SIZE+4k] */ 1075 ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, 1076 BTRFS_MAX_EXTENT_SIZE + sectorsize, 1077 BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, 1078 EXTENT_DIRTY | EXTENT_DELALLOC | 1079 EXTENT_DO_ACCOUNTING | EXTENT_UPTODATE, 0, 0, 1080 NULL, GFP_KERNEL); 1081 if (ret) { 1082 test_msg("clear_extent_bit returned %d\n", ret); 1083 goto out; 1084 } 1085 if (BTRFS_I(inode)->outstanding_extents != 4) { 1086 ret = -EINVAL; 1087 test_msg("Miscount, wanted 4, got %u\n", 1088 BTRFS_I(inode)->outstanding_extents); 1089 goto out; 1090 } 1091 1092 /* 1093 * Refill the hole again just for good measure, because I thought it 1094 * might fail and I'd rather satisfy my paranoia at this point. 1095 */ 1096 BTRFS_I(inode)->outstanding_extents++; 1097 ret = btrfs_set_extent_delalloc(inode, 1098 BTRFS_MAX_EXTENT_SIZE + sectorsize, 1099 BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, NULL); 1100 if (ret) { 1101 test_msg("btrfs_set_extent_delalloc returned %d\n", ret); 1102 goto out; 1103 } 1104 if (BTRFS_I(inode)->outstanding_extents != 3) { 1105 ret = -EINVAL; 1106 test_msg("Miscount, wanted 3, got %u\n", 1107 BTRFS_I(inode)->outstanding_extents); 1108 goto out; 1109 } 1110 1111 /* Empty */ 1112 ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1, 1113 EXTENT_DIRTY | EXTENT_DELALLOC | 1114 EXTENT_DO_ACCOUNTING | EXTENT_UPTODATE, 0, 0, 1115 NULL, GFP_KERNEL); 1116 if (ret) { 1117 test_msg("clear_extent_bit returned %d\n", ret); 1118 goto out; 1119 } 1120 if (BTRFS_I(inode)->outstanding_extents) { 1121 ret = -EINVAL; 1122 test_msg("Miscount, wanted 0, got %u\n", 1123 BTRFS_I(inode)->outstanding_extents); 1124 goto out; 1125 } 1126 ret = 0; 1127 out: 1128 if (ret) 1129 clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1, 1130 EXTENT_DIRTY | EXTENT_DELALLOC | 1131 EXTENT_DO_ACCOUNTING | EXTENT_UPTODATE, 0, 0, 1132 NULL, GFP_KERNEL); 1133 iput(inode); 1134 btrfs_free_dummy_root(root); 1135 return ret; 1136 } 1137 1138 int btrfs_test_inodes(u32 sectorsize, u32 nodesize) 1139 { 1140 int ret; 1141 1142 set_bit(EXTENT_FLAG_COMPRESSED, &compressed_only); 1143 set_bit(EXTENT_FLAG_VACANCY, &vacancy_only); 1144 set_bit(EXTENT_FLAG_PREALLOC, &prealloc_only); 1145 1146 test_msg("Running btrfs_get_extent tests\n"); 1147 ret = test_btrfs_get_extent(sectorsize, nodesize); 1148 if (ret) 1149 return ret; 1150 test_msg("Running hole first btrfs_get_extent test\n"); 1151 ret = test_hole_first(sectorsize, nodesize); 1152 if (ret) 1153 return ret; 1154 test_msg("Running outstanding_extents tests\n"); 1155 return test_extent_accounting(sectorsize, nodesize); 1156 } 1157