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