cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

inode-tests.c (32015B)


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