0001
0002
0003
0004
0005
0006 #include <linux/types.h>
0007 #include "btrfs-tests.h"
0008 #include "../ctree.h"
0009 #include "../btrfs_inode.h"
0010 #include "../disk-io.h"
0011 #include "../extent_io.h"
0012 #include "../volumes.h"
0013 #include "../compression.h"
0014
0015 static void insert_extent(struct btrfs_root *root, u64 start, u64 len,
0016 u64 ram_bytes, u64 offset, u64 disk_bytenr,
0017 u64 disk_len, u32 type, u8 compression, int slot)
0018 {
0019 struct btrfs_path path;
0020 struct btrfs_file_extent_item *fi;
0021 struct extent_buffer *leaf = root->node;
0022 struct btrfs_key key;
0023 u32 value_len = sizeof(struct btrfs_file_extent_item);
0024
0025 if (type == BTRFS_FILE_EXTENT_INLINE)
0026 value_len += len;
0027 memset(&path, 0, sizeof(path));
0028
0029 path.nodes[0] = leaf;
0030 path.slots[0] = slot;
0031
0032 key.objectid = BTRFS_FIRST_FREE_OBJECTID;
0033 key.type = BTRFS_EXTENT_DATA_KEY;
0034 key.offset = start;
0035
0036 btrfs_setup_item_for_insert(root, &path, &key, value_len);
0037 fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
0038 btrfs_set_file_extent_generation(leaf, fi, 1);
0039 btrfs_set_file_extent_type(leaf, fi, type);
0040 btrfs_set_file_extent_disk_bytenr(leaf, fi, disk_bytenr);
0041 btrfs_set_file_extent_disk_num_bytes(leaf, fi, disk_len);
0042 btrfs_set_file_extent_offset(leaf, fi, offset);
0043 btrfs_set_file_extent_num_bytes(leaf, fi, len);
0044 btrfs_set_file_extent_ram_bytes(leaf, fi, ram_bytes);
0045 btrfs_set_file_extent_compression(leaf, fi, compression);
0046 btrfs_set_file_extent_encryption(leaf, fi, 0);
0047 btrfs_set_file_extent_other_encoding(leaf, fi, 0);
0048 }
0049
0050 static void insert_inode_item_key(struct btrfs_root *root)
0051 {
0052 struct btrfs_path path;
0053 struct extent_buffer *leaf = root->node;
0054 struct btrfs_key key;
0055 u32 value_len = 0;
0056
0057 memset(&path, 0, sizeof(path));
0058
0059 path.nodes[0] = leaf;
0060 path.slots[0] = 0;
0061
0062 key.objectid = BTRFS_INODE_ITEM_KEY;
0063 key.type = BTRFS_INODE_ITEM_KEY;
0064 key.offset = 0;
0065
0066 btrfs_setup_item_for_insert(root, &path, &key, value_len);
0067 }
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079
0080
0081
0082
0083
0084
0085
0086
0087 static void setup_file_extents(struct btrfs_root *root, u32 sectorsize)
0088 {
0089 int slot = 0;
0090 u64 disk_bytenr = SZ_1M;
0091 u64 offset = 0;
0092
0093
0094 insert_extent(root, offset, 5, 5, 0, 0, 0, BTRFS_FILE_EXTENT_REG, 0,
0095 slot);
0096 slot++;
0097 offset += 5;
0098
0099
0100
0101
0102
0103
0104
0105 insert_extent(root, offset, 1, 1, 0, 0, 0, BTRFS_FILE_EXTENT_INLINE, 0,
0106 slot);
0107 slot++;
0108 offset = sectorsize;
0109
0110
0111 insert_extent(root, offset, 4, 4, 0, 0, 0, BTRFS_FILE_EXTENT_REG, 0,
0112 slot);
0113 slot++;
0114 offset += 4;
0115
0116
0117 insert_extent(root, offset, sectorsize - 1, sectorsize - 1, 0,
0118 disk_bytenr, sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot);
0119 slot++;
0120 disk_bytenr += sectorsize;
0121 offset += sectorsize - 1;
0122
0123
0124
0125
0126
0127 insert_extent(root, offset, sectorsize, 4 * sectorsize, 0, disk_bytenr,
0128 4 * sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot);
0129 slot++;
0130 offset += sectorsize;
0131 insert_extent(root, offset, sectorsize, sectorsize, 0, 0, 0,
0132 BTRFS_FILE_EXTENT_REG, 0, slot);
0133 slot++;
0134 offset += sectorsize;
0135 insert_extent(root, offset, 2 * sectorsize, 4 * sectorsize,
0136 2 * sectorsize, disk_bytenr, 4 * sectorsize,
0137 BTRFS_FILE_EXTENT_REG, 0, slot);
0138 slot++;
0139 offset += 2 * sectorsize;
0140 disk_bytenr += 4 * sectorsize;
0141
0142
0143 insert_extent(root, offset, sectorsize, sectorsize, 0, disk_bytenr,
0144 sectorsize, BTRFS_FILE_EXTENT_PREALLOC, 0, slot);
0145 slot++;
0146 offset += sectorsize;
0147
0148
0149
0150
0151
0152 disk_bytenr += 2 * sectorsize;
0153
0154
0155
0156
0157
0158
0159 insert_extent(root, offset, sectorsize, 4 * sectorsize, 0, disk_bytenr,
0160 4 * sectorsize, BTRFS_FILE_EXTENT_PREALLOC, 0, slot);
0161 slot++;
0162 offset += sectorsize;
0163 insert_extent(root, offset, sectorsize, 4 * sectorsize, sectorsize,
0164 disk_bytenr, 4 * sectorsize, BTRFS_FILE_EXTENT_REG, 0,
0165 slot);
0166 slot++;
0167 offset += sectorsize;
0168 insert_extent(root, offset, 2 * sectorsize, 4 * sectorsize,
0169 2 * sectorsize, disk_bytenr, 4 * sectorsize,
0170 BTRFS_FILE_EXTENT_PREALLOC, 0, slot);
0171 slot++;
0172 offset += 2 * sectorsize;
0173 disk_bytenr += 4 * sectorsize;
0174
0175
0176 insert_extent(root, offset, 2 * sectorsize, 2 * sectorsize, 0,
0177 disk_bytenr, sectorsize, BTRFS_FILE_EXTENT_REG,
0178 BTRFS_COMPRESS_ZLIB, slot);
0179 slot++;
0180 offset += 2 * sectorsize;
0181
0182 disk_bytenr += 2 * sectorsize;
0183
0184
0185 insert_extent(root, offset, sectorsize, 4 * sectorsize, 0, disk_bytenr,
0186 sectorsize, BTRFS_FILE_EXTENT_REG,
0187 BTRFS_COMPRESS_ZLIB, slot);
0188 slot++;
0189 offset += sectorsize;
0190 insert_extent(root, offset, sectorsize, sectorsize, 0,
0191 disk_bytenr + sectorsize, sectorsize,
0192 BTRFS_FILE_EXTENT_REG, 0, slot);
0193 slot++;
0194 offset += sectorsize;
0195 insert_extent(root, offset, 2 * sectorsize, 4 * sectorsize,
0196 2 * sectorsize, disk_bytenr, sectorsize,
0197 BTRFS_FILE_EXTENT_REG, BTRFS_COMPRESS_ZLIB, slot);
0198 slot++;
0199 offset += 2 * sectorsize;
0200 disk_bytenr += 2 * sectorsize;
0201
0202
0203 insert_extent(root, offset, sectorsize, sectorsize, 0, disk_bytenr,
0204 sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot);
0205 slot++;
0206 offset += 4 * sectorsize;
0207 disk_bytenr += sectorsize;
0208 insert_extent(root, offset, sectorsize, sectorsize, 0, disk_bytenr,
0209 sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot);
0210 }
0211
0212 static unsigned long prealloc_only = 0;
0213 static unsigned long compressed_only = 0;
0214 static unsigned long vacancy_only = 0;
0215
0216 static noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
0217 {
0218 struct btrfs_fs_info *fs_info = NULL;
0219 struct inode *inode = NULL;
0220 struct btrfs_root *root = NULL;
0221 struct extent_map *em = NULL;
0222 u64 orig_start;
0223 u64 disk_bytenr;
0224 u64 offset;
0225 int ret = -ENOMEM;
0226
0227 test_msg("running btrfs_get_extent tests");
0228
0229 inode = btrfs_new_test_inode();
0230 if (!inode) {
0231 test_std_err(TEST_ALLOC_INODE);
0232 return ret;
0233 }
0234
0235 fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
0236 if (!fs_info) {
0237 test_std_err(TEST_ALLOC_FS_INFO);
0238 goto out;
0239 }
0240
0241 root = btrfs_alloc_dummy_root(fs_info);
0242 if (IS_ERR(root)) {
0243 test_std_err(TEST_ALLOC_ROOT);
0244 goto out;
0245 }
0246
0247 root->node = alloc_dummy_extent_buffer(fs_info, nodesize);
0248 if (!root->node) {
0249 test_std_err(TEST_ALLOC_ROOT);
0250 goto out;
0251 }
0252
0253 btrfs_set_header_nritems(root->node, 0);
0254 btrfs_set_header_level(root->node, 0);
0255 ret = -EINVAL;
0256
0257
0258 BTRFS_I(inode)->root = root;
0259 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, 0, sectorsize);
0260 if (IS_ERR(em)) {
0261 em = NULL;
0262 test_err("got an error when we shouldn't have");
0263 goto out;
0264 }
0265 if (em->block_start != EXTENT_MAP_HOLE) {
0266 test_err("expected a hole, got %llu", em->block_start);
0267 goto out;
0268 }
0269 free_extent_map(em);
0270 btrfs_drop_extent_cache(BTRFS_I(inode), 0, (u64)-1, 0);
0271
0272
0273
0274
0275
0276
0277 setup_file_extents(root, sectorsize);
0278
0279 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, 0, (u64)-1);
0280 if (IS_ERR(em)) {
0281 test_err("got an error when we shouldn't have");
0282 goto out;
0283 }
0284 if (em->block_start != EXTENT_MAP_HOLE) {
0285 test_err("expected a hole, got %llu", em->block_start);
0286 goto out;
0287 }
0288 if (em->start != 0 || em->len != 5) {
0289 test_err(
0290 "unexpected extent wanted start 0 len 5, got start %llu len %llu",
0291 em->start, em->len);
0292 goto out;
0293 }
0294 if (em->flags != 0) {
0295 test_err("unexpected flags set, want 0 have %lu", em->flags);
0296 goto out;
0297 }
0298 offset = em->start + em->len;
0299 free_extent_map(em);
0300
0301 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
0302 if (IS_ERR(em)) {
0303 test_err("got an error when we shouldn't have");
0304 goto out;
0305 }
0306 if (em->block_start != EXTENT_MAP_INLINE) {
0307 test_err("expected an inline, got %llu", em->block_start);
0308 goto out;
0309 }
0310
0311 if (em->start != offset || em->len != (sectorsize - 5)) {
0312 test_err(
0313 "unexpected extent wanted start %llu len 1, got start %llu len %llu",
0314 offset, em->start, em->len);
0315 goto out;
0316 }
0317 if (em->flags != 0) {
0318 test_err("unexpected flags set, want 0 have %lu", em->flags);
0319 goto out;
0320 }
0321
0322
0323
0324
0325
0326 offset = em->start + em->len;
0327 free_extent_map(em);
0328
0329 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
0330 if (IS_ERR(em)) {
0331 test_err("got an error when we shouldn't have");
0332 goto out;
0333 }
0334 if (em->block_start != EXTENT_MAP_HOLE) {
0335 test_err("expected a hole, got %llu", em->block_start);
0336 goto out;
0337 }
0338 if (em->start != offset || em->len != 4) {
0339 test_err(
0340 "unexpected extent wanted start %llu len 4, got start %llu len %llu",
0341 offset, em->start, em->len);
0342 goto out;
0343 }
0344 if (em->flags != 0) {
0345 test_err("unexpected flags set, want 0 have %lu", em->flags);
0346 goto out;
0347 }
0348 offset = em->start + em->len;
0349 free_extent_map(em);
0350
0351
0352 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
0353 if (IS_ERR(em)) {
0354 test_err("got an error when we shouldn't have");
0355 goto out;
0356 }
0357 if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
0358 test_err("expected a real extent, got %llu", em->block_start);
0359 goto out;
0360 }
0361 if (em->start != offset || em->len != sectorsize - 1) {
0362 test_err(
0363 "unexpected extent wanted start %llu len 4095, got start %llu len %llu",
0364 offset, em->start, em->len);
0365 goto out;
0366 }
0367 if (em->flags != 0) {
0368 test_err("unexpected flags set, want 0 have %lu", em->flags);
0369 goto out;
0370 }
0371 if (em->orig_start != em->start) {
0372 test_err("wrong orig offset, want %llu, have %llu", em->start,
0373 em->orig_start);
0374 goto out;
0375 }
0376 offset = em->start + em->len;
0377 free_extent_map(em);
0378
0379
0380 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
0381 if (IS_ERR(em)) {
0382 test_err("got an error when we shouldn't have");
0383 goto out;
0384 }
0385 if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
0386 test_err("expected a real extent, got %llu", em->block_start);
0387 goto out;
0388 }
0389 if (em->start != offset || em->len != sectorsize) {
0390 test_err(
0391 "unexpected extent start %llu len %u, got start %llu len %llu",
0392 offset, sectorsize, em->start, em->len);
0393 goto out;
0394 }
0395 if (em->flags != 0) {
0396 test_err("unexpected flags set, want 0 have %lu", em->flags);
0397 goto out;
0398 }
0399 if (em->orig_start != em->start) {
0400 test_err("wrong orig offset, want %llu, have %llu", em->start,
0401 em->orig_start);
0402 goto out;
0403 }
0404 disk_bytenr = em->block_start;
0405 orig_start = em->start;
0406 offset = em->start + em->len;
0407 free_extent_map(em);
0408
0409 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
0410 if (IS_ERR(em)) {
0411 test_err("got an error when we shouldn't have");
0412 goto out;
0413 }
0414 if (em->block_start != EXTENT_MAP_HOLE) {
0415 test_err("expected a hole, got %llu", em->block_start);
0416 goto out;
0417 }
0418 if (em->start != offset || em->len != sectorsize) {
0419 test_err(
0420 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
0421 offset, sectorsize, em->start, em->len);
0422 goto out;
0423 }
0424 if (em->flags != 0) {
0425 test_err("unexpected flags set, want 0 have %lu", em->flags);
0426 goto out;
0427 }
0428 offset = em->start + em->len;
0429 free_extent_map(em);
0430
0431 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
0432 if (IS_ERR(em)) {
0433 test_err("got an error when we shouldn't have");
0434 goto out;
0435 }
0436 if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
0437 test_err("expected a real extent, got %llu", em->block_start);
0438 goto out;
0439 }
0440 if (em->start != offset || em->len != 2 * sectorsize) {
0441 test_err(
0442 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
0443 offset, 2 * sectorsize, em->start, em->len);
0444 goto out;
0445 }
0446 if (em->flags != 0) {
0447 test_err("unexpected flags set, want 0 have %lu", em->flags);
0448 goto out;
0449 }
0450 if (em->orig_start != orig_start) {
0451 test_err("wrong orig offset, want %llu, have %llu",
0452 orig_start, em->orig_start);
0453 goto out;
0454 }
0455 disk_bytenr += (em->start - orig_start);
0456 if (em->block_start != disk_bytenr) {
0457 test_err("wrong block start, want %llu, have %llu",
0458 disk_bytenr, em->block_start);
0459 goto out;
0460 }
0461 offset = em->start + em->len;
0462 free_extent_map(em);
0463
0464
0465 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
0466 if (IS_ERR(em)) {
0467 test_err("got an error when we shouldn't have");
0468 goto out;
0469 }
0470 if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
0471 test_err("expected a real extent, got %llu", em->block_start);
0472 goto out;
0473 }
0474 if (em->start != offset || em->len != sectorsize) {
0475 test_err(
0476 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
0477 offset, sectorsize, em->start, em->len);
0478 goto out;
0479 }
0480 if (em->flags != prealloc_only) {
0481 test_err("unexpected flags set, want %lu have %lu",
0482 prealloc_only, em->flags);
0483 goto out;
0484 }
0485 if (em->orig_start != em->start) {
0486 test_err("wrong orig offset, want %llu, have %llu", em->start,
0487 em->orig_start);
0488 goto out;
0489 }
0490 offset = em->start + em->len;
0491 free_extent_map(em);
0492
0493
0494 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
0495 if (IS_ERR(em)) {
0496 test_err("got an error when we shouldn't have");
0497 goto out;
0498 }
0499 if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
0500 test_err("expected a real extent, got %llu", em->block_start);
0501 goto out;
0502 }
0503 if (em->start != offset || em->len != sectorsize) {
0504 test_err(
0505 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
0506 offset, sectorsize, em->start, em->len);
0507 goto out;
0508 }
0509 if (em->flags != prealloc_only) {
0510 test_err("unexpected flags set, want %lu have %lu",
0511 prealloc_only, em->flags);
0512 goto out;
0513 }
0514 if (em->orig_start != em->start) {
0515 test_err("wrong orig offset, want %llu, have %llu", em->start,
0516 em->orig_start);
0517 goto out;
0518 }
0519 disk_bytenr = em->block_start;
0520 orig_start = em->start;
0521 offset = em->start + em->len;
0522 free_extent_map(em);
0523
0524 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
0525 if (IS_ERR(em)) {
0526 test_err("got an error when we shouldn't have");
0527 goto out;
0528 }
0529 if (em->block_start >= EXTENT_MAP_HOLE) {
0530 test_err("expected a real extent, got %llu", em->block_start);
0531 goto out;
0532 }
0533 if (em->start != offset || em->len != sectorsize) {
0534 test_err(
0535 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
0536 offset, sectorsize, em->start, em->len);
0537 goto out;
0538 }
0539 if (em->flags != 0) {
0540 test_err("unexpected flags set, want 0 have %lu", em->flags);
0541 goto out;
0542 }
0543 if (em->orig_start != orig_start) {
0544 test_err("unexpected orig offset, wanted %llu, have %llu",
0545 orig_start, em->orig_start);
0546 goto out;
0547 }
0548 if (em->block_start != (disk_bytenr + (em->start - em->orig_start))) {
0549 test_err("unexpected block start, wanted %llu, have %llu",
0550 disk_bytenr + (em->start - em->orig_start),
0551 em->block_start);
0552 goto out;
0553 }
0554 offset = em->start + em->len;
0555 free_extent_map(em);
0556
0557 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
0558 if (IS_ERR(em)) {
0559 test_err("got an error when we shouldn't have");
0560 goto out;
0561 }
0562 if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
0563 test_err("expected a real extent, got %llu", em->block_start);
0564 goto out;
0565 }
0566 if (em->start != offset || em->len != 2 * sectorsize) {
0567 test_err(
0568 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
0569 offset, 2 * sectorsize, em->start, em->len);
0570 goto out;
0571 }
0572 if (em->flags != prealloc_only) {
0573 test_err("unexpected flags set, want %lu have %lu",
0574 prealloc_only, em->flags);
0575 goto out;
0576 }
0577 if (em->orig_start != orig_start) {
0578 test_err("wrong orig offset, want %llu, have %llu", orig_start,
0579 em->orig_start);
0580 goto out;
0581 }
0582 if (em->block_start != (disk_bytenr + (em->start - em->orig_start))) {
0583 test_err("unexpected block start, wanted %llu, have %llu",
0584 disk_bytenr + (em->start - em->orig_start),
0585 em->block_start);
0586 goto out;
0587 }
0588 offset = em->start + em->len;
0589 free_extent_map(em);
0590
0591
0592 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
0593 if (IS_ERR(em)) {
0594 test_err("got an error when we shouldn't have");
0595 goto out;
0596 }
0597 if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
0598 test_err("expected a real extent, got %llu", em->block_start);
0599 goto out;
0600 }
0601 if (em->start != offset || em->len != 2 * sectorsize) {
0602 test_err(
0603 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
0604 offset, 2 * sectorsize, em->start, em->len);
0605 goto out;
0606 }
0607 if (em->flags != compressed_only) {
0608 test_err("unexpected flags set, want %lu have %lu",
0609 compressed_only, em->flags);
0610 goto out;
0611 }
0612 if (em->orig_start != em->start) {
0613 test_err("wrong orig offset, want %llu, have %llu",
0614 em->start, em->orig_start);
0615 goto out;
0616 }
0617 if (em->compress_type != BTRFS_COMPRESS_ZLIB) {
0618 test_err("unexpected compress type, wanted %d, got %d",
0619 BTRFS_COMPRESS_ZLIB, em->compress_type);
0620 goto out;
0621 }
0622 offset = em->start + em->len;
0623 free_extent_map(em);
0624
0625
0626 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
0627 if (IS_ERR(em)) {
0628 test_err("got an error when we shouldn't have");
0629 goto out;
0630 }
0631 if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
0632 test_err("expected a real extent, got %llu", em->block_start);
0633 goto out;
0634 }
0635 if (em->start != offset || em->len != sectorsize) {
0636 test_err(
0637 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
0638 offset, sectorsize, em->start, em->len);
0639 goto out;
0640 }
0641 if (em->flags != compressed_only) {
0642 test_err("unexpected flags set, want %lu have %lu",
0643 compressed_only, em->flags);
0644 goto out;
0645 }
0646 if (em->orig_start != em->start) {
0647 test_err("wrong orig offset, want %llu, have %llu",
0648 em->start, em->orig_start);
0649 goto out;
0650 }
0651 if (em->compress_type != BTRFS_COMPRESS_ZLIB) {
0652 test_err("unexpected compress type, wanted %d, got %d",
0653 BTRFS_COMPRESS_ZLIB, em->compress_type);
0654 goto out;
0655 }
0656 disk_bytenr = em->block_start;
0657 orig_start = em->start;
0658 offset = em->start + em->len;
0659 free_extent_map(em);
0660
0661 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
0662 if (IS_ERR(em)) {
0663 test_err("got an error when we shouldn't have");
0664 goto out;
0665 }
0666 if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
0667 test_err("expected a real extent, got %llu", em->block_start);
0668 goto out;
0669 }
0670 if (em->start != offset || em->len != sectorsize) {
0671 test_err(
0672 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
0673 offset, sectorsize, em->start, em->len);
0674 goto out;
0675 }
0676 if (em->flags != 0) {
0677 test_err("unexpected flags set, want 0 have %lu", em->flags);
0678 goto out;
0679 }
0680 if (em->orig_start != em->start) {
0681 test_err("wrong orig offset, want %llu, have %llu", em->start,
0682 em->orig_start);
0683 goto out;
0684 }
0685 offset = em->start + em->len;
0686 free_extent_map(em);
0687
0688 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
0689 if (IS_ERR(em)) {
0690 test_err("got an error when we shouldn't have");
0691 goto out;
0692 }
0693 if (em->block_start != disk_bytenr) {
0694 test_err("block start does not match, want %llu got %llu",
0695 disk_bytenr, em->block_start);
0696 goto out;
0697 }
0698 if (em->start != offset || em->len != 2 * sectorsize) {
0699 test_err(
0700 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
0701 offset, 2 * sectorsize, em->start, em->len);
0702 goto out;
0703 }
0704 if (em->flags != compressed_only) {
0705 test_err("unexpected flags set, want %lu have %lu",
0706 compressed_only, em->flags);
0707 goto out;
0708 }
0709 if (em->orig_start != orig_start) {
0710 test_err("wrong orig offset, want %llu, have %llu",
0711 em->start, orig_start);
0712 goto out;
0713 }
0714 if (em->compress_type != BTRFS_COMPRESS_ZLIB) {
0715 test_err("unexpected compress type, wanted %d, got %d",
0716 BTRFS_COMPRESS_ZLIB, em->compress_type);
0717 goto out;
0718 }
0719 offset = em->start + em->len;
0720 free_extent_map(em);
0721
0722
0723 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset + 6, sectorsize);
0724 if (IS_ERR(em)) {
0725 test_err("got an error when we shouldn't have");
0726 goto out;
0727 }
0728 if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
0729 test_err("expected a real extent, got %llu", em->block_start);
0730 goto out;
0731 }
0732 if (em->start != offset || em->len != sectorsize) {
0733 test_err(
0734 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
0735 offset, sectorsize, em->start, em->len);
0736 goto out;
0737 }
0738 if (em->flags != 0) {
0739 test_err("unexpected flags set, want 0 have %lu", em->flags);
0740 goto out;
0741 }
0742 if (em->orig_start != em->start) {
0743 test_err("wrong orig offset, want %llu, have %llu", em->start,
0744 em->orig_start);
0745 goto out;
0746 }
0747 offset = em->start + em->len;
0748 free_extent_map(em);
0749
0750 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, SZ_4M);
0751 if (IS_ERR(em)) {
0752 test_err("got an error when we shouldn't have");
0753 goto out;
0754 }
0755 if (em->block_start != EXTENT_MAP_HOLE) {
0756 test_err("expected a hole extent, got %llu", em->block_start);
0757 goto out;
0758 }
0759
0760
0761
0762
0763
0764 if (em->start != offset || em->len != 3 * sectorsize) {
0765 test_err(
0766 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
0767 offset, 3 * sectorsize, em->start, em->len);
0768 goto out;
0769 }
0770 if (em->flags != vacancy_only) {
0771 test_err("unexpected flags set, want %lu have %lu",
0772 vacancy_only, em->flags);
0773 goto out;
0774 }
0775 if (em->orig_start != em->start) {
0776 test_err("wrong orig offset, want %llu, have %llu", em->start,
0777 em->orig_start);
0778 goto out;
0779 }
0780 offset = em->start + em->len;
0781 free_extent_map(em);
0782
0783 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
0784 if (IS_ERR(em)) {
0785 test_err("got an error when we shouldn't have");
0786 goto out;
0787 }
0788 if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
0789 test_err("expected a real extent, got %llu", em->block_start);
0790 goto out;
0791 }
0792 if (em->start != offset || em->len != sectorsize) {
0793 test_err(
0794 "unexpected extent wanted start %llu len %u, got start %llu len %llu",
0795 offset, sectorsize, em->start, em->len);
0796 goto out;
0797 }
0798 if (em->flags != 0) {
0799 test_err("unexpected flags set, want 0 have %lu", em->flags);
0800 goto out;
0801 }
0802 if (em->orig_start != em->start) {
0803 test_err("wrong orig offset, want %llu, have %llu", em->start,
0804 em->orig_start);
0805 goto out;
0806 }
0807 ret = 0;
0808 out:
0809 if (!IS_ERR(em))
0810 free_extent_map(em);
0811 iput(inode);
0812 btrfs_free_dummy_root(root);
0813 btrfs_free_dummy_fs_info(fs_info);
0814 return ret;
0815 }
0816
0817 static int test_hole_first(u32 sectorsize, u32 nodesize)
0818 {
0819 struct btrfs_fs_info *fs_info = NULL;
0820 struct inode *inode = NULL;
0821 struct btrfs_root *root = NULL;
0822 struct extent_map *em = NULL;
0823 int ret = -ENOMEM;
0824
0825 test_msg("running hole first btrfs_get_extent test");
0826
0827 inode = btrfs_new_test_inode();
0828 if (!inode) {
0829 test_std_err(TEST_ALLOC_INODE);
0830 return ret;
0831 }
0832
0833 fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
0834 if (!fs_info) {
0835 test_std_err(TEST_ALLOC_FS_INFO);
0836 goto out;
0837 }
0838
0839 root = btrfs_alloc_dummy_root(fs_info);
0840 if (IS_ERR(root)) {
0841 test_std_err(TEST_ALLOC_ROOT);
0842 goto out;
0843 }
0844
0845 root->node = alloc_dummy_extent_buffer(fs_info, nodesize);
0846 if (!root->node) {
0847 test_std_err(TEST_ALLOC_ROOT);
0848 goto out;
0849 }
0850
0851 btrfs_set_header_nritems(root->node, 0);
0852 btrfs_set_header_level(root->node, 0);
0853 BTRFS_I(inode)->root = root;
0854 ret = -EINVAL;
0855
0856
0857
0858
0859
0860 insert_inode_item_key(root);
0861 insert_extent(root, sectorsize, sectorsize, sectorsize, 0, sectorsize,
0862 sectorsize, BTRFS_FILE_EXTENT_REG, 0, 1);
0863 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, 0, 2 * sectorsize);
0864 if (IS_ERR(em)) {
0865 test_err("got an error when we shouldn't have");
0866 goto out;
0867 }
0868 if (em->block_start != EXTENT_MAP_HOLE) {
0869 test_err("expected a hole, got %llu", em->block_start);
0870 goto out;
0871 }
0872 if (em->start != 0 || em->len != sectorsize) {
0873 test_err(
0874 "unexpected extent wanted start 0 len %u, got start %llu len %llu",
0875 sectorsize, em->start, em->len);
0876 goto out;
0877 }
0878 if (em->flags != vacancy_only) {
0879 test_err("wrong flags, wanted %lu, have %lu", vacancy_only,
0880 em->flags);
0881 goto out;
0882 }
0883 free_extent_map(em);
0884
0885 em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, sectorsize, 2 * sectorsize);
0886 if (IS_ERR(em)) {
0887 test_err("got an error when we shouldn't have");
0888 goto out;
0889 }
0890 if (em->block_start != sectorsize) {
0891 test_err("expected a real extent, got %llu", em->block_start);
0892 goto out;
0893 }
0894 if (em->start != sectorsize || em->len != sectorsize) {
0895 test_err(
0896 "unexpected extent wanted start %u len %u, got start %llu len %llu",
0897 sectorsize, sectorsize, em->start, em->len);
0898 goto out;
0899 }
0900 if (em->flags != 0) {
0901 test_err("unexpected flags set, wanted 0 got %lu",
0902 em->flags);
0903 goto out;
0904 }
0905 ret = 0;
0906 out:
0907 if (!IS_ERR(em))
0908 free_extent_map(em);
0909 iput(inode);
0910 btrfs_free_dummy_root(root);
0911 btrfs_free_dummy_fs_info(fs_info);
0912 return ret;
0913 }
0914
0915 static int test_extent_accounting(u32 sectorsize, u32 nodesize)
0916 {
0917 struct btrfs_fs_info *fs_info = NULL;
0918 struct inode *inode = NULL;
0919 struct btrfs_root *root = NULL;
0920 int ret = -ENOMEM;
0921
0922 test_msg("running outstanding_extents tests");
0923
0924 inode = btrfs_new_test_inode();
0925 if (!inode) {
0926 test_std_err(TEST_ALLOC_INODE);
0927 return ret;
0928 }
0929
0930 fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
0931 if (!fs_info) {
0932 test_std_err(TEST_ALLOC_FS_INFO);
0933 goto out;
0934 }
0935
0936 root = btrfs_alloc_dummy_root(fs_info);
0937 if (IS_ERR(root)) {
0938 test_std_err(TEST_ALLOC_ROOT);
0939 goto out;
0940 }
0941
0942 BTRFS_I(inode)->root = root;
0943
0944
0945 ret = btrfs_set_extent_delalloc(BTRFS_I(inode), 0,
0946 BTRFS_MAX_EXTENT_SIZE - 1, 0, NULL);
0947 if (ret) {
0948 test_err("btrfs_set_extent_delalloc returned %d", ret);
0949 goto out;
0950 }
0951 if (BTRFS_I(inode)->outstanding_extents != 1) {
0952 ret = -EINVAL;
0953 test_err("miscount, wanted 1, got %u",
0954 BTRFS_I(inode)->outstanding_extents);
0955 goto out;
0956 }
0957
0958
0959 ret = btrfs_set_extent_delalloc(BTRFS_I(inode), BTRFS_MAX_EXTENT_SIZE,
0960 BTRFS_MAX_EXTENT_SIZE + sectorsize - 1,
0961 0, NULL);
0962 if (ret) {
0963 test_err("btrfs_set_extent_delalloc returned %d", ret);
0964 goto out;
0965 }
0966 if (BTRFS_I(inode)->outstanding_extents != 2) {
0967 ret = -EINVAL;
0968 test_err("miscount, wanted 2, got %u",
0969 BTRFS_I(inode)->outstanding_extents);
0970 goto out;
0971 }
0972
0973
0974 ret = clear_extent_bit(&BTRFS_I(inode)->io_tree,
0975 BTRFS_MAX_EXTENT_SIZE >> 1,
0976 (BTRFS_MAX_EXTENT_SIZE >> 1) + sectorsize - 1,
0977 EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
0978 EXTENT_UPTODATE, 0, 0, NULL);
0979 if (ret) {
0980 test_err("clear_extent_bit returned %d", ret);
0981 goto out;
0982 }
0983 if (BTRFS_I(inode)->outstanding_extents != 2) {
0984 ret = -EINVAL;
0985 test_err("miscount, wanted 2, got %u",
0986 BTRFS_I(inode)->outstanding_extents);
0987 goto out;
0988 }
0989
0990
0991 ret = btrfs_set_extent_delalloc(BTRFS_I(inode), BTRFS_MAX_EXTENT_SIZE >> 1,
0992 (BTRFS_MAX_EXTENT_SIZE >> 1)
0993 + sectorsize - 1,
0994 0, NULL);
0995 if (ret) {
0996 test_err("btrfs_set_extent_delalloc returned %d", ret);
0997 goto out;
0998 }
0999 if (BTRFS_I(inode)->outstanding_extents != 2) {
1000 ret = -EINVAL;
1001 test_err("miscount, wanted 2, got %u",
1002 BTRFS_I(inode)->outstanding_extents);
1003 goto out;
1004 }
1005
1006
1007
1008
1009 ret = btrfs_set_extent_delalloc(BTRFS_I(inode),
1010 BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize,
1011 (BTRFS_MAX_EXTENT_SIZE << 1) + 3 * sectorsize - 1,
1012 0, NULL);
1013 if (ret) {
1014 test_err("btrfs_set_extent_delalloc returned %d", ret);
1015 goto out;
1016 }
1017 if (BTRFS_I(inode)->outstanding_extents != 4) {
1018 ret = -EINVAL;
1019 test_err("miscount, wanted 4, got %u",
1020 BTRFS_I(inode)->outstanding_extents);
1021 goto out;
1022 }
1023
1024
1025
1026
1027 ret = btrfs_set_extent_delalloc(BTRFS_I(inode),
1028 BTRFS_MAX_EXTENT_SIZE + sectorsize,
1029 BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, 0, NULL);
1030 if (ret) {
1031 test_err("btrfs_set_extent_delalloc returned %d", ret);
1032 goto out;
1033 }
1034 if (BTRFS_I(inode)->outstanding_extents != 3) {
1035 ret = -EINVAL;
1036 test_err("miscount, wanted 3, got %u",
1037 BTRFS_I(inode)->outstanding_extents);
1038 goto out;
1039 }
1040
1041
1042 ret = clear_extent_bit(&BTRFS_I(inode)->io_tree,
1043 BTRFS_MAX_EXTENT_SIZE + sectorsize,
1044 BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1,
1045 EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
1046 EXTENT_UPTODATE, 0, 0, NULL);
1047 if (ret) {
1048 test_err("clear_extent_bit returned %d", ret);
1049 goto out;
1050 }
1051 if (BTRFS_I(inode)->outstanding_extents != 4) {
1052 ret = -EINVAL;
1053 test_err("miscount, wanted 4, got %u",
1054 BTRFS_I(inode)->outstanding_extents);
1055 goto out;
1056 }
1057
1058
1059
1060
1061
1062 ret = btrfs_set_extent_delalloc(BTRFS_I(inode),
1063 BTRFS_MAX_EXTENT_SIZE + sectorsize,
1064 BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, 0, NULL);
1065 if (ret) {
1066 test_err("btrfs_set_extent_delalloc returned %d", ret);
1067 goto out;
1068 }
1069 if (BTRFS_I(inode)->outstanding_extents != 3) {
1070 ret = -EINVAL;
1071 test_err("miscount, wanted 3, got %u",
1072 BTRFS_I(inode)->outstanding_extents);
1073 goto out;
1074 }
1075
1076
1077 ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1,
1078 EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
1079 EXTENT_UPTODATE, 0, 0, NULL);
1080 if (ret) {
1081 test_err("clear_extent_bit returned %d", ret);
1082 goto out;
1083 }
1084 if (BTRFS_I(inode)->outstanding_extents) {
1085 ret = -EINVAL;
1086 test_err("miscount, wanted 0, got %u",
1087 BTRFS_I(inode)->outstanding_extents);
1088 goto out;
1089 }
1090 ret = 0;
1091 out:
1092 if (ret)
1093 clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1,
1094 EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
1095 EXTENT_UPTODATE, 0, 0, NULL);
1096 iput(inode);
1097 btrfs_free_dummy_root(root);
1098 btrfs_free_dummy_fs_info(fs_info);
1099 return ret;
1100 }
1101
1102 int btrfs_test_inodes(u32 sectorsize, u32 nodesize)
1103 {
1104 int ret;
1105
1106 test_msg("running inode tests");
1107
1108 set_bit(EXTENT_FLAG_COMPRESSED, &compressed_only);
1109 set_bit(EXTENT_FLAG_PREALLOC, &prealloc_only);
1110
1111 ret = test_btrfs_get_extent(sectorsize, nodesize);
1112 if (ret)
1113 return ret;
1114 ret = test_hole_first(sectorsize, nodesize);
1115 if (ret)
1116 return ret;
1117 return test_extent_accounting(sectorsize, nodesize);
1118 }