/* * Passing a NULL trans handle is fine here, we have a dummy root eb * and the tree is a single node (level 0).
*/
btrfs_setup_item_for_insert(NULL, root, &path, &key, value_len);
fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
btrfs_set_file_extent_generation(leaf, fi, 1);
btrfs_set_file_extent_type(leaf, fi, type);
btrfs_set_file_extent_disk_bytenr(leaf, fi, disk_bytenr);
btrfs_set_file_extent_disk_num_bytes(leaf, fi, disk_len);
btrfs_set_file_extent_offset(leaf, fi, offset);
btrfs_set_file_extent_num_bytes(leaf, fi, len);
btrfs_set_file_extent_ram_bytes(leaf, fi, ram_bytes);
btrfs_set_file_extent_compression(leaf, fi, compression);
btrfs_set_file_extent_encryption(leaf, fi, 0);
btrfs_set_file_extent_other_encoding(leaf, fi, 0);
}
/* * Passing a NULL trans handle is fine here, we have a dummy root eb * and the tree is a single node (level 0).
*/
btrfs_setup_item_for_insert(NULL, root, &path, &key, value_len);
}
/* * Build the most complicated map of extents the earth has ever seen. We want * this so we can test all of the corner cases of btrfs_get_extent. Here is a * diagram of how the extents will look though this may not be possible we still * want to make sure everything acts normally (the last number is not inclusive) * * [0 - 6][ 6 - 4096 ][ 4096 - 4100][4100 - 8195][8195 - 12291] * [inline][hole but no extent][ hole ][ regular ][regular1 split] * * [12291 - 16387][16387 - 24579][24579 - 28675][ 28675 - 32771][32771 - 36867 ] * [ hole ][regular1 split][ prealloc ][ prealloc1 ][prealloc1 written] * * [36867 - 45059][45059 - 53251][53251 - 57347][57347 - 61443][61443- 69635] * [ prealloc1 ][ compressed ][ compressed1 ][ regular ][ compressed1] * * [69635-73731][ 73731 - 86019 ][86019-90115] * [ regular ][ hole but no extent][ regular ]
*/ staticvoid setup_file_extents(struct btrfs_root *root, u32 sectorsize)
{ int slot = 0;
u64 disk_bytenr = SZ_1M;
u64 offset = 0;
/* * Tree-checker has strict limits on inline extents that they can only * exist at file offset 0, thus we can only have one inline file extent * at most.
*/
insert_extent(root, offset, 6, 6, 0, 0, 0, BTRFS_FILE_EXTENT_INLINE, 0,
slot);
slot++;
offset = sectorsize;
/* Now another hole */
insert_extent(root, offset, 4, 4, 0, 0, 0, BTRFS_FILE_EXTENT_REG, 0,
slot);
slot++;
offset += 4;
btrfs_set_header_nritems(root->node, 0);
btrfs_set_header_level(root->node, 0);
ret = -EINVAL;
/* First with no extents */
BTRFS_I(inode)->root = root;
em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, sectorsize); if (IS_ERR(em)) {
em = NULL;
test_err("got an error when we shouldn't have"); goto out;
} if (em->disk_bytenr != EXTENT_MAP_HOLE) {
test_err("expected a hole, got %llu", em->disk_bytenr); goto out;
}
btrfs_free_extent_map(em);
btrfs_drop_extent_map_range(BTRFS_I(inode), 0, (u64)-1, false);
/* * All of the magic numbers are based on the mapping setup in * setup_file_extents, so if you change anything there you need to * update the comment and update the expected values below.
*/
setup_file_extents(root, sectorsize);
em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, (u64)-1); if (IS_ERR(em)) {
test_err("got an error when we shouldn't have"); goto out;
} if (em->disk_bytenr != EXTENT_MAP_INLINE) {
test_err("expected an inline, got %llu", em->disk_bytenr); goto out;
}
/* * For inline extent, we always round up the em to sectorsize, as * they are either: * * a) a hidden hole * The range will be zeroed at inline extent read time. * * b) a file extent with unaligned bytenr * Tree checker will reject it.
*/ if (em->start != 0 || em->len != sectorsize) {
test_err( "unexpected extent wanted start 0 len %u, got start %llu len %llu",
sectorsize, em->start, em->len); goto out;
} if (em->flags != 0) {
test_err("unexpected flags set, want 0 have %u", em->flags); goto out;
} /* * We don't test anything else for inline since it doesn't get set * unless we have a page for it to write into. Maybe we should change * this?
*/
offset = em->start + em->len;
btrfs_free_extent_map(em);
em = btrfs_get_extent(BTRFS_I(inode), NULL, offset, sectorsize); if (IS_ERR(em)) {
test_err("got an error when we shouldn't have"); goto out;
} if (em->disk_bytenr != EXTENT_MAP_HOLE) {
test_err("expected a hole, got %llu", em->disk_bytenr); goto out;
} if (em->start != offset || em->len != 4) {
test_err( "unexpected extent wanted start %llu len 4, got start %llu len %llu",
offset, em->start, em->len); goto out;
} if (em->flags != 0) {
test_err("unexpected flags set, want 0 have %u", em->flags); goto out;
}
offset = em->start + em->len;
btrfs_free_extent_map(em);
/* Regular extent */
em = btrfs_get_extent(BTRFS_I(inode), NULL, offset, sectorsize); if (IS_ERR(em)) {
test_err("got an error when we shouldn't have"); goto out;
} if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
test_err("expected a real extent, got %llu", em->disk_bytenr); goto out;
} if (em->start != offset || em->len != sectorsize - 1) {
test_err( "unexpected extent wanted start %llu len 4095, got start %llu len %llu",
offset, em->start, em->len); goto out;
} if (em->flags != 0) {
test_err("unexpected flags set, want 0 have %u", em->flags); goto out;
} if (em->offset != 0) {
test_err("wrong offset, want 0, have %llu", em->offset); goto out;
}
offset = em->start + em->len;
btrfs_free_extent_map(em);
/* The next 3 are split extents */
em = btrfs_get_extent(BTRFS_I(inode), NULL, offset, sectorsize); if (IS_ERR(em)) {
test_err("got an error when we shouldn't have"); goto out;
} if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
test_err("expected a real extent, got %llu", em->disk_bytenr); goto out;
} if (em->start != offset || em->len != sectorsize) {
test_err( "unexpected extent start %llu len %u, got start %llu len %llu",
offset, sectorsize, em->start, em->len); goto out;
} if (em->flags != 0) {
test_err("unexpected flags set, want 0 have %u", em->flags); goto out;
} if (em->offset != 0) {
test_err("wrong offset, want 0, have %llu", em->offset); goto out;
}
disk_bytenr = btrfs_extent_map_block_start(em);
orig_start = em->start;
offset = em->start + em->len;
btrfs_free_extent_map(em);
em = btrfs_get_extent(BTRFS_I(inode), NULL, offset, sectorsize); if (IS_ERR(em)) {
test_err("got an error when we shouldn't have"); goto out;
} if (em->disk_bytenr != EXTENT_MAP_HOLE) {
test_err("expected a hole, got %llu", em->disk_bytenr); goto out;
} if (em->start != offset || em->len != sectorsize) {
test_err( "unexpected extent wanted start %llu len %u, got start %llu len %llu",
offset, sectorsize, em->start, em->len); goto out;
} if (em->flags != 0) {
test_err("unexpected flags set, want 0 have %u", em->flags); goto out;
}
offset = em->start + em->len;
btrfs_free_extent_map(em);
em = btrfs_get_extent(BTRFS_I(inode), NULL, offset, sectorsize); if (IS_ERR(em)) {
test_err("got an error when we shouldn't have"); goto out;
} if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
test_err("expected a real extent, got %llu", em->disk_bytenr); goto out;
} if (em->start != offset || em->len != 2 * sectorsize) {
test_err( "unexpected extent wanted start %llu len %u, got start %llu len %llu",
offset, 2 * sectorsize, em->start, em->len); goto out;
} if (em->flags != 0) {
test_err("unexpected flags set, want 0 have %u", em->flags); goto out;
} if (em->start - em->offset != orig_start) {
test_err("wrong offset, em->start=%llu em->offset=%llu orig_start=%llu",
em->start, em->offset, orig_start); goto out;
}
disk_bytenr += (em->start - orig_start); if (btrfs_extent_map_block_start(em) != disk_bytenr) {
test_err("wrong block start, want %llu, have %llu",
disk_bytenr, btrfs_extent_map_block_start(em)); goto out;
}
offset = em->start + em->len;
btrfs_free_extent_map(em);
/* Prealloc extent */
em = btrfs_get_extent(BTRFS_I(inode), NULL, offset, sectorsize); if (IS_ERR(em)) {
test_err("got an error when we shouldn't have"); goto out;
} if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
test_err("expected a real extent, got %llu", em->disk_bytenr); goto out;
} if (em->start != offset || em->len != sectorsize) {
test_err( "unexpected extent wanted start %llu len %u, got start %llu len %llu",
offset, sectorsize, em->start, em->len); goto out;
} if (em->flags != prealloc_only) {
test_err("unexpected flags set, want %u have %u",
prealloc_only, em->flags); goto out;
} if (em->offset != 0) {
test_err("wrong offset, want 0, have %llu", em->offset); goto out;
}
offset = em->start + em->len;
btrfs_free_extent_map(em);
/* The next 3 are a half written prealloc extent */
em = btrfs_get_extent(BTRFS_I(inode), NULL, offset, sectorsize); if (IS_ERR(em)) {
test_err("got an error when we shouldn't have"); goto out;
} if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
test_err("expected a real extent, got %llu", em->disk_bytenr); goto out;
} if (em->start != offset || em->len != sectorsize) {
test_err( "unexpected extent wanted start %llu len %u, got start %llu len %llu",
offset, sectorsize, em->start, em->len); goto out;
} if (em->flags != prealloc_only) {
test_err("unexpected flags set, want %u have %u",
prealloc_only, em->flags); goto out;
} if (em->offset != 0) {
test_err("wrong offset, want 0, have %llu", em->offset); goto out;
}
disk_bytenr = btrfs_extent_map_block_start(em);
orig_start = em->start;
offset = em->start + em->len;
btrfs_free_extent_map(em);
em = btrfs_get_extent(BTRFS_I(inode), NULL, offset, sectorsize); if (IS_ERR(em)) {
test_err("got an error when we shouldn't have"); goto out;
} if (em->disk_bytenr >= EXTENT_MAP_HOLE) {
test_err("expected a real extent, got %llu", em->disk_bytenr); goto out;
} if (em->start != offset || em->len != sectorsize) {
test_err( "unexpected extent wanted start %llu len %u, got start %llu len %llu",
offset, sectorsize, em->start, em->len); goto out;
} if (em->flags != 0) {
test_err("unexpected flags set, want 0 have %u", em->flags); goto out;
} if (em->start - em->offset != orig_start) {
test_err("unexpected offset, wanted %llu, have %llu",
em->start - orig_start, em->offset); goto out;
} if (btrfs_extent_map_block_start(em) != disk_bytenr + em->offset) {
test_err("unexpected block start, wanted %llu, have %llu",
disk_bytenr + em->offset, btrfs_extent_map_block_start(em)); goto out;
}
offset = em->start + em->len;
btrfs_free_extent_map(em);
em = btrfs_get_extent(BTRFS_I(inode), NULL, offset, sectorsize); if (IS_ERR(em)) {
test_err("got an error when we shouldn't have"); goto out;
} if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
test_err("expected a real extent, got %llu", em->disk_bytenr); goto out;
} if (em->start != offset || em->len != 2 * sectorsize) {
test_err( "unexpected extent wanted start %llu len %u, got start %llu len %llu",
offset, 2 * sectorsize, em->start, em->len); goto out;
} if (em->flags != prealloc_only) {
test_err("unexpected flags set, want %u have %u",
prealloc_only, em->flags); goto out;
} if (em->start - em->offset != orig_start) {
test_err("wrong offset, em->start=%llu em->offset=%llu orig_start=%llu",
em->start, em->offset, orig_start); goto out;
} if (btrfs_extent_map_block_start(em) != disk_bytenr + em->offset) {
test_err("unexpected block start, wanted %llu, have %llu",
disk_bytenr + em->offset, btrfs_extent_map_block_start(em)); goto out;
}
offset = em->start + em->len;
btrfs_free_extent_map(em);
/* Now for the compressed extent */
em = btrfs_get_extent(BTRFS_I(inode), NULL, offset, sectorsize); if (IS_ERR(em)) {
test_err("got an error when we shouldn't have"); goto out;
} if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
test_err("expected a real extent, got %llu", em->disk_bytenr); goto out;
} if (em->start != offset || em->len != 2 * sectorsize) {
test_err( "unexpected extent wanted start %llu len %u, got start %llu len %llu",
offset, 2 * sectorsize, em->start, em->len); goto out;
} if (em->flags != compressed_only) {
test_err("unexpected flags set, want %u have %u",
compressed_only, em->flags); goto out;
} if (em->offset != 0) {
test_err("wrong offset, want 0, have %llu", em->offset); goto out;
} if (btrfs_extent_map_compression(em) != BTRFS_COMPRESS_ZLIB) {
test_err("unexpected compress type, wanted %d, got %d",
BTRFS_COMPRESS_ZLIB, btrfs_extent_map_compression(em)); goto out;
}
offset = em->start + em->len;
btrfs_free_extent_map(em);
/* Split compressed extent */
em = btrfs_get_extent(BTRFS_I(inode), NULL, offset, sectorsize); if (IS_ERR(em)) {
test_err("got an error when we shouldn't have"); goto out;
} if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
test_err("expected a real extent, got %llu", em->disk_bytenr); goto out;
} if (em->start != offset || em->len != sectorsize) {
test_err( "unexpected extent wanted start %llu len %u, got start %llu len %llu",
offset, sectorsize, em->start, em->len); goto out;
} if (em->flags != compressed_only) {
test_err("unexpected flags set, want %u have %u",
compressed_only, em->flags); goto out;
} if (em->offset != 0) {
test_err("wrong offset, want 0, have %llu", em->offset); goto out;
} if (btrfs_extent_map_compression(em) != BTRFS_COMPRESS_ZLIB) {
test_err("unexpected compress type, wanted %d, got %d",
BTRFS_COMPRESS_ZLIB, btrfs_extent_map_compression(em)); goto out;
}
disk_bytenr = btrfs_extent_map_block_start(em);
orig_start = em->start;
offset = em->start + em->len;
btrfs_free_extent_map(em);
em = btrfs_get_extent(BTRFS_I(inode), NULL, offset, sectorsize); if (IS_ERR(em)) {
test_err("got an error when we shouldn't have"); goto out;
} if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
test_err("expected a real extent, got %llu", em->disk_bytenr); goto out;
} if (em->start != offset || em->len != sectorsize) {
test_err( "unexpected extent wanted start %llu len %u, got start %llu len %llu",
offset, sectorsize, em->start, em->len); goto out;
} if (em->flags != 0) {
test_err("unexpected flags set, want 0 have %u", em->flags); goto out;
} if (em->offset != 0) {
test_err("wrong offset, want 0, have %llu", em->offset); goto out;
}
offset = em->start + em->len;
btrfs_free_extent_map(em);
em = btrfs_get_extent(BTRFS_I(inode), NULL, offset, sectorsize); if (IS_ERR(em)) {
test_err("got an error when we shouldn't have"); goto out;
} if (btrfs_extent_map_block_start(em) != disk_bytenr) {
test_err("block start does not match, want %llu got %llu",
disk_bytenr, btrfs_extent_map_block_start(em)); goto out;
} if (em->start != offset || em->len != 2 * sectorsize) {
test_err( "unexpected extent wanted start %llu len %u, got start %llu len %llu",
offset, 2 * sectorsize, em->start, em->len); goto out;
} if (em->flags != compressed_only) {
test_err("unexpected flags set, want %u have %u",
compressed_only, em->flags); goto out;
} if (em->start - em->offset != orig_start) {
test_err("wrong offset, em->start=%llu em->offset=%llu orig_start=%llu",
em->start, em->offset, orig_start); goto out;
} if (btrfs_extent_map_compression(em) != BTRFS_COMPRESS_ZLIB) {
test_err("unexpected compress type, wanted %d, got %d",
BTRFS_COMPRESS_ZLIB, btrfs_extent_map_compression(em)); goto out;
}
offset = em->start + em->len;
btrfs_free_extent_map(em);
/* A hole between regular extents but no hole extent */
em = btrfs_get_extent(BTRFS_I(inode), NULL, offset + 6, sectorsize); if (IS_ERR(em)) {
test_err("got an error when we shouldn't have"); goto out;
} if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
test_err("expected a real extent, got %llu", em->disk_bytenr); goto out;
} if (em->start != offset || em->len != sectorsize) {
test_err( "unexpected extent wanted start %llu len %u, got start %llu len %llu",
offset, sectorsize, em->start, em->len); goto out;
} if (em->flags != 0) {
test_err("unexpected flags set, want 0 have %u", em->flags); goto out;
} if (em->offset != 0) {
test_err("wrong offset, want 0, have %llu", em->offset); goto out;
}
offset = em->start + em->len;
btrfs_free_extent_map(em);
em = btrfs_get_extent(BTRFS_I(inode), NULL, offset, SZ_4M); if (IS_ERR(em)) {
test_err("got an error when we shouldn't have"); goto out;
} if (em->disk_bytenr != EXTENT_MAP_HOLE) {
test_err("expected a hole extent, got %llu", em->disk_bytenr); goto out;
} /* * Currently we just return a length that we requested rather than the * length of the actual hole, if this changes we'll have to change this * test.
*/ if (em->start != offset || em->len != 3 * sectorsize) {
test_err( "unexpected extent wanted start %llu len %u, got start %llu len %llu",
offset, 3 * sectorsize, em->start, em->len); goto out;
} if (em->flags != vacancy_only) {
test_err("unexpected flags set, want %u have %u",
vacancy_only, em->flags); goto out;
} if (em->offset != 0) {
test_err("wrong offset, want 0, have %llu", em->offset); goto out;
}
offset = em->start + em->len;
btrfs_free_extent_map(em);
em = btrfs_get_extent(BTRFS_I(inode), NULL, offset, sectorsize); if (IS_ERR(em)) {
test_err("got an error when we shouldn't have"); goto out;
} if (em->disk_bytenr >= EXTENT_MAP_LAST_BYTE) {
test_err("expected a real extent, got %llu", em->disk_bytenr); goto out;
} if (em->start != offset || em->len != sectorsize) {
test_err( "unexpected extent wanted start %llu len %u, got start %llu len %llu",
offset, sectorsize, em->start, em->len); goto out;
} if (em->flags != 0) {
test_err("unexpected flags set, want 0 have %u", em->flags); goto out;
} if (em->offset != 0) {
test_err("wrong orig offset, want 0, have %llu", em->offset); goto out;
}
ret = 0;
out: if (!IS_ERR(em))
btrfs_free_extent_map(em);
iput(inode);
btrfs_free_dummy_root(root);
btrfs_free_dummy_fs_info(fs_info); return ret;
}
/* * [BTRFS_MAX_EXTENT_SIZE+sectorsize][sectorsize][BTRFS_MAX_EXTENT_SIZE+sectorsize]
*/
ret = btrfs_set_extent_delalloc(BTRFS_I(inode),
BTRFS_MAX_EXTENT_SIZE + sectorsize,
BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, 0, NULL); if (ret) {
test_err("btrfs_set_extent_delalloc returned %d", ret); goto out;
} if (BTRFS_I(inode)->outstanding_extents != 3) {
ret = -EINVAL;
test_err("miscount, wanted 3, got %u",
BTRFS_I(inode)->outstanding_extents); goto out;
}
/* [BTRFS_MAX_EXTENT_SIZE+4k][4K HOLE][BTRFS_MAX_EXTENT_SIZE+4k] */
ret = btrfs_clear_extent_bit(&BTRFS_I(inode)->io_tree,
BTRFS_MAX_EXTENT_SIZE + sectorsize,
BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1,
EXTENT_DELALLOC | EXTENT_DELALLOC_NEW, NULL); if (ret) {
test_err("clear_extent_bit returned %d", ret); goto out;
} if (BTRFS_I(inode)->outstanding_extents != 4) {
ret = -EINVAL;
test_err("miscount, wanted 4, got %u",
BTRFS_I(inode)->outstanding_extents); goto out;
}
/* * Refill the hole again just for good measure, because I thought it * might fail and I'd rather satisfy my paranoia at this point.
*/
ret = btrfs_set_extent_delalloc(BTRFS_I(inode),
BTRFS_MAX_EXTENT_SIZE + sectorsize,
BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, 0, NULL); if (ret) {
test_err("btrfs_set_extent_delalloc returned %d", ret); goto out;
} if (BTRFS_I(inode)->outstanding_extents != 3) {
ret = -EINVAL;
test_err("miscount, wanted 3, got %u",
BTRFS_I(inode)->outstanding_extents); goto out;
}
/* Empty */
ret = btrfs_clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1,
EXTENT_DELALLOC | EXTENT_DELALLOC_NEW, NULL); if (ret) {
test_err("clear_extent_bit returned %d", ret); goto out;
} if (BTRFS_I(inode)->outstanding_extents) {
ret = -EINVAL;
test_err("miscount, wanted 0, got %u",
BTRFS_I(inode)->outstanding_extents); goto out;
}
ret = 0;
out: if (ret)
btrfs_clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1,
EXTENT_DELALLOC | EXTENT_DELALLOC_NEW, NULL);
iput(inode);
btrfs_free_dummy_root(root);
btrfs_free_dummy_fs_info(fs_info); return ret;
}
int btrfs_test_inodes(u32 sectorsize, u32 nodesize)
{ int ret;
ret = test_btrfs_get_extent(sectorsize, nodesize); if (ret) return ret;
ret = test_hole_first(sectorsize, nodesize); if (ret) return ret; return test_extent_accounting(sectorsize, nodesize);
}
Messung V0.5
¤ Dauer der Verarbeitung: 0.13 Sekunden
(vorverarbeitet)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.