18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2013 Fusion IO.  All rights reserved.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/types.h>
78c2ecf20Sopenharmony_ci#include "btrfs-tests.h"
88c2ecf20Sopenharmony_ci#include "../ctree.h"
98c2ecf20Sopenharmony_ci#include "../btrfs_inode.h"
108c2ecf20Sopenharmony_ci#include "../disk-io.h"
118c2ecf20Sopenharmony_ci#include "../extent_io.h"
128c2ecf20Sopenharmony_ci#include "../volumes.h"
138c2ecf20Sopenharmony_ci#include "../compression.h"
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_cistatic void insert_extent(struct btrfs_root *root, u64 start, u64 len,
168c2ecf20Sopenharmony_ci			  u64 ram_bytes, u64 offset, u64 disk_bytenr,
178c2ecf20Sopenharmony_ci			  u64 disk_len, u32 type, u8 compression, int slot)
188c2ecf20Sopenharmony_ci{
198c2ecf20Sopenharmony_ci	struct btrfs_path path;
208c2ecf20Sopenharmony_ci	struct btrfs_file_extent_item *fi;
218c2ecf20Sopenharmony_ci	struct extent_buffer *leaf = root->node;
228c2ecf20Sopenharmony_ci	struct btrfs_key key;
238c2ecf20Sopenharmony_ci	u32 value_len = sizeof(struct btrfs_file_extent_item);
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_ci	if (type == BTRFS_FILE_EXTENT_INLINE)
268c2ecf20Sopenharmony_ci		value_len += len;
278c2ecf20Sopenharmony_ci	memset(&path, 0, sizeof(path));
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci	path.nodes[0] = leaf;
308c2ecf20Sopenharmony_ci	path.slots[0] = slot;
318c2ecf20Sopenharmony_ci
328c2ecf20Sopenharmony_ci	key.objectid = BTRFS_FIRST_FREE_OBJECTID;
338c2ecf20Sopenharmony_ci	key.type = BTRFS_EXTENT_DATA_KEY;
348c2ecf20Sopenharmony_ci	key.offset = start;
358c2ecf20Sopenharmony_ci
368c2ecf20Sopenharmony_ci	setup_items_for_insert(root, &path, &key, &value_len, 1);
378c2ecf20Sopenharmony_ci	fi = btrfs_item_ptr(leaf, slot, struct btrfs_file_extent_item);
388c2ecf20Sopenharmony_ci	btrfs_set_file_extent_generation(leaf, fi, 1);
398c2ecf20Sopenharmony_ci	btrfs_set_file_extent_type(leaf, fi, type);
408c2ecf20Sopenharmony_ci	btrfs_set_file_extent_disk_bytenr(leaf, fi, disk_bytenr);
418c2ecf20Sopenharmony_ci	btrfs_set_file_extent_disk_num_bytes(leaf, fi, disk_len);
428c2ecf20Sopenharmony_ci	btrfs_set_file_extent_offset(leaf, fi, offset);
438c2ecf20Sopenharmony_ci	btrfs_set_file_extent_num_bytes(leaf, fi, len);
448c2ecf20Sopenharmony_ci	btrfs_set_file_extent_ram_bytes(leaf, fi, ram_bytes);
458c2ecf20Sopenharmony_ci	btrfs_set_file_extent_compression(leaf, fi, compression);
468c2ecf20Sopenharmony_ci	btrfs_set_file_extent_encryption(leaf, fi, 0);
478c2ecf20Sopenharmony_ci	btrfs_set_file_extent_other_encoding(leaf, fi, 0);
488c2ecf20Sopenharmony_ci}
498c2ecf20Sopenharmony_ci
508c2ecf20Sopenharmony_cistatic void insert_inode_item_key(struct btrfs_root *root)
518c2ecf20Sopenharmony_ci{
528c2ecf20Sopenharmony_ci	struct btrfs_path path;
538c2ecf20Sopenharmony_ci	struct extent_buffer *leaf = root->node;
548c2ecf20Sopenharmony_ci	struct btrfs_key key;
558c2ecf20Sopenharmony_ci	u32 value_len = 0;
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_ci	memset(&path, 0, sizeof(path));
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci	path.nodes[0] = leaf;
608c2ecf20Sopenharmony_ci	path.slots[0] = 0;
618c2ecf20Sopenharmony_ci
628c2ecf20Sopenharmony_ci	key.objectid = BTRFS_INODE_ITEM_KEY;
638c2ecf20Sopenharmony_ci	key.type = BTRFS_INODE_ITEM_KEY;
648c2ecf20Sopenharmony_ci	key.offset = 0;
658c2ecf20Sopenharmony_ci
668c2ecf20Sopenharmony_ci	setup_items_for_insert(root, &path, &key, &value_len, 1);
678c2ecf20Sopenharmony_ci}
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_ci/*
708c2ecf20Sopenharmony_ci * Build the most complicated map of extents the earth has ever seen.  We want
718c2ecf20Sopenharmony_ci * this so we can test all of the corner cases of btrfs_get_extent.  Here is a
728c2ecf20Sopenharmony_ci * diagram of how the extents will look though this may not be possible we still
738c2ecf20Sopenharmony_ci * want to make sure everything acts normally (the last number is not inclusive)
748c2ecf20Sopenharmony_ci *
758c2ecf20Sopenharmony_ci * [0 - 5][5 -  6][     6 - 4096     ][ 4096 - 4100][4100 - 8195][8195 - 12291]
768c2ecf20Sopenharmony_ci * [hole ][inline][hole but no extent][  hole   ][   regular ][regular1 split]
778c2ecf20Sopenharmony_ci *
788c2ecf20Sopenharmony_ci * [12291 - 16387][16387 - 24579][24579 - 28675][ 28675 - 32771][32771 - 36867 ]
798c2ecf20Sopenharmony_ci * [    hole    ][regular1 split][   prealloc ][   prealloc1  ][prealloc1 written]
808c2ecf20Sopenharmony_ci *
818c2ecf20Sopenharmony_ci * [36867 - 45059][45059 - 53251][53251 - 57347][57347 - 61443][61443- 69635]
828c2ecf20Sopenharmony_ci * [  prealloc1  ][ compressed  ][ compressed1 ][    regular  ][ compressed1]
838c2ecf20Sopenharmony_ci *
848c2ecf20Sopenharmony_ci * [69635-73731][   73731 - 86019   ][86019-90115]
858c2ecf20Sopenharmony_ci * [  regular  ][ hole but no extent][  regular  ]
868c2ecf20Sopenharmony_ci */
878c2ecf20Sopenharmony_cistatic void setup_file_extents(struct btrfs_root *root, u32 sectorsize)
888c2ecf20Sopenharmony_ci{
898c2ecf20Sopenharmony_ci	int slot = 0;
908c2ecf20Sopenharmony_ci	u64 disk_bytenr = SZ_1M;
918c2ecf20Sopenharmony_ci	u64 offset = 0;
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_ci	/* First we want a hole */
948c2ecf20Sopenharmony_ci	insert_extent(root, offset, 5, 5, 0, 0, 0, BTRFS_FILE_EXTENT_REG, 0,
958c2ecf20Sopenharmony_ci		      slot);
968c2ecf20Sopenharmony_ci	slot++;
978c2ecf20Sopenharmony_ci	offset += 5;
988c2ecf20Sopenharmony_ci
998c2ecf20Sopenharmony_ci	/*
1008c2ecf20Sopenharmony_ci	 * Now we want an inline extent, I don't think this is possible but hey
1018c2ecf20Sopenharmony_ci	 * why not?  Also keep in mind if we have an inline extent it counts as
1028c2ecf20Sopenharmony_ci	 * the whole first page.  If we were to expand it we would have to cow
1038c2ecf20Sopenharmony_ci	 * and we wouldn't have an inline extent anymore.
1048c2ecf20Sopenharmony_ci	 */
1058c2ecf20Sopenharmony_ci	insert_extent(root, offset, 1, 1, 0, 0, 0, BTRFS_FILE_EXTENT_INLINE, 0,
1068c2ecf20Sopenharmony_ci		      slot);
1078c2ecf20Sopenharmony_ci	slot++;
1088c2ecf20Sopenharmony_ci	offset = sectorsize;
1098c2ecf20Sopenharmony_ci
1108c2ecf20Sopenharmony_ci	/* Now another hole */
1118c2ecf20Sopenharmony_ci	insert_extent(root, offset, 4, 4, 0, 0, 0, BTRFS_FILE_EXTENT_REG, 0,
1128c2ecf20Sopenharmony_ci		      slot);
1138c2ecf20Sopenharmony_ci	slot++;
1148c2ecf20Sopenharmony_ci	offset += 4;
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	/* Now for a regular extent */
1178c2ecf20Sopenharmony_ci	insert_extent(root, offset, sectorsize - 1, sectorsize - 1, 0,
1188c2ecf20Sopenharmony_ci		      disk_bytenr, sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot);
1198c2ecf20Sopenharmony_ci	slot++;
1208c2ecf20Sopenharmony_ci	disk_bytenr += sectorsize;
1218c2ecf20Sopenharmony_ci	offset += sectorsize - 1;
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci	/*
1248c2ecf20Sopenharmony_ci	 * Now for 3 extents that were split from a hole punch so we test
1258c2ecf20Sopenharmony_ci	 * offsets properly.
1268c2ecf20Sopenharmony_ci	 */
1278c2ecf20Sopenharmony_ci	insert_extent(root, offset, sectorsize, 4 * sectorsize, 0, disk_bytenr,
1288c2ecf20Sopenharmony_ci		      4 * sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot);
1298c2ecf20Sopenharmony_ci	slot++;
1308c2ecf20Sopenharmony_ci	offset += sectorsize;
1318c2ecf20Sopenharmony_ci	insert_extent(root, offset, sectorsize, sectorsize, 0, 0, 0,
1328c2ecf20Sopenharmony_ci		      BTRFS_FILE_EXTENT_REG, 0, slot);
1338c2ecf20Sopenharmony_ci	slot++;
1348c2ecf20Sopenharmony_ci	offset += sectorsize;
1358c2ecf20Sopenharmony_ci	insert_extent(root, offset, 2 * sectorsize, 4 * sectorsize,
1368c2ecf20Sopenharmony_ci		      2 * sectorsize, disk_bytenr, 4 * sectorsize,
1378c2ecf20Sopenharmony_ci		      BTRFS_FILE_EXTENT_REG, 0, slot);
1388c2ecf20Sopenharmony_ci	slot++;
1398c2ecf20Sopenharmony_ci	offset += 2 * sectorsize;
1408c2ecf20Sopenharmony_ci	disk_bytenr += 4 * sectorsize;
1418c2ecf20Sopenharmony_ci
1428c2ecf20Sopenharmony_ci	/* Now for a unwritten prealloc extent */
1438c2ecf20Sopenharmony_ci	insert_extent(root, offset, sectorsize, sectorsize, 0, disk_bytenr,
1448c2ecf20Sopenharmony_ci		sectorsize, BTRFS_FILE_EXTENT_PREALLOC, 0, slot);
1458c2ecf20Sopenharmony_ci	slot++;
1468c2ecf20Sopenharmony_ci	offset += sectorsize;
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci	/*
1498c2ecf20Sopenharmony_ci	 * We want to jack up disk_bytenr a little more so the em stuff doesn't
1508c2ecf20Sopenharmony_ci	 * merge our records.
1518c2ecf20Sopenharmony_ci	 */
1528c2ecf20Sopenharmony_ci	disk_bytenr += 2 * sectorsize;
1538c2ecf20Sopenharmony_ci
1548c2ecf20Sopenharmony_ci	/*
1558c2ecf20Sopenharmony_ci	 * Now for a partially written prealloc extent, basically the same as
1568c2ecf20Sopenharmony_ci	 * the hole punch example above.  Ram_bytes never changes when you mark
1578c2ecf20Sopenharmony_ci	 * extents written btw.
1588c2ecf20Sopenharmony_ci	 */
1598c2ecf20Sopenharmony_ci	insert_extent(root, offset, sectorsize, 4 * sectorsize, 0, disk_bytenr,
1608c2ecf20Sopenharmony_ci		      4 * sectorsize, BTRFS_FILE_EXTENT_PREALLOC, 0, slot);
1618c2ecf20Sopenharmony_ci	slot++;
1628c2ecf20Sopenharmony_ci	offset += sectorsize;
1638c2ecf20Sopenharmony_ci	insert_extent(root, offset, sectorsize, 4 * sectorsize, sectorsize,
1648c2ecf20Sopenharmony_ci		      disk_bytenr, 4 * sectorsize, BTRFS_FILE_EXTENT_REG, 0,
1658c2ecf20Sopenharmony_ci		      slot);
1668c2ecf20Sopenharmony_ci	slot++;
1678c2ecf20Sopenharmony_ci	offset += sectorsize;
1688c2ecf20Sopenharmony_ci	insert_extent(root, offset, 2 * sectorsize, 4 * sectorsize,
1698c2ecf20Sopenharmony_ci		      2 * sectorsize, disk_bytenr, 4 * sectorsize,
1708c2ecf20Sopenharmony_ci		      BTRFS_FILE_EXTENT_PREALLOC, 0, slot);
1718c2ecf20Sopenharmony_ci	slot++;
1728c2ecf20Sopenharmony_ci	offset += 2 * sectorsize;
1738c2ecf20Sopenharmony_ci	disk_bytenr += 4 * sectorsize;
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci	/* Now a normal compressed extent */
1768c2ecf20Sopenharmony_ci	insert_extent(root, offset, 2 * sectorsize, 2 * sectorsize, 0,
1778c2ecf20Sopenharmony_ci		      disk_bytenr, sectorsize, BTRFS_FILE_EXTENT_REG,
1788c2ecf20Sopenharmony_ci		      BTRFS_COMPRESS_ZLIB, slot);
1798c2ecf20Sopenharmony_ci	slot++;
1808c2ecf20Sopenharmony_ci	offset += 2 * sectorsize;
1818c2ecf20Sopenharmony_ci	/* No merges */
1828c2ecf20Sopenharmony_ci	disk_bytenr += 2 * sectorsize;
1838c2ecf20Sopenharmony_ci
1848c2ecf20Sopenharmony_ci	/* Now a split compressed extent */
1858c2ecf20Sopenharmony_ci	insert_extent(root, offset, sectorsize, 4 * sectorsize, 0, disk_bytenr,
1868c2ecf20Sopenharmony_ci		      sectorsize, BTRFS_FILE_EXTENT_REG,
1878c2ecf20Sopenharmony_ci		      BTRFS_COMPRESS_ZLIB, slot);
1888c2ecf20Sopenharmony_ci	slot++;
1898c2ecf20Sopenharmony_ci	offset += sectorsize;
1908c2ecf20Sopenharmony_ci	insert_extent(root, offset, sectorsize, sectorsize, 0,
1918c2ecf20Sopenharmony_ci		      disk_bytenr + sectorsize, sectorsize,
1928c2ecf20Sopenharmony_ci		      BTRFS_FILE_EXTENT_REG, 0, slot);
1938c2ecf20Sopenharmony_ci	slot++;
1948c2ecf20Sopenharmony_ci	offset += sectorsize;
1958c2ecf20Sopenharmony_ci	insert_extent(root, offset, 2 * sectorsize, 4 * sectorsize,
1968c2ecf20Sopenharmony_ci		      2 * sectorsize, disk_bytenr, sectorsize,
1978c2ecf20Sopenharmony_ci		      BTRFS_FILE_EXTENT_REG, BTRFS_COMPRESS_ZLIB, slot);
1988c2ecf20Sopenharmony_ci	slot++;
1998c2ecf20Sopenharmony_ci	offset += 2 * sectorsize;
2008c2ecf20Sopenharmony_ci	disk_bytenr += 2 * sectorsize;
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci	/* Now extents that have a hole but no hole extent */
2038c2ecf20Sopenharmony_ci	insert_extent(root, offset, sectorsize, sectorsize, 0, disk_bytenr,
2048c2ecf20Sopenharmony_ci		      sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot);
2058c2ecf20Sopenharmony_ci	slot++;
2068c2ecf20Sopenharmony_ci	offset += 4 * sectorsize;
2078c2ecf20Sopenharmony_ci	disk_bytenr += sectorsize;
2088c2ecf20Sopenharmony_ci	insert_extent(root, offset, sectorsize, sectorsize, 0, disk_bytenr,
2098c2ecf20Sopenharmony_ci		      sectorsize, BTRFS_FILE_EXTENT_REG, 0, slot);
2108c2ecf20Sopenharmony_ci}
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_cistatic unsigned long prealloc_only = 0;
2138c2ecf20Sopenharmony_cistatic unsigned long compressed_only = 0;
2148c2ecf20Sopenharmony_cistatic unsigned long vacancy_only = 0;
2158c2ecf20Sopenharmony_ci
2168c2ecf20Sopenharmony_cistatic noinline int test_btrfs_get_extent(u32 sectorsize, u32 nodesize)
2178c2ecf20Sopenharmony_ci{
2188c2ecf20Sopenharmony_ci	struct btrfs_fs_info *fs_info = NULL;
2198c2ecf20Sopenharmony_ci	struct inode *inode = NULL;
2208c2ecf20Sopenharmony_ci	struct btrfs_root *root = NULL;
2218c2ecf20Sopenharmony_ci	struct extent_map *em = NULL;
2228c2ecf20Sopenharmony_ci	u64 orig_start;
2238c2ecf20Sopenharmony_ci	u64 disk_bytenr;
2248c2ecf20Sopenharmony_ci	u64 offset;
2258c2ecf20Sopenharmony_ci	int ret = -ENOMEM;
2268c2ecf20Sopenharmony_ci
2278c2ecf20Sopenharmony_ci	test_msg("running btrfs_get_extent tests");
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci	inode = btrfs_new_test_inode();
2308c2ecf20Sopenharmony_ci	if (!inode) {
2318c2ecf20Sopenharmony_ci		test_std_err(TEST_ALLOC_INODE);
2328c2ecf20Sopenharmony_ci		return ret;
2338c2ecf20Sopenharmony_ci	}
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_ci	inode->i_mode = S_IFREG;
2368c2ecf20Sopenharmony_ci	BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY;
2378c2ecf20Sopenharmony_ci	BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID;
2388c2ecf20Sopenharmony_ci	BTRFS_I(inode)->location.offset = 0;
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_ci	fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
2418c2ecf20Sopenharmony_ci	if (!fs_info) {
2428c2ecf20Sopenharmony_ci		test_std_err(TEST_ALLOC_FS_INFO);
2438c2ecf20Sopenharmony_ci		goto out;
2448c2ecf20Sopenharmony_ci	}
2458c2ecf20Sopenharmony_ci
2468c2ecf20Sopenharmony_ci	root = btrfs_alloc_dummy_root(fs_info);
2478c2ecf20Sopenharmony_ci	if (IS_ERR(root)) {
2488c2ecf20Sopenharmony_ci		test_std_err(TEST_ALLOC_ROOT);
2498c2ecf20Sopenharmony_ci		goto out;
2508c2ecf20Sopenharmony_ci	}
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci	root->node = alloc_dummy_extent_buffer(fs_info, nodesize);
2538c2ecf20Sopenharmony_ci	if (!root->node) {
2548c2ecf20Sopenharmony_ci		test_std_err(TEST_ALLOC_ROOT);
2558c2ecf20Sopenharmony_ci		goto out;
2568c2ecf20Sopenharmony_ci	}
2578c2ecf20Sopenharmony_ci
2588c2ecf20Sopenharmony_ci	btrfs_set_header_nritems(root->node, 0);
2598c2ecf20Sopenharmony_ci	btrfs_set_header_level(root->node, 0);
2608c2ecf20Sopenharmony_ci	ret = -EINVAL;
2618c2ecf20Sopenharmony_ci
2628c2ecf20Sopenharmony_ci	/* First with no extents */
2638c2ecf20Sopenharmony_ci	BTRFS_I(inode)->root = root;
2648c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, 0, sectorsize);
2658c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
2668c2ecf20Sopenharmony_ci		em = NULL;
2678c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
2688c2ecf20Sopenharmony_ci		goto out;
2698c2ecf20Sopenharmony_ci	}
2708c2ecf20Sopenharmony_ci	if (em->block_start != EXTENT_MAP_HOLE) {
2718c2ecf20Sopenharmony_ci		test_err("expected a hole, got %llu", em->block_start);
2728c2ecf20Sopenharmony_ci		goto out;
2738c2ecf20Sopenharmony_ci	}
2748c2ecf20Sopenharmony_ci	free_extent_map(em);
2758c2ecf20Sopenharmony_ci	btrfs_drop_extent_cache(BTRFS_I(inode), 0, (u64)-1, 0);
2768c2ecf20Sopenharmony_ci
2778c2ecf20Sopenharmony_ci	/*
2788c2ecf20Sopenharmony_ci	 * All of the magic numbers are based on the mapping setup in
2798c2ecf20Sopenharmony_ci	 * setup_file_extents, so if you change anything there you need to
2808c2ecf20Sopenharmony_ci	 * update the comment and update the expected values below.
2818c2ecf20Sopenharmony_ci	 */
2828c2ecf20Sopenharmony_ci	setup_file_extents(root, sectorsize);
2838c2ecf20Sopenharmony_ci
2848c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, 0, (u64)-1);
2858c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
2868c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
2878c2ecf20Sopenharmony_ci		goto out;
2888c2ecf20Sopenharmony_ci	}
2898c2ecf20Sopenharmony_ci	if (em->block_start != EXTENT_MAP_HOLE) {
2908c2ecf20Sopenharmony_ci		test_err("expected a hole, got %llu", em->block_start);
2918c2ecf20Sopenharmony_ci		goto out;
2928c2ecf20Sopenharmony_ci	}
2938c2ecf20Sopenharmony_ci	if (em->start != 0 || em->len != 5) {
2948c2ecf20Sopenharmony_ci		test_err(
2958c2ecf20Sopenharmony_ci		"unexpected extent wanted start 0 len 5, got start %llu len %llu",
2968c2ecf20Sopenharmony_ci			em->start, em->len);
2978c2ecf20Sopenharmony_ci		goto out;
2988c2ecf20Sopenharmony_ci	}
2998c2ecf20Sopenharmony_ci	if (em->flags != 0) {
3008c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want 0 have %lu", em->flags);
3018c2ecf20Sopenharmony_ci		goto out;
3028c2ecf20Sopenharmony_ci	}
3038c2ecf20Sopenharmony_ci	offset = em->start + em->len;
3048c2ecf20Sopenharmony_ci	free_extent_map(em);
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
3078c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
3088c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
3098c2ecf20Sopenharmony_ci		goto out;
3108c2ecf20Sopenharmony_ci	}
3118c2ecf20Sopenharmony_ci	if (em->block_start != EXTENT_MAP_INLINE) {
3128c2ecf20Sopenharmony_ci		test_err("expected an inline, got %llu", em->block_start);
3138c2ecf20Sopenharmony_ci		goto out;
3148c2ecf20Sopenharmony_ci	}
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_ci	if (em->start != offset || em->len != (sectorsize - 5)) {
3178c2ecf20Sopenharmony_ci		test_err(
3188c2ecf20Sopenharmony_ci	"unexpected extent wanted start %llu len 1, got start %llu len %llu",
3198c2ecf20Sopenharmony_ci			offset, em->start, em->len);
3208c2ecf20Sopenharmony_ci		goto out;
3218c2ecf20Sopenharmony_ci	}
3228c2ecf20Sopenharmony_ci	if (em->flags != 0) {
3238c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want 0 have %lu", em->flags);
3248c2ecf20Sopenharmony_ci		goto out;
3258c2ecf20Sopenharmony_ci	}
3268c2ecf20Sopenharmony_ci	/*
3278c2ecf20Sopenharmony_ci	 * We don't test anything else for inline since it doesn't get set
3288c2ecf20Sopenharmony_ci	 * unless we have a page for it to write into.  Maybe we should change
3298c2ecf20Sopenharmony_ci	 * this?
3308c2ecf20Sopenharmony_ci	 */
3318c2ecf20Sopenharmony_ci	offset = em->start + em->len;
3328c2ecf20Sopenharmony_ci	free_extent_map(em);
3338c2ecf20Sopenharmony_ci
3348c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
3358c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
3368c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
3378c2ecf20Sopenharmony_ci		goto out;
3388c2ecf20Sopenharmony_ci	}
3398c2ecf20Sopenharmony_ci	if (em->block_start != EXTENT_MAP_HOLE) {
3408c2ecf20Sopenharmony_ci		test_err("expected a hole, got %llu", em->block_start);
3418c2ecf20Sopenharmony_ci		goto out;
3428c2ecf20Sopenharmony_ci	}
3438c2ecf20Sopenharmony_ci	if (em->start != offset || em->len != 4) {
3448c2ecf20Sopenharmony_ci		test_err(
3458c2ecf20Sopenharmony_ci	"unexpected extent wanted start %llu len 4, got start %llu len %llu",
3468c2ecf20Sopenharmony_ci			offset, em->start, em->len);
3478c2ecf20Sopenharmony_ci		goto out;
3488c2ecf20Sopenharmony_ci	}
3498c2ecf20Sopenharmony_ci	if (em->flags != 0) {
3508c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want 0 have %lu", em->flags);
3518c2ecf20Sopenharmony_ci		goto out;
3528c2ecf20Sopenharmony_ci	}
3538c2ecf20Sopenharmony_ci	offset = em->start + em->len;
3548c2ecf20Sopenharmony_ci	free_extent_map(em);
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_ci	/* Regular extent */
3578c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
3588c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
3598c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
3608c2ecf20Sopenharmony_ci		goto out;
3618c2ecf20Sopenharmony_ci	}
3628c2ecf20Sopenharmony_ci	if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
3638c2ecf20Sopenharmony_ci		test_err("expected a real extent, got %llu", em->block_start);
3648c2ecf20Sopenharmony_ci		goto out;
3658c2ecf20Sopenharmony_ci	}
3668c2ecf20Sopenharmony_ci	if (em->start != offset || em->len != sectorsize - 1) {
3678c2ecf20Sopenharmony_ci		test_err(
3688c2ecf20Sopenharmony_ci	"unexpected extent wanted start %llu len 4095, got start %llu len %llu",
3698c2ecf20Sopenharmony_ci			offset, em->start, em->len);
3708c2ecf20Sopenharmony_ci		goto out;
3718c2ecf20Sopenharmony_ci	}
3728c2ecf20Sopenharmony_ci	if (em->flags != 0) {
3738c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want 0 have %lu", em->flags);
3748c2ecf20Sopenharmony_ci		goto out;
3758c2ecf20Sopenharmony_ci	}
3768c2ecf20Sopenharmony_ci	if (em->orig_start != em->start) {
3778c2ecf20Sopenharmony_ci		test_err("wrong orig offset, want %llu, have %llu", em->start,
3788c2ecf20Sopenharmony_ci			 em->orig_start);
3798c2ecf20Sopenharmony_ci		goto out;
3808c2ecf20Sopenharmony_ci	}
3818c2ecf20Sopenharmony_ci	offset = em->start + em->len;
3828c2ecf20Sopenharmony_ci	free_extent_map(em);
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_ci	/* The next 3 are split extents */
3858c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
3868c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
3878c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
3888c2ecf20Sopenharmony_ci		goto out;
3898c2ecf20Sopenharmony_ci	}
3908c2ecf20Sopenharmony_ci	if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
3918c2ecf20Sopenharmony_ci		test_err("expected a real extent, got %llu", em->block_start);
3928c2ecf20Sopenharmony_ci		goto out;
3938c2ecf20Sopenharmony_ci	}
3948c2ecf20Sopenharmony_ci	if (em->start != offset || em->len != sectorsize) {
3958c2ecf20Sopenharmony_ci		test_err(
3968c2ecf20Sopenharmony_ci		"unexpected extent start %llu len %u, got start %llu len %llu",
3978c2ecf20Sopenharmony_ci			offset, sectorsize, em->start, em->len);
3988c2ecf20Sopenharmony_ci		goto out;
3998c2ecf20Sopenharmony_ci	}
4008c2ecf20Sopenharmony_ci	if (em->flags != 0) {
4018c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want 0 have %lu", em->flags);
4028c2ecf20Sopenharmony_ci		goto out;
4038c2ecf20Sopenharmony_ci	}
4048c2ecf20Sopenharmony_ci	if (em->orig_start != em->start) {
4058c2ecf20Sopenharmony_ci		test_err("wrong orig offset, want %llu, have %llu", em->start,
4068c2ecf20Sopenharmony_ci			 em->orig_start);
4078c2ecf20Sopenharmony_ci		goto out;
4088c2ecf20Sopenharmony_ci	}
4098c2ecf20Sopenharmony_ci	disk_bytenr = em->block_start;
4108c2ecf20Sopenharmony_ci	orig_start = em->start;
4118c2ecf20Sopenharmony_ci	offset = em->start + em->len;
4128c2ecf20Sopenharmony_ci	free_extent_map(em);
4138c2ecf20Sopenharmony_ci
4148c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
4158c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
4168c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
4178c2ecf20Sopenharmony_ci		goto out;
4188c2ecf20Sopenharmony_ci	}
4198c2ecf20Sopenharmony_ci	if (em->block_start != EXTENT_MAP_HOLE) {
4208c2ecf20Sopenharmony_ci		test_err("expected a hole, got %llu", em->block_start);
4218c2ecf20Sopenharmony_ci		goto out;
4228c2ecf20Sopenharmony_ci	}
4238c2ecf20Sopenharmony_ci	if (em->start != offset || em->len != sectorsize) {
4248c2ecf20Sopenharmony_ci		test_err(
4258c2ecf20Sopenharmony_ci	"unexpected extent wanted start %llu len %u, got start %llu len %llu",
4268c2ecf20Sopenharmony_ci			offset, sectorsize, em->start, em->len);
4278c2ecf20Sopenharmony_ci		goto out;
4288c2ecf20Sopenharmony_ci	}
4298c2ecf20Sopenharmony_ci	if (em->flags != 0) {
4308c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want 0 have %lu", em->flags);
4318c2ecf20Sopenharmony_ci		goto out;
4328c2ecf20Sopenharmony_ci	}
4338c2ecf20Sopenharmony_ci	offset = em->start + em->len;
4348c2ecf20Sopenharmony_ci	free_extent_map(em);
4358c2ecf20Sopenharmony_ci
4368c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
4378c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
4388c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
4398c2ecf20Sopenharmony_ci		goto out;
4408c2ecf20Sopenharmony_ci	}
4418c2ecf20Sopenharmony_ci	if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
4428c2ecf20Sopenharmony_ci		test_err("expected a real extent, got %llu", em->block_start);
4438c2ecf20Sopenharmony_ci		goto out;
4448c2ecf20Sopenharmony_ci	}
4458c2ecf20Sopenharmony_ci	if (em->start != offset || em->len != 2 * sectorsize) {
4468c2ecf20Sopenharmony_ci		test_err(
4478c2ecf20Sopenharmony_ci	"unexpected extent wanted start %llu len %u, got start %llu len %llu",
4488c2ecf20Sopenharmony_ci			offset, 2 * sectorsize, em->start, em->len);
4498c2ecf20Sopenharmony_ci		goto out;
4508c2ecf20Sopenharmony_ci	}
4518c2ecf20Sopenharmony_ci	if (em->flags != 0) {
4528c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want 0 have %lu", em->flags);
4538c2ecf20Sopenharmony_ci		goto out;
4548c2ecf20Sopenharmony_ci	}
4558c2ecf20Sopenharmony_ci	if (em->orig_start != orig_start) {
4568c2ecf20Sopenharmony_ci		test_err("wrong orig offset, want %llu, have %llu",
4578c2ecf20Sopenharmony_ci			 orig_start, em->orig_start);
4588c2ecf20Sopenharmony_ci		goto out;
4598c2ecf20Sopenharmony_ci	}
4608c2ecf20Sopenharmony_ci	disk_bytenr += (em->start - orig_start);
4618c2ecf20Sopenharmony_ci	if (em->block_start != disk_bytenr) {
4628c2ecf20Sopenharmony_ci		test_err("wrong block start, want %llu, have %llu",
4638c2ecf20Sopenharmony_ci			 disk_bytenr, em->block_start);
4648c2ecf20Sopenharmony_ci		goto out;
4658c2ecf20Sopenharmony_ci	}
4668c2ecf20Sopenharmony_ci	offset = em->start + em->len;
4678c2ecf20Sopenharmony_ci	free_extent_map(em);
4688c2ecf20Sopenharmony_ci
4698c2ecf20Sopenharmony_ci	/* Prealloc extent */
4708c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
4718c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
4728c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
4738c2ecf20Sopenharmony_ci		goto out;
4748c2ecf20Sopenharmony_ci	}
4758c2ecf20Sopenharmony_ci	if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
4768c2ecf20Sopenharmony_ci		test_err("expected a real extent, got %llu", em->block_start);
4778c2ecf20Sopenharmony_ci		goto out;
4788c2ecf20Sopenharmony_ci	}
4798c2ecf20Sopenharmony_ci	if (em->start != offset || em->len != sectorsize) {
4808c2ecf20Sopenharmony_ci		test_err(
4818c2ecf20Sopenharmony_ci	"unexpected extent wanted start %llu len %u, got start %llu len %llu",
4828c2ecf20Sopenharmony_ci			offset, sectorsize, em->start, em->len);
4838c2ecf20Sopenharmony_ci		goto out;
4848c2ecf20Sopenharmony_ci	}
4858c2ecf20Sopenharmony_ci	if (em->flags != prealloc_only) {
4868c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want %lu have %lu",
4878c2ecf20Sopenharmony_ci			 prealloc_only, em->flags);
4888c2ecf20Sopenharmony_ci		goto out;
4898c2ecf20Sopenharmony_ci	}
4908c2ecf20Sopenharmony_ci	if (em->orig_start != em->start) {
4918c2ecf20Sopenharmony_ci		test_err("wrong orig offset, want %llu, have %llu", em->start,
4928c2ecf20Sopenharmony_ci			 em->orig_start);
4938c2ecf20Sopenharmony_ci		goto out;
4948c2ecf20Sopenharmony_ci	}
4958c2ecf20Sopenharmony_ci	offset = em->start + em->len;
4968c2ecf20Sopenharmony_ci	free_extent_map(em);
4978c2ecf20Sopenharmony_ci
4988c2ecf20Sopenharmony_ci	/* The next 3 are a half written prealloc extent */
4998c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
5008c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
5018c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
5028c2ecf20Sopenharmony_ci		goto out;
5038c2ecf20Sopenharmony_ci	}
5048c2ecf20Sopenharmony_ci	if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
5058c2ecf20Sopenharmony_ci		test_err("expected a real extent, got %llu", em->block_start);
5068c2ecf20Sopenharmony_ci		goto out;
5078c2ecf20Sopenharmony_ci	}
5088c2ecf20Sopenharmony_ci	if (em->start != offset || em->len != sectorsize) {
5098c2ecf20Sopenharmony_ci		test_err(
5108c2ecf20Sopenharmony_ci	"unexpected extent wanted start %llu len %u, got start %llu len %llu",
5118c2ecf20Sopenharmony_ci			offset, sectorsize, em->start, em->len);
5128c2ecf20Sopenharmony_ci		goto out;
5138c2ecf20Sopenharmony_ci	}
5148c2ecf20Sopenharmony_ci	if (em->flags != prealloc_only) {
5158c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want %lu have %lu",
5168c2ecf20Sopenharmony_ci			 prealloc_only, em->flags);
5178c2ecf20Sopenharmony_ci		goto out;
5188c2ecf20Sopenharmony_ci	}
5198c2ecf20Sopenharmony_ci	if (em->orig_start != em->start) {
5208c2ecf20Sopenharmony_ci		test_err("wrong orig offset, want %llu, have %llu", em->start,
5218c2ecf20Sopenharmony_ci			 em->orig_start);
5228c2ecf20Sopenharmony_ci		goto out;
5238c2ecf20Sopenharmony_ci	}
5248c2ecf20Sopenharmony_ci	disk_bytenr = em->block_start;
5258c2ecf20Sopenharmony_ci	orig_start = em->start;
5268c2ecf20Sopenharmony_ci	offset = em->start + em->len;
5278c2ecf20Sopenharmony_ci	free_extent_map(em);
5288c2ecf20Sopenharmony_ci
5298c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
5308c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
5318c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
5328c2ecf20Sopenharmony_ci		goto out;
5338c2ecf20Sopenharmony_ci	}
5348c2ecf20Sopenharmony_ci	if (em->block_start >= EXTENT_MAP_HOLE) {
5358c2ecf20Sopenharmony_ci		test_err("expected a real extent, got %llu", em->block_start);
5368c2ecf20Sopenharmony_ci		goto out;
5378c2ecf20Sopenharmony_ci	}
5388c2ecf20Sopenharmony_ci	if (em->start != offset || em->len != sectorsize) {
5398c2ecf20Sopenharmony_ci		test_err(
5408c2ecf20Sopenharmony_ci	"unexpected extent wanted start %llu len %u, got start %llu len %llu",
5418c2ecf20Sopenharmony_ci			offset, sectorsize, em->start, em->len);
5428c2ecf20Sopenharmony_ci		goto out;
5438c2ecf20Sopenharmony_ci	}
5448c2ecf20Sopenharmony_ci	if (em->flags != 0) {
5458c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want 0 have %lu", em->flags);
5468c2ecf20Sopenharmony_ci		goto out;
5478c2ecf20Sopenharmony_ci	}
5488c2ecf20Sopenharmony_ci	if (em->orig_start != orig_start) {
5498c2ecf20Sopenharmony_ci		test_err("unexpected orig offset, wanted %llu, have %llu",
5508c2ecf20Sopenharmony_ci			 orig_start, em->orig_start);
5518c2ecf20Sopenharmony_ci		goto out;
5528c2ecf20Sopenharmony_ci	}
5538c2ecf20Sopenharmony_ci	if (em->block_start != (disk_bytenr + (em->start - em->orig_start))) {
5548c2ecf20Sopenharmony_ci		test_err("unexpected block start, wanted %llu, have %llu",
5558c2ecf20Sopenharmony_ci			 disk_bytenr + (em->start - em->orig_start),
5568c2ecf20Sopenharmony_ci			 em->block_start);
5578c2ecf20Sopenharmony_ci		goto out;
5588c2ecf20Sopenharmony_ci	}
5598c2ecf20Sopenharmony_ci	offset = em->start + em->len;
5608c2ecf20Sopenharmony_ci	free_extent_map(em);
5618c2ecf20Sopenharmony_ci
5628c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
5638c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
5648c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
5658c2ecf20Sopenharmony_ci		goto out;
5668c2ecf20Sopenharmony_ci	}
5678c2ecf20Sopenharmony_ci	if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
5688c2ecf20Sopenharmony_ci		test_err("expected a real extent, got %llu", em->block_start);
5698c2ecf20Sopenharmony_ci		goto out;
5708c2ecf20Sopenharmony_ci	}
5718c2ecf20Sopenharmony_ci	if (em->start != offset || em->len != 2 * sectorsize) {
5728c2ecf20Sopenharmony_ci		test_err(
5738c2ecf20Sopenharmony_ci	"unexpected extent wanted start %llu len %u, got start %llu len %llu",
5748c2ecf20Sopenharmony_ci			offset, 2 * sectorsize, em->start, em->len);
5758c2ecf20Sopenharmony_ci		goto out;
5768c2ecf20Sopenharmony_ci	}
5778c2ecf20Sopenharmony_ci	if (em->flags != prealloc_only) {
5788c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want %lu have %lu",
5798c2ecf20Sopenharmony_ci			 prealloc_only, em->flags);
5808c2ecf20Sopenharmony_ci		goto out;
5818c2ecf20Sopenharmony_ci	}
5828c2ecf20Sopenharmony_ci	if (em->orig_start != orig_start) {
5838c2ecf20Sopenharmony_ci		test_err("wrong orig offset, want %llu, have %llu", orig_start,
5848c2ecf20Sopenharmony_ci			 em->orig_start);
5858c2ecf20Sopenharmony_ci		goto out;
5868c2ecf20Sopenharmony_ci	}
5878c2ecf20Sopenharmony_ci	if (em->block_start != (disk_bytenr + (em->start - em->orig_start))) {
5888c2ecf20Sopenharmony_ci		test_err("unexpected block start, wanted %llu, have %llu",
5898c2ecf20Sopenharmony_ci			 disk_bytenr + (em->start - em->orig_start),
5908c2ecf20Sopenharmony_ci			 em->block_start);
5918c2ecf20Sopenharmony_ci		goto out;
5928c2ecf20Sopenharmony_ci	}
5938c2ecf20Sopenharmony_ci	offset = em->start + em->len;
5948c2ecf20Sopenharmony_ci	free_extent_map(em);
5958c2ecf20Sopenharmony_ci
5968c2ecf20Sopenharmony_ci	/* Now for the compressed extent */
5978c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
5988c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
5998c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
6008c2ecf20Sopenharmony_ci		goto out;
6018c2ecf20Sopenharmony_ci	}
6028c2ecf20Sopenharmony_ci	if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
6038c2ecf20Sopenharmony_ci		test_err("expected a real extent, got %llu", em->block_start);
6048c2ecf20Sopenharmony_ci		goto out;
6058c2ecf20Sopenharmony_ci	}
6068c2ecf20Sopenharmony_ci	if (em->start != offset || em->len != 2 * sectorsize) {
6078c2ecf20Sopenharmony_ci		test_err(
6088c2ecf20Sopenharmony_ci	"unexpected extent wanted start %llu len %u, got start %llu len %llu",
6098c2ecf20Sopenharmony_ci			offset, 2 * sectorsize, em->start, em->len);
6108c2ecf20Sopenharmony_ci		goto out;
6118c2ecf20Sopenharmony_ci	}
6128c2ecf20Sopenharmony_ci	if (em->flags != compressed_only) {
6138c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want %lu have %lu",
6148c2ecf20Sopenharmony_ci			 compressed_only, em->flags);
6158c2ecf20Sopenharmony_ci		goto out;
6168c2ecf20Sopenharmony_ci	}
6178c2ecf20Sopenharmony_ci	if (em->orig_start != em->start) {
6188c2ecf20Sopenharmony_ci		test_err("wrong orig offset, want %llu, have %llu",
6198c2ecf20Sopenharmony_ci			 em->start, em->orig_start);
6208c2ecf20Sopenharmony_ci		goto out;
6218c2ecf20Sopenharmony_ci	}
6228c2ecf20Sopenharmony_ci	if (em->compress_type != BTRFS_COMPRESS_ZLIB) {
6238c2ecf20Sopenharmony_ci		test_err("unexpected compress type, wanted %d, got %d",
6248c2ecf20Sopenharmony_ci			 BTRFS_COMPRESS_ZLIB, em->compress_type);
6258c2ecf20Sopenharmony_ci		goto out;
6268c2ecf20Sopenharmony_ci	}
6278c2ecf20Sopenharmony_ci	offset = em->start + em->len;
6288c2ecf20Sopenharmony_ci	free_extent_map(em);
6298c2ecf20Sopenharmony_ci
6308c2ecf20Sopenharmony_ci	/* Split compressed extent */
6318c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
6328c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
6338c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
6348c2ecf20Sopenharmony_ci		goto out;
6358c2ecf20Sopenharmony_ci	}
6368c2ecf20Sopenharmony_ci	if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
6378c2ecf20Sopenharmony_ci		test_err("expected a real extent, got %llu", em->block_start);
6388c2ecf20Sopenharmony_ci		goto out;
6398c2ecf20Sopenharmony_ci	}
6408c2ecf20Sopenharmony_ci	if (em->start != offset || em->len != sectorsize) {
6418c2ecf20Sopenharmony_ci		test_err(
6428c2ecf20Sopenharmony_ci	"unexpected extent wanted start %llu len %u, got start %llu len %llu",
6438c2ecf20Sopenharmony_ci			offset, sectorsize, em->start, em->len);
6448c2ecf20Sopenharmony_ci		goto out;
6458c2ecf20Sopenharmony_ci	}
6468c2ecf20Sopenharmony_ci	if (em->flags != compressed_only) {
6478c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want %lu have %lu",
6488c2ecf20Sopenharmony_ci			 compressed_only, em->flags);
6498c2ecf20Sopenharmony_ci		goto out;
6508c2ecf20Sopenharmony_ci	}
6518c2ecf20Sopenharmony_ci	if (em->orig_start != em->start) {
6528c2ecf20Sopenharmony_ci		test_err("wrong orig offset, want %llu, have %llu",
6538c2ecf20Sopenharmony_ci			 em->start, em->orig_start);
6548c2ecf20Sopenharmony_ci		goto out;
6558c2ecf20Sopenharmony_ci	}
6568c2ecf20Sopenharmony_ci	if (em->compress_type != BTRFS_COMPRESS_ZLIB) {
6578c2ecf20Sopenharmony_ci		test_err("unexpected compress type, wanted %d, got %d",
6588c2ecf20Sopenharmony_ci			 BTRFS_COMPRESS_ZLIB, em->compress_type);
6598c2ecf20Sopenharmony_ci		goto out;
6608c2ecf20Sopenharmony_ci	}
6618c2ecf20Sopenharmony_ci	disk_bytenr = em->block_start;
6628c2ecf20Sopenharmony_ci	orig_start = em->start;
6638c2ecf20Sopenharmony_ci	offset = em->start + em->len;
6648c2ecf20Sopenharmony_ci	free_extent_map(em);
6658c2ecf20Sopenharmony_ci
6668c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
6678c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
6688c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
6698c2ecf20Sopenharmony_ci		goto out;
6708c2ecf20Sopenharmony_ci	}
6718c2ecf20Sopenharmony_ci	if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
6728c2ecf20Sopenharmony_ci		test_err("expected a real extent, got %llu", em->block_start);
6738c2ecf20Sopenharmony_ci		goto out;
6748c2ecf20Sopenharmony_ci	}
6758c2ecf20Sopenharmony_ci	if (em->start != offset || em->len != sectorsize) {
6768c2ecf20Sopenharmony_ci		test_err(
6778c2ecf20Sopenharmony_ci	"unexpected extent wanted start %llu len %u, got start %llu len %llu",
6788c2ecf20Sopenharmony_ci			offset, sectorsize, em->start, em->len);
6798c2ecf20Sopenharmony_ci		goto out;
6808c2ecf20Sopenharmony_ci	}
6818c2ecf20Sopenharmony_ci	if (em->flags != 0) {
6828c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want 0 have %lu", em->flags);
6838c2ecf20Sopenharmony_ci		goto out;
6848c2ecf20Sopenharmony_ci	}
6858c2ecf20Sopenharmony_ci	if (em->orig_start != em->start) {
6868c2ecf20Sopenharmony_ci		test_err("wrong orig offset, want %llu, have %llu", em->start,
6878c2ecf20Sopenharmony_ci			 em->orig_start);
6888c2ecf20Sopenharmony_ci		goto out;
6898c2ecf20Sopenharmony_ci	}
6908c2ecf20Sopenharmony_ci	offset = em->start + em->len;
6918c2ecf20Sopenharmony_ci	free_extent_map(em);
6928c2ecf20Sopenharmony_ci
6938c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
6948c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
6958c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
6968c2ecf20Sopenharmony_ci		goto out;
6978c2ecf20Sopenharmony_ci	}
6988c2ecf20Sopenharmony_ci	if (em->block_start != disk_bytenr) {
6998c2ecf20Sopenharmony_ci		test_err("block start does not match, want %llu got %llu",
7008c2ecf20Sopenharmony_ci			 disk_bytenr, em->block_start);
7018c2ecf20Sopenharmony_ci		goto out;
7028c2ecf20Sopenharmony_ci	}
7038c2ecf20Sopenharmony_ci	if (em->start != offset || em->len != 2 * sectorsize) {
7048c2ecf20Sopenharmony_ci		test_err(
7058c2ecf20Sopenharmony_ci	"unexpected extent wanted start %llu len %u, got start %llu len %llu",
7068c2ecf20Sopenharmony_ci			offset, 2 * sectorsize, em->start, em->len);
7078c2ecf20Sopenharmony_ci		goto out;
7088c2ecf20Sopenharmony_ci	}
7098c2ecf20Sopenharmony_ci	if (em->flags != compressed_only) {
7108c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want %lu have %lu",
7118c2ecf20Sopenharmony_ci			 compressed_only, em->flags);
7128c2ecf20Sopenharmony_ci		goto out;
7138c2ecf20Sopenharmony_ci	}
7148c2ecf20Sopenharmony_ci	if (em->orig_start != orig_start) {
7158c2ecf20Sopenharmony_ci		test_err("wrong orig offset, want %llu, have %llu",
7168c2ecf20Sopenharmony_ci			 em->start, orig_start);
7178c2ecf20Sopenharmony_ci		goto out;
7188c2ecf20Sopenharmony_ci	}
7198c2ecf20Sopenharmony_ci	if (em->compress_type != BTRFS_COMPRESS_ZLIB) {
7208c2ecf20Sopenharmony_ci		test_err("unexpected compress type, wanted %d, got %d",
7218c2ecf20Sopenharmony_ci			 BTRFS_COMPRESS_ZLIB, em->compress_type);
7228c2ecf20Sopenharmony_ci		goto out;
7238c2ecf20Sopenharmony_ci	}
7248c2ecf20Sopenharmony_ci	offset = em->start + em->len;
7258c2ecf20Sopenharmony_ci	free_extent_map(em);
7268c2ecf20Sopenharmony_ci
7278c2ecf20Sopenharmony_ci	/* A hole between regular extents but no hole extent */
7288c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset + 6, sectorsize);
7298c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
7308c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
7318c2ecf20Sopenharmony_ci		goto out;
7328c2ecf20Sopenharmony_ci	}
7338c2ecf20Sopenharmony_ci	if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
7348c2ecf20Sopenharmony_ci		test_err("expected a real extent, got %llu", em->block_start);
7358c2ecf20Sopenharmony_ci		goto out;
7368c2ecf20Sopenharmony_ci	}
7378c2ecf20Sopenharmony_ci	if (em->start != offset || em->len != sectorsize) {
7388c2ecf20Sopenharmony_ci		test_err(
7398c2ecf20Sopenharmony_ci	"unexpected extent wanted start %llu len %u, got start %llu len %llu",
7408c2ecf20Sopenharmony_ci			offset, sectorsize, em->start, em->len);
7418c2ecf20Sopenharmony_ci		goto out;
7428c2ecf20Sopenharmony_ci	}
7438c2ecf20Sopenharmony_ci	if (em->flags != 0) {
7448c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want 0 have %lu", em->flags);
7458c2ecf20Sopenharmony_ci		goto out;
7468c2ecf20Sopenharmony_ci	}
7478c2ecf20Sopenharmony_ci	if (em->orig_start != em->start) {
7488c2ecf20Sopenharmony_ci		test_err("wrong orig offset, want %llu, have %llu", em->start,
7498c2ecf20Sopenharmony_ci			 em->orig_start);
7508c2ecf20Sopenharmony_ci		goto out;
7518c2ecf20Sopenharmony_ci	}
7528c2ecf20Sopenharmony_ci	offset = em->start + em->len;
7538c2ecf20Sopenharmony_ci	free_extent_map(em);
7548c2ecf20Sopenharmony_ci
7558c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, SZ_4M);
7568c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
7578c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
7588c2ecf20Sopenharmony_ci		goto out;
7598c2ecf20Sopenharmony_ci	}
7608c2ecf20Sopenharmony_ci	if (em->block_start != EXTENT_MAP_HOLE) {
7618c2ecf20Sopenharmony_ci		test_err("expected a hole extent, got %llu", em->block_start);
7628c2ecf20Sopenharmony_ci		goto out;
7638c2ecf20Sopenharmony_ci	}
7648c2ecf20Sopenharmony_ci	/*
7658c2ecf20Sopenharmony_ci	 * Currently we just return a length that we requested rather than the
7668c2ecf20Sopenharmony_ci	 * length of the actual hole, if this changes we'll have to change this
7678c2ecf20Sopenharmony_ci	 * test.
7688c2ecf20Sopenharmony_ci	 */
7698c2ecf20Sopenharmony_ci	if (em->start != offset || em->len != 3 * sectorsize) {
7708c2ecf20Sopenharmony_ci		test_err(
7718c2ecf20Sopenharmony_ci	"unexpected extent wanted start %llu len %u, got start %llu len %llu",
7728c2ecf20Sopenharmony_ci			offset, 3 * sectorsize, em->start, em->len);
7738c2ecf20Sopenharmony_ci		goto out;
7748c2ecf20Sopenharmony_ci	}
7758c2ecf20Sopenharmony_ci	if (em->flags != vacancy_only) {
7768c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want %lu have %lu",
7778c2ecf20Sopenharmony_ci			 vacancy_only, em->flags);
7788c2ecf20Sopenharmony_ci		goto out;
7798c2ecf20Sopenharmony_ci	}
7808c2ecf20Sopenharmony_ci	if (em->orig_start != em->start) {
7818c2ecf20Sopenharmony_ci		test_err("wrong orig offset, want %llu, have %llu", em->start,
7828c2ecf20Sopenharmony_ci			 em->orig_start);
7838c2ecf20Sopenharmony_ci		goto out;
7848c2ecf20Sopenharmony_ci	}
7858c2ecf20Sopenharmony_ci	offset = em->start + em->len;
7868c2ecf20Sopenharmony_ci	free_extent_map(em);
7878c2ecf20Sopenharmony_ci
7888c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, offset, sectorsize);
7898c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
7908c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
7918c2ecf20Sopenharmony_ci		goto out;
7928c2ecf20Sopenharmony_ci	}
7938c2ecf20Sopenharmony_ci	if (em->block_start >= EXTENT_MAP_LAST_BYTE) {
7948c2ecf20Sopenharmony_ci		test_err("expected a real extent, got %llu", em->block_start);
7958c2ecf20Sopenharmony_ci		goto out;
7968c2ecf20Sopenharmony_ci	}
7978c2ecf20Sopenharmony_ci	if (em->start != offset || em->len != sectorsize) {
7988c2ecf20Sopenharmony_ci		test_err(
7998c2ecf20Sopenharmony_ci	"unexpected extent wanted start %llu len %u, got start %llu len %llu",
8008c2ecf20Sopenharmony_ci			offset, sectorsize, em->start, em->len);
8018c2ecf20Sopenharmony_ci		goto out;
8028c2ecf20Sopenharmony_ci	}
8038c2ecf20Sopenharmony_ci	if (em->flags != 0) {
8048c2ecf20Sopenharmony_ci		test_err("unexpected flags set, want 0 have %lu", em->flags);
8058c2ecf20Sopenharmony_ci		goto out;
8068c2ecf20Sopenharmony_ci	}
8078c2ecf20Sopenharmony_ci	if (em->orig_start != em->start) {
8088c2ecf20Sopenharmony_ci		test_err("wrong orig offset, want %llu, have %llu", em->start,
8098c2ecf20Sopenharmony_ci			 em->orig_start);
8108c2ecf20Sopenharmony_ci		goto out;
8118c2ecf20Sopenharmony_ci	}
8128c2ecf20Sopenharmony_ci	ret = 0;
8138c2ecf20Sopenharmony_ciout:
8148c2ecf20Sopenharmony_ci	if (!IS_ERR(em))
8158c2ecf20Sopenharmony_ci		free_extent_map(em);
8168c2ecf20Sopenharmony_ci	iput(inode);
8178c2ecf20Sopenharmony_ci	btrfs_free_dummy_root(root);
8188c2ecf20Sopenharmony_ci	btrfs_free_dummy_fs_info(fs_info);
8198c2ecf20Sopenharmony_ci	return ret;
8208c2ecf20Sopenharmony_ci}
8218c2ecf20Sopenharmony_ci
8228c2ecf20Sopenharmony_cistatic int test_hole_first(u32 sectorsize, u32 nodesize)
8238c2ecf20Sopenharmony_ci{
8248c2ecf20Sopenharmony_ci	struct btrfs_fs_info *fs_info = NULL;
8258c2ecf20Sopenharmony_ci	struct inode *inode = NULL;
8268c2ecf20Sopenharmony_ci	struct btrfs_root *root = NULL;
8278c2ecf20Sopenharmony_ci	struct extent_map *em = NULL;
8288c2ecf20Sopenharmony_ci	int ret = -ENOMEM;
8298c2ecf20Sopenharmony_ci
8308c2ecf20Sopenharmony_ci	test_msg("running hole first btrfs_get_extent test");
8318c2ecf20Sopenharmony_ci
8328c2ecf20Sopenharmony_ci	inode = btrfs_new_test_inode();
8338c2ecf20Sopenharmony_ci	if (!inode) {
8348c2ecf20Sopenharmony_ci		test_std_err(TEST_ALLOC_INODE);
8358c2ecf20Sopenharmony_ci		return ret;
8368c2ecf20Sopenharmony_ci	}
8378c2ecf20Sopenharmony_ci
8388c2ecf20Sopenharmony_ci	BTRFS_I(inode)->location.type = BTRFS_INODE_ITEM_KEY;
8398c2ecf20Sopenharmony_ci	BTRFS_I(inode)->location.objectid = BTRFS_FIRST_FREE_OBJECTID;
8408c2ecf20Sopenharmony_ci	BTRFS_I(inode)->location.offset = 0;
8418c2ecf20Sopenharmony_ci
8428c2ecf20Sopenharmony_ci	fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
8438c2ecf20Sopenharmony_ci	if (!fs_info) {
8448c2ecf20Sopenharmony_ci		test_std_err(TEST_ALLOC_FS_INFO);
8458c2ecf20Sopenharmony_ci		goto out;
8468c2ecf20Sopenharmony_ci	}
8478c2ecf20Sopenharmony_ci
8488c2ecf20Sopenharmony_ci	root = btrfs_alloc_dummy_root(fs_info);
8498c2ecf20Sopenharmony_ci	if (IS_ERR(root)) {
8508c2ecf20Sopenharmony_ci		test_std_err(TEST_ALLOC_ROOT);
8518c2ecf20Sopenharmony_ci		goto out;
8528c2ecf20Sopenharmony_ci	}
8538c2ecf20Sopenharmony_ci
8548c2ecf20Sopenharmony_ci	root->node = alloc_dummy_extent_buffer(fs_info, nodesize);
8558c2ecf20Sopenharmony_ci	if (!root->node) {
8568c2ecf20Sopenharmony_ci		test_std_err(TEST_ALLOC_ROOT);
8578c2ecf20Sopenharmony_ci		goto out;
8588c2ecf20Sopenharmony_ci	}
8598c2ecf20Sopenharmony_ci
8608c2ecf20Sopenharmony_ci	btrfs_set_header_nritems(root->node, 0);
8618c2ecf20Sopenharmony_ci	btrfs_set_header_level(root->node, 0);
8628c2ecf20Sopenharmony_ci	BTRFS_I(inode)->root = root;
8638c2ecf20Sopenharmony_ci	ret = -EINVAL;
8648c2ecf20Sopenharmony_ci
8658c2ecf20Sopenharmony_ci	/*
8668c2ecf20Sopenharmony_ci	 * Need a blank inode item here just so we don't confuse
8678c2ecf20Sopenharmony_ci	 * btrfs_get_extent.
8688c2ecf20Sopenharmony_ci	 */
8698c2ecf20Sopenharmony_ci	insert_inode_item_key(root);
8708c2ecf20Sopenharmony_ci	insert_extent(root, sectorsize, sectorsize, sectorsize, 0, sectorsize,
8718c2ecf20Sopenharmony_ci		      sectorsize, BTRFS_FILE_EXTENT_REG, 0, 1);
8728c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, 0, 2 * sectorsize);
8738c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
8748c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
8758c2ecf20Sopenharmony_ci		goto out;
8768c2ecf20Sopenharmony_ci	}
8778c2ecf20Sopenharmony_ci	if (em->block_start != EXTENT_MAP_HOLE) {
8788c2ecf20Sopenharmony_ci		test_err("expected a hole, got %llu", em->block_start);
8798c2ecf20Sopenharmony_ci		goto out;
8808c2ecf20Sopenharmony_ci	}
8818c2ecf20Sopenharmony_ci	if (em->start != 0 || em->len != sectorsize) {
8828c2ecf20Sopenharmony_ci		test_err(
8838c2ecf20Sopenharmony_ci	"unexpected extent wanted start 0 len %u, got start %llu len %llu",
8848c2ecf20Sopenharmony_ci			sectorsize, em->start, em->len);
8858c2ecf20Sopenharmony_ci		goto out;
8868c2ecf20Sopenharmony_ci	}
8878c2ecf20Sopenharmony_ci	if (em->flags != vacancy_only) {
8888c2ecf20Sopenharmony_ci		test_err("wrong flags, wanted %lu, have %lu", vacancy_only,
8898c2ecf20Sopenharmony_ci			 em->flags);
8908c2ecf20Sopenharmony_ci		goto out;
8918c2ecf20Sopenharmony_ci	}
8928c2ecf20Sopenharmony_ci	free_extent_map(em);
8938c2ecf20Sopenharmony_ci
8948c2ecf20Sopenharmony_ci	em = btrfs_get_extent(BTRFS_I(inode), NULL, 0, sectorsize, 2 * sectorsize);
8958c2ecf20Sopenharmony_ci	if (IS_ERR(em)) {
8968c2ecf20Sopenharmony_ci		test_err("got an error when we shouldn't have");
8978c2ecf20Sopenharmony_ci		goto out;
8988c2ecf20Sopenharmony_ci	}
8998c2ecf20Sopenharmony_ci	if (em->block_start != sectorsize) {
9008c2ecf20Sopenharmony_ci		test_err("expected a real extent, got %llu", em->block_start);
9018c2ecf20Sopenharmony_ci		goto out;
9028c2ecf20Sopenharmony_ci	}
9038c2ecf20Sopenharmony_ci	if (em->start != sectorsize || em->len != sectorsize) {
9048c2ecf20Sopenharmony_ci		test_err(
9058c2ecf20Sopenharmony_ci	"unexpected extent wanted start %u len %u, got start %llu len %llu",
9068c2ecf20Sopenharmony_ci			sectorsize, sectorsize, em->start, em->len);
9078c2ecf20Sopenharmony_ci		goto out;
9088c2ecf20Sopenharmony_ci	}
9098c2ecf20Sopenharmony_ci	if (em->flags != 0) {
9108c2ecf20Sopenharmony_ci		test_err("unexpected flags set, wanted 0 got %lu",
9118c2ecf20Sopenharmony_ci			 em->flags);
9128c2ecf20Sopenharmony_ci		goto out;
9138c2ecf20Sopenharmony_ci	}
9148c2ecf20Sopenharmony_ci	ret = 0;
9158c2ecf20Sopenharmony_ciout:
9168c2ecf20Sopenharmony_ci	if (!IS_ERR(em))
9178c2ecf20Sopenharmony_ci		free_extent_map(em);
9188c2ecf20Sopenharmony_ci	iput(inode);
9198c2ecf20Sopenharmony_ci	btrfs_free_dummy_root(root);
9208c2ecf20Sopenharmony_ci	btrfs_free_dummy_fs_info(fs_info);
9218c2ecf20Sopenharmony_ci	return ret;
9228c2ecf20Sopenharmony_ci}
9238c2ecf20Sopenharmony_ci
9248c2ecf20Sopenharmony_cistatic int test_extent_accounting(u32 sectorsize, u32 nodesize)
9258c2ecf20Sopenharmony_ci{
9268c2ecf20Sopenharmony_ci	struct btrfs_fs_info *fs_info = NULL;
9278c2ecf20Sopenharmony_ci	struct inode *inode = NULL;
9288c2ecf20Sopenharmony_ci	struct btrfs_root *root = NULL;
9298c2ecf20Sopenharmony_ci	int ret = -ENOMEM;
9308c2ecf20Sopenharmony_ci
9318c2ecf20Sopenharmony_ci	test_msg("running outstanding_extents tests");
9328c2ecf20Sopenharmony_ci
9338c2ecf20Sopenharmony_ci	inode = btrfs_new_test_inode();
9348c2ecf20Sopenharmony_ci	if (!inode) {
9358c2ecf20Sopenharmony_ci		test_std_err(TEST_ALLOC_INODE);
9368c2ecf20Sopenharmony_ci		return ret;
9378c2ecf20Sopenharmony_ci	}
9388c2ecf20Sopenharmony_ci
9398c2ecf20Sopenharmony_ci	fs_info = btrfs_alloc_dummy_fs_info(nodesize, sectorsize);
9408c2ecf20Sopenharmony_ci	if (!fs_info) {
9418c2ecf20Sopenharmony_ci		test_std_err(TEST_ALLOC_FS_INFO);
9428c2ecf20Sopenharmony_ci		goto out;
9438c2ecf20Sopenharmony_ci	}
9448c2ecf20Sopenharmony_ci
9458c2ecf20Sopenharmony_ci	root = btrfs_alloc_dummy_root(fs_info);
9468c2ecf20Sopenharmony_ci	if (IS_ERR(root)) {
9478c2ecf20Sopenharmony_ci		test_std_err(TEST_ALLOC_ROOT);
9488c2ecf20Sopenharmony_ci		goto out;
9498c2ecf20Sopenharmony_ci	}
9508c2ecf20Sopenharmony_ci
9518c2ecf20Sopenharmony_ci	BTRFS_I(inode)->root = root;
9528c2ecf20Sopenharmony_ci
9538c2ecf20Sopenharmony_ci	/* [BTRFS_MAX_EXTENT_SIZE] */
9548c2ecf20Sopenharmony_ci	ret = btrfs_set_extent_delalloc(BTRFS_I(inode), 0,
9558c2ecf20Sopenharmony_ci					BTRFS_MAX_EXTENT_SIZE - 1, 0, NULL);
9568c2ecf20Sopenharmony_ci	if (ret) {
9578c2ecf20Sopenharmony_ci		test_err("btrfs_set_extent_delalloc returned %d", ret);
9588c2ecf20Sopenharmony_ci		goto out;
9598c2ecf20Sopenharmony_ci	}
9608c2ecf20Sopenharmony_ci	if (BTRFS_I(inode)->outstanding_extents != 1) {
9618c2ecf20Sopenharmony_ci		ret = -EINVAL;
9628c2ecf20Sopenharmony_ci		test_err("miscount, wanted 1, got %u",
9638c2ecf20Sopenharmony_ci			 BTRFS_I(inode)->outstanding_extents);
9648c2ecf20Sopenharmony_ci		goto out;
9658c2ecf20Sopenharmony_ci	}
9668c2ecf20Sopenharmony_ci
9678c2ecf20Sopenharmony_ci	/* [BTRFS_MAX_EXTENT_SIZE][sectorsize] */
9688c2ecf20Sopenharmony_ci	ret = btrfs_set_extent_delalloc(BTRFS_I(inode), BTRFS_MAX_EXTENT_SIZE,
9698c2ecf20Sopenharmony_ci					BTRFS_MAX_EXTENT_SIZE + sectorsize - 1,
9708c2ecf20Sopenharmony_ci					0, NULL);
9718c2ecf20Sopenharmony_ci	if (ret) {
9728c2ecf20Sopenharmony_ci		test_err("btrfs_set_extent_delalloc returned %d", ret);
9738c2ecf20Sopenharmony_ci		goto out;
9748c2ecf20Sopenharmony_ci	}
9758c2ecf20Sopenharmony_ci	if (BTRFS_I(inode)->outstanding_extents != 2) {
9768c2ecf20Sopenharmony_ci		ret = -EINVAL;
9778c2ecf20Sopenharmony_ci		test_err("miscount, wanted 2, got %u",
9788c2ecf20Sopenharmony_ci			 BTRFS_I(inode)->outstanding_extents);
9798c2ecf20Sopenharmony_ci		goto out;
9808c2ecf20Sopenharmony_ci	}
9818c2ecf20Sopenharmony_ci
9828c2ecf20Sopenharmony_ci	/* [BTRFS_MAX_EXTENT_SIZE/2][sectorsize HOLE][the rest] */
9838c2ecf20Sopenharmony_ci	ret = clear_extent_bit(&BTRFS_I(inode)->io_tree,
9848c2ecf20Sopenharmony_ci			       BTRFS_MAX_EXTENT_SIZE >> 1,
9858c2ecf20Sopenharmony_ci			       (BTRFS_MAX_EXTENT_SIZE >> 1) + sectorsize - 1,
9868c2ecf20Sopenharmony_ci			       EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
9878c2ecf20Sopenharmony_ci			       EXTENT_UPTODATE, 0, 0, NULL);
9888c2ecf20Sopenharmony_ci	if (ret) {
9898c2ecf20Sopenharmony_ci		test_err("clear_extent_bit returned %d", ret);
9908c2ecf20Sopenharmony_ci		goto out;
9918c2ecf20Sopenharmony_ci	}
9928c2ecf20Sopenharmony_ci	if (BTRFS_I(inode)->outstanding_extents != 2) {
9938c2ecf20Sopenharmony_ci		ret = -EINVAL;
9948c2ecf20Sopenharmony_ci		test_err("miscount, wanted 2, got %u",
9958c2ecf20Sopenharmony_ci			 BTRFS_I(inode)->outstanding_extents);
9968c2ecf20Sopenharmony_ci		goto out;
9978c2ecf20Sopenharmony_ci	}
9988c2ecf20Sopenharmony_ci
9998c2ecf20Sopenharmony_ci	/* [BTRFS_MAX_EXTENT_SIZE][sectorsize] */
10008c2ecf20Sopenharmony_ci	ret = btrfs_set_extent_delalloc(BTRFS_I(inode), BTRFS_MAX_EXTENT_SIZE >> 1,
10018c2ecf20Sopenharmony_ci					(BTRFS_MAX_EXTENT_SIZE >> 1)
10028c2ecf20Sopenharmony_ci					+ sectorsize - 1,
10038c2ecf20Sopenharmony_ci					0, NULL);
10048c2ecf20Sopenharmony_ci	if (ret) {
10058c2ecf20Sopenharmony_ci		test_err("btrfs_set_extent_delalloc returned %d", ret);
10068c2ecf20Sopenharmony_ci		goto out;
10078c2ecf20Sopenharmony_ci	}
10088c2ecf20Sopenharmony_ci	if (BTRFS_I(inode)->outstanding_extents != 2) {
10098c2ecf20Sopenharmony_ci		ret = -EINVAL;
10108c2ecf20Sopenharmony_ci		test_err("miscount, wanted 2, got %u",
10118c2ecf20Sopenharmony_ci			 BTRFS_I(inode)->outstanding_extents);
10128c2ecf20Sopenharmony_ci		goto out;
10138c2ecf20Sopenharmony_ci	}
10148c2ecf20Sopenharmony_ci
10158c2ecf20Sopenharmony_ci	/*
10168c2ecf20Sopenharmony_ci	 * [BTRFS_MAX_EXTENT_SIZE+sectorsize][sectorsize HOLE][BTRFS_MAX_EXTENT_SIZE+sectorsize]
10178c2ecf20Sopenharmony_ci	 */
10188c2ecf20Sopenharmony_ci	ret = btrfs_set_extent_delalloc(BTRFS_I(inode),
10198c2ecf20Sopenharmony_ci			BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize,
10208c2ecf20Sopenharmony_ci			(BTRFS_MAX_EXTENT_SIZE << 1) + 3 * sectorsize - 1,
10218c2ecf20Sopenharmony_ci			0, NULL);
10228c2ecf20Sopenharmony_ci	if (ret) {
10238c2ecf20Sopenharmony_ci		test_err("btrfs_set_extent_delalloc returned %d", ret);
10248c2ecf20Sopenharmony_ci		goto out;
10258c2ecf20Sopenharmony_ci	}
10268c2ecf20Sopenharmony_ci	if (BTRFS_I(inode)->outstanding_extents != 4) {
10278c2ecf20Sopenharmony_ci		ret = -EINVAL;
10288c2ecf20Sopenharmony_ci		test_err("miscount, wanted 4, got %u",
10298c2ecf20Sopenharmony_ci			 BTRFS_I(inode)->outstanding_extents);
10308c2ecf20Sopenharmony_ci		goto out;
10318c2ecf20Sopenharmony_ci	}
10328c2ecf20Sopenharmony_ci
10338c2ecf20Sopenharmony_ci	/*
10348c2ecf20Sopenharmony_ci	* [BTRFS_MAX_EXTENT_SIZE+sectorsize][sectorsize][BTRFS_MAX_EXTENT_SIZE+sectorsize]
10358c2ecf20Sopenharmony_ci	*/
10368c2ecf20Sopenharmony_ci	ret = btrfs_set_extent_delalloc(BTRFS_I(inode),
10378c2ecf20Sopenharmony_ci			BTRFS_MAX_EXTENT_SIZE + sectorsize,
10388c2ecf20Sopenharmony_ci			BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, 0, NULL);
10398c2ecf20Sopenharmony_ci	if (ret) {
10408c2ecf20Sopenharmony_ci		test_err("btrfs_set_extent_delalloc returned %d", ret);
10418c2ecf20Sopenharmony_ci		goto out;
10428c2ecf20Sopenharmony_ci	}
10438c2ecf20Sopenharmony_ci	if (BTRFS_I(inode)->outstanding_extents != 3) {
10448c2ecf20Sopenharmony_ci		ret = -EINVAL;
10458c2ecf20Sopenharmony_ci		test_err("miscount, wanted 3, got %u",
10468c2ecf20Sopenharmony_ci			 BTRFS_I(inode)->outstanding_extents);
10478c2ecf20Sopenharmony_ci		goto out;
10488c2ecf20Sopenharmony_ci	}
10498c2ecf20Sopenharmony_ci
10508c2ecf20Sopenharmony_ci	/* [BTRFS_MAX_EXTENT_SIZE+4k][4K HOLE][BTRFS_MAX_EXTENT_SIZE+4k] */
10518c2ecf20Sopenharmony_ci	ret = clear_extent_bit(&BTRFS_I(inode)->io_tree,
10528c2ecf20Sopenharmony_ci			       BTRFS_MAX_EXTENT_SIZE + sectorsize,
10538c2ecf20Sopenharmony_ci			       BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1,
10548c2ecf20Sopenharmony_ci			       EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
10558c2ecf20Sopenharmony_ci			       EXTENT_UPTODATE, 0, 0, NULL);
10568c2ecf20Sopenharmony_ci	if (ret) {
10578c2ecf20Sopenharmony_ci		test_err("clear_extent_bit returned %d", ret);
10588c2ecf20Sopenharmony_ci		goto out;
10598c2ecf20Sopenharmony_ci	}
10608c2ecf20Sopenharmony_ci	if (BTRFS_I(inode)->outstanding_extents != 4) {
10618c2ecf20Sopenharmony_ci		ret = -EINVAL;
10628c2ecf20Sopenharmony_ci		test_err("miscount, wanted 4, got %u",
10638c2ecf20Sopenharmony_ci			 BTRFS_I(inode)->outstanding_extents);
10648c2ecf20Sopenharmony_ci		goto out;
10658c2ecf20Sopenharmony_ci	}
10668c2ecf20Sopenharmony_ci
10678c2ecf20Sopenharmony_ci	/*
10688c2ecf20Sopenharmony_ci	 * Refill the hole again just for good measure, because I thought it
10698c2ecf20Sopenharmony_ci	 * might fail and I'd rather satisfy my paranoia at this point.
10708c2ecf20Sopenharmony_ci	 */
10718c2ecf20Sopenharmony_ci	ret = btrfs_set_extent_delalloc(BTRFS_I(inode),
10728c2ecf20Sopenharmony_ci			BTRFS_MAX_EXTENT_SIZE + sectorsize,
10738c2ecf20Sopenharmony_ci			BTRFS_MAX_EXTENT_SIZE + 2 * sectorsize - 1, 0, NULL);
10748c2ecf20Sopenharmony_ci	if (ret) {
10758c2ecf20Sopenharmony_ci		test_err("btrfs_set_extent_delalloc returned %d", ret);
10768c2ecf20Sopenharmony_ci		goto out;
10778c2ecf20Sopenharmony_ci	}
10788c2ecf20Sopenharmony_ci	if (BTRFS_I(inode)->outstanding_extents != 3) {
10798c2ecf20Sopenharmony_ci		ret = -EINVAL;
10808c2ecf20Sopenharmony_ci		test_err("miscount, wanted 3, got %u",
10818c2ecf20Sopenharmony_ci			 BTRFS_I(inode)->outstanding_extents);
10828c2ecf20Sopenharmony_ci		goto out;
10838c2ecf20Sopenharmony_ci	}
10848c2ecf20Sopenharmony_ci
10858c2ecf20Sopenharmony_ci	/* Empty */
10868c2ecf20Sopenharmony_ci	ret = clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1,
10878c2ecf20Sopenharmony_ci			       EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
10888c2ecf20Sopenharmony_ci			       EXTENT_UPTODATE, 0, 0, NULL);
10898c2ecf20Sopenharmony_ci	if (ret) {
10908c2ecf20Sopenharmony_ci		test_err("clear_extent_bit returned %d", ret);
10918c2ecf20Sopenharmony_ci		goto out;
10928c2ecf20Sopenharmony_ci	}
10938c2ecf20Sopenharmony_ci	if (BTRFS_I(inode)->outstanding_extents) {
10948c2ecf20Sopenharmony_ci		ret = -EINVAL;
10958c2ecf20Sopenharmony_ci		test_err("miscount, wanted 0, got %u",
10968c2ecf20Sopenharmony_ci			 BTRFS_I(inode)->outstanding_extents);
10978c2ecf20Sopenharmony_ci		goto out;
10988c2ecf20Sopenharmony_ci	}
10998c2ecf20Sopenharmony_ci	ret = 0;
11008c2ecf20Sopenharmony_ciout:
11018c2ecf20Sopenharmony_ci	if (ret)
11028c2ecf20Sopenharmony_ci		clear_extent_bit(&BTRFS_I(inode)->io_tree, 0, (u64)-1,
11038c2ecf20Sopenharmony_ci				 EXTENT_DELALLOC | EXTENT_DELALLOC_NEW |
11048c2ecf20Sopenharmony_ci				 EXTENT_UPTODATE, 0, 0, NULL);
11058c2ecf20Sopenharmony_ci	iput(inode);
11068c2ecf20Sopenharmony_ci	btrfs_free_dummy_root(root);
11078c2ecf20Sopenharmony_ci	btrfs_free_dummy_fs_info(fs_info);
11088c2ecf20Sopenharmony_ci	return ret;
11098c2ecf20Sopenharmony_ci}
11108c2ecf20Sopenharmony_ci
11118c2ecf20Sopenharmony_ciint btrfs_test_inodes(u32 sectorsize, u32 nodesize)
11128c2ecf20Sopenharmony_ci{
11138c2ecf20Sopenharmony_ci	int ret;
11148c2ecf20Sopenharmony_ci
11158c2ecf20Sopenharmony_ci	test_msg("running inode tests");
11168c2ecf20Sopenharmony_ci
11178c2ecf20Sopenharmony_ci	set_bit(EXTENT_FLAG_COMPRESSED, &compressed_only);
11188c2ecf20Sopenharmony_ci	set_bit(EXTENT_FLAG_PREALLOC, &prealloc_only);
11198c2ecf20Sopenharmony_ci
11208c2ecf20Sopenharmony_ci	ret = test_btrfs_get_extent(sectorsize, nodesize);
11218c2ecf20Sopenharmony_ci	if (ret)
11228c2ecf20Sopenharmony_ci		return ret;
11238c2ecf20Sopenharmony_ci	ret = test_hole_first(sectorsize, nodesize);
11248c2ecf20Sopenharmony_ci	if (ret)
11258c2ecf20Sopenharmony_ci		return ret;
11268c2ecf20Sopenharmony_ci	return test_extent_accounting(sectorsize, nodesize);
11278c2ecf20Sopenharmony_ci}
1128