162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2015 Facebook.  All rights reserved.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#include <linux/kernel.h>
762306a36Sopenharmony_ci#include <linux/sched/mm.h>
862306a36Sopenharmony_ci#include "messages.h"
962306a36Sopenharmony_ci#include "ctree.h"
1062306a36Sopenharmony_ci#include "disk-io.h"
1162306a36Sopenharmony_ci#include "locking.h"
1262306a36Sopenharmony_ci#include "free-space-tree.h"
1362306a36Sopenharmony_ci#include "transaction.h"
1462306a36Sopenharmony_ci#include "block-group.h"
1562306a36Sopenharmony_ci#include "fs.h"
1662306a36Sopenharmony_ci#include "accessors.h"
1762306a36Sopenharmony_ci#include "extent-tree.h"
1862306a36Sopenharmony_ci#include "root-tree.h"
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_cistatic int __add_block_group_free_space(struct btrfs_trans_handle *trans,
2162306a36Sopenharmony_ci					struct btrfs_block_group *block_group,
2262306a36Sopenharmony_ci					struct btrfs_path *path);
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistatic struct btrfs_root *btrfs_free_space_root(
2562306a36Sopenharmony_ci				struct btrfs_block_group *block_group)
2662306a36Sopenharmony_ci{
2762306a36Sopenharmony_ci	struct btrfs_key key = {
2862306a36Sopenharmony_ci		.objectid = BTRFS_FREE_SPACE_TREE_OBJECTID,
2962306a36Sopenharmony_ci		.type = BTRFS_ROOT_ITEM_KEY,
3062306a36Sopenharmony_ci		.offset = 0,
3162306a36Sopenharmony_ci	};
3262306a36Sopenharmony_ci
3362306a36Sopenharmony_ci	if (btrfs_fs_incompat(block_group->fs_info, EXTENT_TREE_V2))
3462306a36Sopenharmony_ci		key.offset = block_group->global_root_id;
3562306a36Sopenharmony_ci	return btrfs_global_root(block_group->fs_info, &key);
3662306a36Sopenharmony_ci}
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_civoid set_free_space_tree_thresholds(struct btrfs_block_group *cache)
3962306a36Sopenharmony_ci{
4062306a36Sopenharmony_ci	u32 bitmap_range;
4162306a36Sopenharmony_ci	size_t bitmap_size;
4262306a36Sopenharmony_ci	u64 num_bitmaps, total_bitmap_size;
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	if (WARN_ON(cache->length == 0))
4562306a36Sopenharmony_ci		btrfs_warn(cache->fs_info, "block group %llu length is zero",
4662306a36Sopenharmony_ci			   cache->start);
4762306a36Sopenharmony_ci
4862306a36Sopenharmony_ci	/*
4962306a36Sopenharmony_ci	 * We convert to bitmaps when the disk space required for using extents
5062306a36Sopenharmony_ci	 * exceeds that required for using bitmaps.
5162306a36Sopenharmony_ci	 */
5262306a36Sopenharmony_ci	bitmap_range = cache->fs_info->sectorsize * BTRFS_FREE_SPACE_BITMAP_BITS;
5362306a36Sopenharmony_ci	num_bitmaps = div_u64(cache->length + bitmap_range - 1, bitmap_range);
5462306a36Sopenharmony_ci	bitmap_size = sizeof(struct btrfs_item) + BTRFS_FREE_SPACE_BITMAP_SIZE;
5562306a36Sopenharmony_ci	total_bitmap_size = num_bitmaps * bitmap_size;
5662306a36Sopenharmony_ci	cache->bitmap_high_thresh = div_u64(total_bitmap_size,
5762306a36Sopenharmony_ci					    sizeof(struct btrfs_item));
5862306a36Sopenharmony_ci
5962306a36Sopenharmony_ci	/*
6062306a36Sopenharmony_ci	 * We allow for a small buffer between the high threshold and low
6162306a36Sopenharmony_ci	 * threshold to avoid thrashing back and forth between the two formats.
6262306a36Sopenharmony_ci	 */
6362306a36Sopenharmony_ci	if (cache->bitmap_high_thresh > 100)
6462306a36Sopenharmony_ci		cache->bitmap_low_thresh = cache->bitmap_high_thresh - 100;
6562306a36Sopenharmony_ci	else
6662306a36Sopenharmony_ci		cache->bitmap_low_thresh = 0;
6762306a36Sopenharmony_ci}
6862306a36Sopenharmony_ci
6962306a36Sopenharmony_cistatic int add_new_free_space_info(struct btrfs_trans_handle *trans,
7062306a36Sopenharmony_ci				   struct btrfs_block_group *block_group,
7162306a36Sopenharmony_ci				   struct btrfs_path *path)
7262306a36Sopenharmony_ci{
7362306a36Sopenharmony_ci	struct btrfs_root *root = btrfs_free_space_root(block_group);
7462306a36Sopenharmony_ci	struct btrfs_free_space_info *info;
7562306a36Sopenharmony_ci	struct btrfs_key key;
7662306a36Sopenharmony_ci	struct extent_buffer *leaf;
7762306a36Sopenharmony_ci	int ret;
7862306a36Sopenharmony_ci
7962306a36Sopenharmony_ci	key.objectid = block_group->start;
8062306a36Sopenharmony_ci	key.type = BTRFS_FREE_SPACE_INFO_KEY;
8162306a36Sopenharmony_ci	key.offset = block_group->length;
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci	ret = btrfs_insert_empty_item(trans, root, path, &key, sizeof(*info));
8462306a36Sopenharmony_ci	if (ret)
8562306a36Sopenharmony_ci		goto out;
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	leaf = path->nodes[0];
8862306a36Sopenharmony_ci	info = btrfs_item_ptr(leaf, path->slots[0],
8962306a36Sopenharmony_ci			      struct btrfs_free_space_info);
9062306a36Sopenharmony_ci	btrfs_set_free_space_extent_count(leaf, info, 0);
9162306a36Sopenharmony_ci	btrfs_set_free_space_flags(leaf, info, 0);
9262306a36Sopenharmony_ci	btrfs_mark_buffer_dirty(trans, leaf);
9362306a36Sopenharmony_ci
9462306a36Sopenharmony_ci	ret = 0;
9562306a36Sopenharmony_ciout:
9662306a36Sopenharmony_ci	btrfs_release_path(path);
9762306a36Sopenharmony_ci	return ret;
9862306a36Sopenharmony_ci}
9962306a36Sopenharmony_ci
10062306a36Sopenharmony_ciEXPORT_FOR_TESTS
10162306a36Sopenharmony_cistruct btrfs_free_space_info *search_free_space_info(
10262306a36Sopenharmony_ci		struct btrfs_trans_handle *trans,
10362306a36Sopenharmony_ci		struct btrfs_block_group *block_group,
10462306a36Sopenharmony_ci		struct btrfs_path *path, int cow)
10562306a36Sopenharmony_ci{
10662306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = block_group->fs_info;
10762306a36Sopenharmony_ci	struct btrfs_root *root = btrfs_free_space_root(block_group);
10862306a36Sopenharmony_ci	struct btrfs_key key;
10962306a36Sopenharmony_ci	int ret;
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	key.objectid = block_group->start;
11262306a36Sopenharmony_ci	key.type = BTRFS_FREE_SPACE_INFO_KEY;
11362306a36Sopenharmony_ci	key.offset = block_group->length;
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	ret = btrfs_search_slot(trans, root, &key, path, 0, cow);
11662306a36Sopenharmony_ci	if (ret < 0)
11762306a36Sopenharmony_ci		return ERR_PTR(ret);
11862306a36Sopenharmony_ci	if (ret != 0) {
11962306a36Sopenharmony_ci		btrfs_warn(fs_info, "missing free space info for %llu",
12062306a36Sopenharmony_ci			   block_group->start);
12162306a36Sopenharmony_ci		ASSERT(0);
12262306a36Sopenharmony_ci		return ERR_PTR(-ENOENT);
12362306a36Sopenharmony_ci	}
12462306a36Sopenharmony_ci
12562306a36Sopenharmony_ci	return btrfs_item_ptr(path->nodes[0], path->slots[0],
12662306a36Sopenharmony_ci			      struct btrfs_free_space_info);
12762306a36Sopenharmony_ci}
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci/*
13062306a36Sopenharmony_ci * btrfs_search_slot() but we're looking for the greatest key less than the
13162306a36Sopenharmony_ci * passed key.
13262306a36Sopenharmony_ci */
13362306a36Sopenharmony_cistatic int btrfs_search_prev_slot(struct btrfs_trans_handle *trans,
13462306a36Sopenharmony_ci				  struct btrfs_root *root,
13562306a36Sopenharmony_ci				  struct btrfs_key *key, struct btrfs_path *p,
13662306a36Sopenharmony_ci				  int ins_len, int cow)
13762306a36Sopenharmony_ci{
13862306a36Sopenharmony_ci	int ret;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	ret = btrfs_search_slot(trans, root, key, p, ins_len, cow);
14162306a36Sopenharmony_ci	if (ret < 0)
14262306a36Sopenharmony_ci		return ret;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	if (ret == 0) {
14562306a36Sopenharmony_ci		ASSERT(0);
14662306a36Sopenharmony_ci		return -EIO;
14762306a36Sopenharmony_ci	}
14862306a36Sopenharmony_ci
14962306a36Sopenharmony_ci	if (p->slots[0] == 0) {
15062306a36Sopenharmony_ci		ASSERT(0);
15162306a36Sopenharmony_ci		return -EIO;
15262306a36Sopenharmony_ci	}
15362306a36Sopenharmony_ci	p->slots[0]--;
15462306a36Sopenharmony_ci
15562306a36Sopenharmony_ci	return 0;
15662306a36Sopenharmony_ci}
15762306a36Sopenharmony_ci
15862306a36Sopenharmony_cistatic inline u32 free_space_bitmap_size(const struct btrfs_fs_info *fs_info,
15962306a36Sopenharmony_ci					 u64 size)
16062306a36Sopenharmony_ci{
16162306a36Sopenharmony_ci	return DIV_ROUND_UP(size >> fs_info->sectorsize_bits, BITS_PER_BYTE);
16262306a36Sopenharmony_ci}
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_cistatic unsigned long *alloc_bitmap(u32 bitmap_size)
16562306a36Sopenharmony_ci{
16662306a36Sopenharmony_ci	unsigned long *ret;
16762306a36Sopenharmony_ci	unsigned int nofs_flag;
16862306a36Sopenharmony_ci	u32 bitmap_rounded_size = round_up(bitmap_size, sizeof(unsigned long));
16962306a36Sopenharmony_ci
17062306a36Sopenharmony_ci	/*
17162306a36Sopenharmony_ci	 * GFP_NOFS doesn't work with kvmalloc(), but we really can't recurse
17262306a36Sopenharmony_ci	 * into the filesystem as the free space bitmap can be modified in the
17362306a36Sopenharmony_ci	 * critical section of a transaction commit.
17462306a36Sopenharmony_ci	 *
17562306a36Sopenharmony_ci	 * TODO: push the memalloc_nofs_{save,restore}() to the caller where we
17662306a36Sopenharmony_ci	 * know that recursion is unsafe.
17762306a36Sopenharmony_ci	 */
17862306a36Sopenharmony_ci	nofs_flag = memalloc_nofs_save();
17962306a36Sopenharmony_ci	ret = kvzalloc(bitmap_rounded_size, GFP_KERNEL);
18062306a36Sopenharmony_ci	memalloc_nofs_restore(nofs_flag);
18162306a36Sopenharmony_ci	return ret;
18262306a36Sopenharmony_ci}
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_cistatic void le_bitmap_set(unsigned long *map, unsigned int start, int len)
18562306a36Sopenharmony_ci{
18662306a36Sopenharmony_ci	u8 *p = ((u8 *)map) + BIT_BYTE(start);
18762306a36Sopenharmony_ci	const unsigned int size = start + len;
18862306a36Sopenharmony_ci	int bits_to_set = BITS_PER_BYTE - (start % BITS_PER_BYTE);
18962306a36Sopenharmony_ci	u8 mask_to_set = BITMAP_FIRST_BYTE_MASK(start);
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	while (len - bits_to_set >= 0) {
19262306a36Sopenharmony_ci		*p |= mask_to_set;
19362306a36Sopenharmony_ci		len -= bits_to_set;
19462306a36Sopenharmony_ci		bits_to_set = BITS_PER_BYTE;
19562306a36Sopenharmony_ci		mask_to_set = ~0;
19662306a36Sopenharmony_ci		p++;
19762306a36Sopenharmony_ci	}
19862306a36Sopenharmony_ci	if (len) {
19962306a36Sopenharmony_ci		mask_to_set &= BITMAP_LAST_BYTE_MASK(size);
20062306a36Sopenharmony_ci		*p |= mask_to_set;
20162306a36Sopenharmony_ci	}
20262306a36Sopenharmony_ci}
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ciEXPORT_FOR_TESTS
20562306a36Sopenharmony_ciint convert_free_space_to_bitmaps(struct btrfs_trans_handle *trans,
20662306a36Sopenharmony_ci				  struct btrfs_block_group *block_group,
20762306a36Sopenharmony_ci				  struct btrfs_path *path)
20862306a36Sopenharmony_ci{
20962306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = trans->fs_info;
21062306a36Sopenharmony_ci	struct btrfs_root *root = btrfs_free_space_root(block_group);
21162306a36Sopenharmony_ci	struct btrfs_free_space_info *info;
21262306a36Sopenharmony_ci	struct btrfs_key key, found_key;
21362306a36Sopenharmony_ci	struct extent_buffer *leaf;
21462306a36Sopenharmony_ci	unsigned long *bitmap;
21562306a36Sopenharmony_ci	char *bitmap_cursor;
21662306a36Sopenharmony_ci	u64 start, end;
21762306a36Sopenharmony_ci	u64 bitmap_range, i;
21862306a36Sopenharmony_ci	u32 bitmap_size, flags, expected_extent_count;
21962306a36Sopenharmony_ci	u32 extent_count = 0;
22062306a36Sopenharmony_ci	int done = 0, nr;
22162306a36Sopenharmony_ci	int ret;
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci	bitmap_size = free_space_bitmap_size(fs_info, block_group->length);
22462306a36Sopenharmony_ci	bitmap = alloc_bitmap(bitmap_size);
22562306a36Sopenharmony_ci	if (!bitmap) {
22662306a36Sopenharmony_ci		ret = -ENOMEM;
22762306a36Sopenharmony_ci		goto out;
22862306a36Sopenharmony_ci	}
22962306a36Sopenharmony_ci
23062306a36Sopenharmony_ci	start = block_group->start;
23162306a36Sopenharmony_ci	end = block_group->start + block_group->length;
23262306a36Sopenharmony_ci
23362306a36Sopenharmony_ci	key.objectid = end - 1;
23462306a36Sopenharmony_ci	key.type = (u8)-1;
23562306a36Sopenharmony_ci	key.offset = (u64)-1;
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci	while (!done) {
23862306a36Sopenharmony_ci		ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);
23962306a36Sopenharmony_ci		if (ret)
24062306a36Sopenharmony_ci			goto out;
24162306a36Sopenharmony_ci
24262306a36Sopenharmony_ci		leaf = path->nodes[0];
24362306a36Sopenharmony_ci		nr = 0;
24462306a36Sopenharmony_ci		path->slots[0]++;
24562306a36Sopenharmony_ci		while (path->slots[0] > 0) {
24662306a36Sopenharmony_ci			btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0] - 1);
24762306a36Sopenharmony_ci
24862306a36Sopenharmony_ci			if (found_key.type == BTRFS_FREE_SPACE_INFO_KEY) {
24962306a36Sopenharmony_ci				ASSERT(found_key.objectid == block_group->start);
25062306a36Sopenharmony_ci				ASSERT(found_key.offset == block_group->length);
25162306a36Sopenharmony_ci				done = 1;
25262306a36Sopenharmony_ci				break;
25362306a36Sopenharmony_ci			} else if (found_key.type == BTRFS_FREE_SPACE_EXTENT_KEY) {
25462306a36Sopenharmony_ci				u64 first, last;
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci				ASSERT(found_key.objectid >= start);
25762306a36Sopenharmony_ci				ASSERT(found_key.objectid < end);
25862306a36Sopenharmony_ci				ASSERT(found_key.objectid + found_key.offset <= end);
25962306a36Sopenharmony_ci
26062306a36Sopenharmony_ci				first = div_u64(found_key.objectid - start,
26162306a36Sopenharmony_ci						fs_info->sectorsize);
26262306a36Sopenharmony_ci				last = div_u64(found_key.objectid + found_key.offset - start,
26362306a36Sopenharmony_ci					       fs_info->sectorsize);
26462306a36Sopenharmony_ci				le_bitmap_set(bitmap, first, last - first);
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci				extent_count++;
26762306a36Sopenharmony_ci				nr++;
26862306a36Sopenharmony_ci				path->slots[0]--;
26962306a36Sopenharmony_ci			} else {
27062306a36Sopenharmony_ci				ASSERT(0);
27162306a36Sopenharmony_ci			}
27262306a36Sopenharmony_ci		}
27362306a36Sopenharmony_ci
27462306a36Sopenharmony_ci		ret = btrfs_del_items(trans, root, path, path->slots[0], nr);
27562306a36Sopenharmony_ci		if (ret)
27662306a36Sopenharmony_ci			goto out;
27762306a36Sopenharmony_ci		btrfs_release_path(path);
27862306a36Sopenharmony_ci	}
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci	info = search_free_space_info(trans, block_group, path, 1);
28162306a36Sopenharmony_ci	if (IS_ERR(info)) {
28262306a36Sopenharmony_ci		ret = PTR_ERR(info);
28362306a36Sopenharmony_ci		goto out;
28462306a36Sopenharmony_ci	}
28562306a36Sopenharmony_ci	leaf = path->nodes[0];
28662306a36Sopenharmony_ci	flags = btrfs_free_space_flags(leaf, info);
28762306a36Sopenharmony_ci	flags |= BTRFS_FREE_SPACE_USING_BITMAPS;
28862306a36Sopenharmony_ci	btrfs_set_free_space_flags(leaf, info, flags);
28962306a36Sopenharmony_ci	expected_extent_count = btrfs_free_space_extent_count(leaf, info);
29062306a36Sopenharmony_ci	btrfs_mark_buffer_dirty(trans, leaf);
29162306a36Sopenharmony_ci	btrfs_release_path(path);
29262306a36Sopenharmony_ci
29362306a36Sopenharmony_ci	if (extent_count != expected_extent_count) {
29462306a36Sopenharmony_ci		btrfs_err(fs_info,
29562306a36Sopenharmony_ci			  "incorrect extent count for %llu; counted %u, expected %u",
29662306a36Sopenharmony_ci			  block_group->start, extent_count,
29762306a36Sopenharmony_ci			  expected_extent_count);
29862306a36Sopenharmony_ci		ASSERT(0);
29962306a36Sopenharmony_ci		ret = -EIO;
30062306a36Sopenharmony_ci		goto out;
30162306a36Sopenharmony_ci	}
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci	bitmap_cursor = (char *)bitmap;
30462306a36Sopenharmony_ci	bitmap_range = fs_info->sectorsize * BTRFS_FREE_SPACE_BITMAP_BITS;
30562306a36Sopenharmony_ci	i = start;
30662306a36Sopenharmony_ci	while (i < end) {
30762306a36Sopenharmony_ci		unsigned long ptr;
30862306a36Sopenharmony_ci		u64 extent_size;
30962306a36Sopenharmony_ci		u32 data_size;
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci		extent_size = min(end - i, bitmap_range);
31262306a36Sopenharmony_ci		data_size = free_space_bitmap_size(fs_info, extent_size);
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_ci		key.objectid = i;
31562306a36Sopenharmony_ci		key.type = BTRFS_FREE_SPACE_BITMAP_KEY;
31662306a36Sopenharmony_ci		key.offset = extent_size;
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci		ret = btrfs_insert_empty_item(trans, root, path, &key,
31962306a36Sopenharmony_ci					      data_size);
32062306a36Sopenharmony_ci		if (ret)
32162306a36Sopenharmony_ci			goto out;
32262306a36Sopenharmony_ci
32362306a36Sopenharmony_ci		leaf = path->nodes[0];
32462306a36Sopenharmony_ci		ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
32562306a36Sopenharmony_ci		write_extent_buffer(leaf, bitmap_cursor, ptr,
32662306a36Sopenharmony_ci				    data_size);
32762306a36Sopenharmony_ci		btrfs_mark_buffer_dirty(trans, leaf);
32862306a36Sopenharmony_ci		btrfs_release_path(path);
32962306a36Sopenharmony_ci
33062306a36Sopenharmony_ci		i += extent_size;
33162306a36Sopenharmony_ci		bitmap_cursor += data_size;
33262306a36Sopenharmony_ci	}
33362306a36Sopenharmony_ci
33462306a36Sopenharmony_ci	ret = 0;
33562306a36Sopenharmony_ciout:
33662306a36Sopenharmony_ci	kvfree(bitmap);
33762306a36Sopenharmony_ci	if (ret)
33862306a36Sopenharmony_ci		btrfs_abort_transaction(trans, ret);
33962306a36Sopenharmony_ci	return ret;
34062306a36Sopenharmony_ci}
34162306a36Sopenharmony_ci
34262306a36Sopenharmony_ciEXPORT_FOR_TESTS
34362306a36Sopenharmony_ciint convert_free_space_to_extents(struct btrfs_trans_handle *trans,
34462306a36Sopenharmony_ci				  struct btrfs_block_group *block_group,
34562306a36Sopenharmony_ci				  struct btrfs_path *path)
34662306a36Sopenharmony_ci{
34762306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = trans->fs_info;
34862306a36Sopenharmony_ci	struct btrfs_root *root = btrfs_free_space_root(block_group);
34962306a36Sopenharmony_ci	struct btrfs_free_space_info *info;
35062306a36Sopenharmony_ci	struct btrfs_key key, found_key;
35162306a36Sopenharmony_ci	struct extent_buffer *leaf;
35262306a36Sopenharmony_ci	unsigned long *bitmap;
35362306a36Sopenharmony_ci	u64 start, end;
35462306a36Sopenharmony_ci	u32 bitmap_size, flags, expected_extent_count;
35562306a36Sopenharmony_ci	unsigned long nrbits, start_bit, end_bit;
35662306a36Sopenharmony_ci	u32 extent_count = 0;
35762306a36Sopenharmony_ci	int done = 0, nr;
35862306a36Sopenharmony_ci	int ret;
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	bitmap_size = free_space_bitmap_size(fs_info, block_group->length);
36162306a36Sopenharmony_ci	bitmap = alloc_bitmap(bitmap_size);
36262306a36Sopenharmony_ci	if (!bitmap) {
36362306a36Sopenharmony_ci		ret = -ENOMEM;
36462306a36Sopenharmony_ci		goto out;
36562306a36Sopenharmony_ci	}
36662306a36Sopenharmony_ci
36762306a36Sopenharmony_ci	start = block_group->start;
36862306a36Sopenharmony_ci	end = block_group->start + block_group->length;
36962306a36Sopenharmony_ci
37062306a36Sopenharmony_ci	key.objectid = end - 1;
37162306a36Sopenharmony_ci	key.type = (u8)-1;
37262306a36Sopenharmony_ci	key.offset = (u64)-1;
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ci	while (!done) {
37562306a36Sopenharmony_ci		ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);
37662306a36Sopenharmony_ci		if (ret)
37762306a36Sopenharmony_ci			goto out;
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci		leaf = path->nodes[0];
38062306a36Sopenharmony_ci		nr = 0;
38162306a36Sopenharmony_ci		path->slots[0]++;
38262306a36Sopenharmony_ci		while (path->slots[0] > 0) {
38362306a36Sopenharmony_ci			btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0] - 1);
38462306a36Sopenharmony_ci
38562306a36Sopenharmony_ci			if (found_key.type == BTRFS_FREE_SPACE_INFO_KEY) {
38662306a36Sopenharmony_ci				ASSERT(found_key.objectid == block_group->start);
38762306a36Sopenharmony_ci				ASSERT(found_key.offset == block_group->length);
38862306a36Sopenharmony_ci				done = 1;
38962306a36Sopenharmony_ci				break;
39062306a36Sopenharmony_ci			} else if (found_key.type == BTRFS_FREE_SPACE_BITMAP_KEY) {
39162306a36Sopenharmony_ci				unsigned long ptr;
39262306a36Sopenharmony_ci				char *bitmap_cursor;
39362306a36Sopenharmony_ci				u32 bitmap_pos, data_size;
39462306a36Sopenharmony_ci
39562306a36Sopenharmony_ci				ASSERT(found_key.objectid >= start);
39662306a36Sopenharmony_ci				ASSERT(found_key.objectid < end);
39762306a36Sopenharmony_ci				ASSERT(found_key.objectid + found_key.offset <= end);
39862306a36Sopenharmony_ci
39962306a36Sopenharmony_ci				bitmap_pos = div_u64(found_key.objectid - start,
40062306a36Sopenharmony_ci						     fs_info->sectorsize *
40162306a36Sopenharmony_ci						     BITS_PER_BYTE);
40262306a36Sopenharmony_ci				bitmap_cursor = ((char *)bitmap) + bitmap_pos;
40362306a36Sopenharmony_ci				data_size = free_space_bitmap_size(fs_info,
40462306a36Sopenharmony_ci								found_key.offset);
40562306a36Sopenharmony_ci
40662306a36Sopenharmony_ci				ptr = btrfs_item_ptr_offset(leaf, path->slots[0] - 1);
40762306a36Sopenharmony_ci				read_extent_buffer(leaf, bitmap_cursor, ptr,
40862306a36Sopenharmony_ci						   data_size);
40962306a36Sopenharmony_ci
41062306a36Sopenharmony_ci				nr++;
41162306a36Sopenharmony_ci				path->slots[0]--;
41262306a36Sopenharmony_ci			} else {
41362306a36Sopenharmony_ci				ASSERT(0);
41462306a36Sopenharmony_ci			}
41562306a36Sopenharmony_ci		}
41662306a36Sopenharmony_ci
41762306a36Sopenharmony_ci		ret = btrfs_del_items(trans, root, path, path->slots[0], nr);
41862306a36Sopenharmony_ci		if (ret)
41962306a36Sopenharmony_ci			goto out;
42062306a36Sopenharmony_ci		btrfs_release_path(path);
42162306a36Sopenharmony_ci	}
42262306a36Sopenharmony_ci
42362306a36Sopenharmony_ci	info = search_free_space_info(trans, block_group, path, 1);
42462306a36Sopenharmony_ci	if (IS_ERR(info)) {
42562306a36Sopenharmony_ci		ret = PTR_ERR(info);
42662306a36Sopenharmony_ci		goto out;
42762306a36Sopenharmony_ci	}
42862306a36Sopenharmony_ci	leaf = path->nodes[0];
42962306a36Sopenharmony_ci	flags = btrfs_free_space_flags(leaf, info);
43062306a36Sopenharmony_ci	flags &= ~BTRFS_FREE_SPACE_USING_BITMAPS;
43162306a36Sopenharmony_ci	btrfs_set_free_space_flags(leaf, info, flags);
43262306a36Sopenharmony_ci	expected_extent_count = btrfs_free_space_extent_count(leaf, info);
43362306a36Sopenharmony_ci	btrfs_mark_buffer_dirty(trans, leaf);
43462306a36Sopenharmony_ci	btrfs_release_path(path);
43562306a36Sopenharmony_ci
43662306a36Sopenharmony_ci	nrbits = block_group->length >> block_group->fs_info->sectorsize_bits;
43762306a36Sopenharmony_ci	start_bit = find_next_bit_le(bitmap, nrbits, 0);
43862306a36Sopenharmony_ci
43962306a36Sopenharmony_ci	while (start_bit < nrbits) {
44062306a36Sopenharmony_ci		end_bit = find_next_zero_bit_le(bitmap, nrbits, start_bit);
44162306a36Sopenharmony_ci		ASSERT(start_bit < end_bit);
44262306a36Sopenharmony_ci
44362306a36Sopenharmony_ci		key.objectid = start + start_bit * block_group->fs_info->sectorsize;
44462306a36Sopenharmony_ci		key.type = BTRFS_FREE_SPACE_EXTENT_KEY;
44562306a36Sopenharmony_ci		key.offset = (end_bit - start_bit) * block_group->fs_info->sectorsize;
44662306a36Sopenharmony_ci
44762306a36Sopenharmony_ci		ret = btrfs_insert_empty_item(trans, root, path, &key, 0);
44862306a36Sopenharmony_ci		if (ret)
44962306a36Sopenharmony_ci			goto out;
45062306a36Sopenharmony_ci		btrfs_release_path(path);
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ci		extent_count++;
45362306a36Sopenharmony_ci
45462306a36Sopenharmony_ci		start_bit = find_next_bit_le(bitmap, nrbits, end_bit);
45562306a36Sopenharmony_ci	}
45662306a36Sopenharmony_ci
45762306a36Sopenharmony_ci	if (extent_count != expected_extent_count) {
45862306a36Sopenharmony_ci		btrfs_err(fs_info,
45962306a36Sopenharmony_ci			  "incorrect extent count for %llu; counted %u, expected %u",
46062306a36Sopenharmony_ci			  block_group->start, extent_count,
46162306a36Sopenharmony_ci			  expected_extent_count);
46262306a36Sopenharmony_ci		ASSERT(0);
46362306a36Sopenharmony_ci		ret = -EIO;
46462306a36Sopenharmony_ci		goto out;
46562306a36Sopenharmony_ci	}
46662306a36Sopenharmony_ci
46762306a36Sopenharmony_ci	ret = 0;
46862306a36Sopenharmony_ciout:
46962306a36Sopenharmony_ci	kvfree(bitmap);
47062306a36Sopenharmony_ci	if (ret)
47162306a36Sopenharmony_ci		btrfs_abort_transaction(trans, ret);
47262306a36Sopenharmony_ci	return ret;
47362306a36Sopenharmony_ci}
47462306a36Sopenharmony_ci
47562306a36Sopenharmony_cistatic int update_free_space_extent_count(struct btrfs_trans_handle *trans,
47662306a36Sopenharmony_ci					  struct btrfs_block_group *block_group,
47762306a36Sopenharmony_ci					  struct btrfs_path *path,
47862306a36Sopenharmony_ci					  int new_extents)
47962306a36Sopenharmony_ci{
48062306a36Sopenharmony_ci	struct btrfs_free_space_info *info;
48162306a36Sopenharmony_ci	u32 flags;
48262306a36Sopenharmony_ci	u32 extent_count;
48362306a36Sopenharmony_ci	int ret = 0;
48462306a36Sopenharmony_ci
48562306a36Sopenharmony_ci	if (new_extents == 0)
48662306a36Sopenharmony_ci		return 0;
48762306a36Sopenharmony_ci
48862306a36Sopenharmony_ci	info = search_free_space_info(trans, block_group, path, 1);
48962306a36Sopenharmony_ci	if (IS_ERR(info)) {
49062306a36Sopenharmony_ci		ret = PTR_ERR(info);
49162306a36Sopenharmony_ci		goto out;
49262306a36Sopenharmony_ci	}
49362306a36Sopenharmony_ci	flags = btrfs_free_space_flags(path->nodes[0], info);
49462306a36Sopenharmony_ci	extent_count = btrfs_free_space_extent_count(path->nodes[0], info);
49562306a36Sopenharmony_ci
49662306a36Sopenharmony_ci	extent_count += new_extents;
49762306a36Sopenharmony_ci	btrfs_set_free_space_extent_count(path->nodes[0], info, extent_count);
49862306a36Sopenharmony_ci	btrfs_mark_buffer_dirty(trans, path->nodes[0]);
49962306a36Sopenharmony_ci	btrfs_release_path(path);
50062306a36Sopenharmony_ci
50162306a36Sopenharmony_ci	if (!(flags & BTRFS_FREE_SPACE_USING_BITMAPS) &&
50262306a36Sopenharmony_ci	    extent_count > block_group->bitmap_high_thresh) {
50362306a36Sopenharmony_ci		ret = convert_free_space_to_bitmaps(trans, block_group, path);
50462306a36Sopenharmony_ci	} else if ((flags & BTRFS_FREE_SPACE_USING_BITMAPS) &&
50562306a36Sopenharmony_ci		   extent_count < block_group->bitmap_low_thresh) {
50662306a36Sopenharmony_ci		ret = convert_free_space_to_extents(trans, block_group, path);
50762306a36Sopenharmony_ci	}
50862306a36Sopenharmony_ci
50962306a36Sopenharmony_ciout:
51062306a36Sopenharmony_ci	return ret;
51162306a36Sopenharmony_ci}
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_ciEXPORT_FOR_TESTS
51462306a36Sopenharmony_ciint free_space_test_bit(struct btrfs_block_group *block_group,
51562306a36Sopenharmony_ci			struct btrfs_path *path, u64 offset)
51662306a36Sopenharmony_ci{
51762306a36Sopenharmony_ci	struct extent_buffer *leaf;
51862306a36Sopenharmony_ci	struct btrfs_key key;
51962306a36Sopenharmony_ci	u64 found_start, found_end;
52062306a36Sopenharmony_ci	unsigned long ptr, i;
52162306a36Sopenharmony_ci
52262306a36Sopenharmony_ci	leaf = path->nodes[0];
52362306a36Sopenharmony_ci	btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
52462306a36Sopenharmony_ci	ASSERT(key.type == BTRFS_FREE_SPACE_BITMAP_KEY);
52562306a36Sopenharmony_ci
52662306a36Sopenharmony_ci	found_start = key.objectid;
52762306a36Sopenharmony_ci	found_end = key.objectid + key.offset;
52862306a36Sopenharmony_ci	ASSERT(offset >= found_start && offset < found_end);
52962306a36Sopenharmony_ci
53062306a36Sopenharmony_ci	ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
53162306a36Sopenharmony_ci	i = div_u64(offset - found_start,
53262306a36Sopenharmony_ci		    block_group->fs_info->sectorsize);
53362306a36Sopenharmony_ci	return !!extent_buffer_test_bit(leaf, ptr, i);
53462306a36Sopenharmony_ci}
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_cistatic void free_space_set_bits(struct btrfs_trans_handle *trans,
53762306a36Sopenharmony_ci				struct btrfs_block_group *block_group,
53862306a36Sopenharmony_ci				struct btrfs_path *path, u64 *start, u64 *size,
53962306a36Sopenharmony_ci				int bit)
54062306a36Sopenharmony_ci{
54162306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = block_group->fs_info;
54262306a36Sopenharmony_ci	struct extent_buffer *leaf;
54362306a36Sopenharmony_ci	struct btrfs_key key;
54462306a36Sopenharmony_ci	u64 end = *start + *size;
54562306a36Sopenharmony_ci	u64 found_start, found_end;
54662306a36Sopenharmony_ci	unsigned long ptr, first, last;
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	leaf = path->nodes[0];
54962306a36Sopenharmony_ci	btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
55062306a36Sopenharmony_ci	ASSERT(key.type == BTRFS_FREE_SPACE_BITMAP_KEY);
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_ci	found_start = key.objectid;
55362306a36Sopenharmony_ci	found_end = key.objectid + key.offset;
55462306a36Sopenharmony_ci	ASSERT(*start >= found_start && *start < found_end);
55562306a36Sopenharmony_ci	ASSERT(end > found_start);
55662306a36Sopenharmony_ci
55762306a36Sopenharmony_ci	if (end > found_end)
55862306a36Sopenharmony_ci		end = found_end;
55962306a36Sopenharmony_ci
56062306a36Sopenharmony_ci	ptr = btrfs_item_ptr_offset(leaf, path->slots[0]);
56162306a36Sopenharmony_ci	first = (*start - found_start) >> fs_info->sectorsize_bits;
56262306a36Sopenharmony_ci	last = (end - found_start) >> fs_info->sectorsize_bits;
56362306a36Sopenharmony_ci	if (bit)
56462306a36Sopenharmony_ci		extent_buffer_bitmap_set(leaf, ptr, first, last - first);
56562306a36Sopenharmony_ci	else
56662306a36Sopenharmony_ci		extent_buffer_bitmap_clear(leaf, ptr, first, last - first);
56762306a36Sopenharmony_ci	btrfs_mark_buffer_dirty(trans, leaf);
56862306a36Sopenharmony_ci
56962306a36Sopenharmony_ci	*size -= end - *start;
57062306a36Sopenharmony_ci	*start = end;
57162306a36Sopenharmony_ci}
57262306a36Sopenharmony_ci
57362306a36Sopenharmony_ci/*
57462306a36Sopenharmony_ci * We can't use btrfs_next_item() in modify_free_space_bitmap() because
57562306a36Sopenharmony_ci * btrfs_next_leaf() doesn't get the path for writing. We can forgo the fancy
57662306a36Sopenharmony_ci * tree walking in btrfs_next_leaf() anyways because we know exactly what we're
57762306a36Sopenharmony_ci * looking for.
57862306a36Sopenharmony_ci */
57962306a36Sopenharmony_cistatic int free_space_next_bitmap(struct btrfs_trans_handle *trans,
58062306a36Sopenharmony_ci				  struct btrfs_root *root, struct btrfs_path *p)
58162306a36Sopenharmony_ci{
58262306a36Sopenharmony_ci	struct btrfs_key key;
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci	if (p->slots[0] + 1 < btrfs_header_nritems(p->nodes[0])) {
58562306a36Sopenharmony_ci		p->slots[0]++;
58662306a36Sopenharmony_ci		return 0;
58762306a36Sopenharmony_ci	}
58862306a36Sopenharmony_ci
58962306a36Sopenharmony_ci	btrfs_item_key_to_cpu(p->nodes[0], &key, p->slots[0]);
59062306a36Sopenharmony_ci	btrfs_release_path(p);
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci	key.objectid += key.offset;
59362306a36Sopenharmony_ci	key.type = (u8)-1;
59462306a36Sopenharmony_ci	key.offset = (u64)-1;
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_ci	return btrfs_search_prev_slot(trans, root, &key, p, 0, 1);
59762306a36Sopenharmony_ci}
59862306a36Sopenharmony_ci
59962306a36Sopenharmony_ci/*
60062306a36Sopenharmony_ci * If remove is 1, then we are removing free space, thus clearing bits in the
60162306a36Sopenharmony_ci * bitmap. If remove is 0, then we are adding free space, thus setting bits in
60262306a36Sopenharmony_ci * the bitmap.
60362306a36Sopenharmony_ci */
60462306a36Sopenharmony_cistatic int modify_free_space_bitmap(struct btrfs_trans_handle *trans,
60562306a36Sopenharmony_ci				    struct btrfs_block_group *block_group,
60662306a36Sopenharmony_ci				    struct btrfs_path *path,
60762306a36Sopenharmony_ci				    u64 start, u64 size, int remove)
60862306a36Sopenharmony_ci{
60962306a36Sopenharmony_ci	struct btrfs_root *root = btrfs_free_space_root(block_group);
61062306a36Sopenharmony_ci	struct btrfs_key key;
61162306a36Sopenharmony_ci	u64 end = start + size;
61262306a36Sopenharmony_ci	u64 cur_start, cur_size;
61362306a36Sopenharmony_ci	int prev_bit, next_bit;
61462306a36Sopenharmony_ci	int new_extents;
61562306a36Sopenharmony_ci	int ret;
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_ci	/*
61862306a36Sopenharmony_ci	 * Read the bit for the block immediately before the extent of space if
61962306a36Sopenharmony_ci	 * that block is within the block group.
62062306a36Sopenharmony_ci	 */
62162306a36Sopenharmony_ci	if (start > block_group->start) {
62262306a36Sopenharmony_ci		u64 prev_block = start - block_group->fs_info->sectorsize;
62362306a36Sopenharmony_ci
62462306a36Sopenharmony_ci		key.objectid = prev_block;
62562306a36Sopenharmony_ci		key.type = (u8)-1;
62662306a36Sopenharmony_ci		key.offset = (u64)-1;
62762306a36Sopenharmony_ci
62862306a36Sopenharmony_ci		ret = btrfs_search_prev_slot(trans, root, &key, path, 0, 1);
62962306a36Sopenharmony_ci		if (ret)
63062306a36Sopenharmony_ci			goto out;
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_ci		prev_bit = free_space_test_bit(block_group, path, prev_block);
63362306a36Sopenharmony_ci
63462306a36Sopenharmony_ci		/* The previous block may have been in the previous bitmap. */
63562306a36Sopenharmony_ci		btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
63662306a36Sopenharmony_ci		if (start >= key.objectid + key.offset) {
63762306a36Sopenharmony_ci			ret = free_space_next_bitmap(trans, root, path);
63862306a36Sopenharmony_ci			if (ret)
63962306a36Sopenharmony_ci				goto out;
64062306a36Sopenharmony_ci		}
64162306a36Sopenharmony_ci	} else {
64262306a36Sopenharmony_ci		key.objectid = start;
64362306a36Sopenharmony_ci		key.type = (u8)-1;
64462306a36Sopenharmony_ci		key.offset = (u64)-1;
64562306a36Sopenharmony_ci
64662306a36Sopenharmony_ci		ret = btrfs_search_prev_slot(trans, root, &key, path, 0, 1);
64762306a36Sopenharmony_ci		if (ret)
64862306a36Sopenharmony_ci			goto out;
64962306a36Sopenharmony_ci
65062306a36Sopenharmony_ci		prev_bit = -1;
65162306a36Sopenharmony_ci	}
65262306a36Sopenharmony_ci
65362306a36Sopenharmony_ci	/*
65462306a36Sopenharmony_ci	 * Iterate over all of the bitmaps overlapped by the extent of space,
65562306a36Sopenharmony_ci	 * clearing/setting bits as required.
65662306a36Sopenharmony_ci	 */
65762306a36Sopenharmony_ci	cur_start = start;
65862306a36Sopenharmony_ci	cur_size = size;
65962306a36Sopenharmony_ci	while (1) {
66062306a36Sopenharmony_ci		free_space_set_bits(trans, block_group, path, &cur_start, &cur_size,
66162306a36Sopenharmony_ci				    !remove);
66262306a36Sopenharmony_ci		if (cur_size == 0)
66362306a36Sopenharmony_ci			break;
66462306a36Sopenharmony_ci		ret = free_space_next_bitmap(trans, root, path);
66562306a36Sopenharmony_ci		if (ret)
66662306a36Sopenharmony_ci			goto out;
66762306a36Sopenharmony_ci	}
66862306a36Sopenharmony_ci
66962306a36Sopenharmony_ci	/*
67062306a36Sopenharmony_ci	 * Read the bit for the block immediately after the extent of space if
67162306a36Sopenharmony_ci	 * that block is within the block group.
67262306a36Sopenharmony_ci	 */
67362306a36Sopenharmony_ci	if (end < block_group->start + block_group->length) {
67462306a36Sopenharmony_ci		/* The next block may be in the next bitmap. */
67562306a36Sopenharmony_ci		btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
67662306a36Sopenharmony_ci		if (end >= key.objectid + key.offset) {
67762306a36Sopenharmony_ci			ret = free_space_next_bitmap(trans, root, path);
67862306a36Sopenharmony_ci			if (ret)
67962306a36Sopenharmony_ci				goto out;
68062306a36Sopenharmony_ci		}
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci		next_bit = free_space_test_bit(block_group, path, end);
68362306a36Sopenharmony_ci	} else {
68462306a36Sopenharmony_ci		next_bit = -1;
68562306a36Sopenharmony_ci	}
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_ci	if (remove) {
68862306a36Sopenharmony_ci		new_extents = -1;
68962306a36Sopenharmony_ci		if (prev_bit == 1) {
69062306a36Sopenharmony_ci			/* Leftover on the left. */
69162306a36Sopenharmony_ci			new_extents++;
69262306a36Sopenharmony_ci		}
69362306a36Sopenharmony_ci		if (next_bit == 1) {
69462306a36Sopenharmony_ci			/* Leftover on the right. */
69562306a36Sopenharmony_ci			new_extents++;
69662306a36Sopenharmony_ci		}
69762306a36Sopenharmony_ci	} else {
69862306a36Sopenharmony_ci		new_extents = 1;
69962306a36Sopenharmony_ci		if (prev_bit == 1) {
70062306a36Sopenharmony_ci			/* Merging with neighbor on the left. */
70162306a36Sopenharmony_ci			new_extents--;
70262306a36Sopenharmony_ci		}
70362306a36Sopenharmony_ci		if (next_bit == 1) {
70462306a36Sopenharmony_ci			/* Merging with neighbor on the right. */
70562306a36Sopenharmony_ci			new_extents--;
70662306a36Sopenharmony_ci		}
70762306a36Sopenharmony_ci	}
70862306a36Sopenharmony_ci
70962306a36Sopenharmony_ci	btrfs_release_path(path);
71062306a36Sopenharmony_ci	ret = update_free_space_extent_count(trans, block_group, path,
71162306a36Sopenharmony_ci					     new_extents);
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ciout:
71462306a36Sopenharmony_ci	return ret;
71562306a36Sopenharmony_ci}
71662306a36Sopenharmony_ci
71762306a36Sopenharmony_cistatic int remove_free_space_extent(struct btrfs_trans_handle *trans,
71862306a36Sopenharmony_ci				    struct btrfs_block_group *block_group,
71962306a36Sopenharmony_ci				    struct btrfs_path *path,
72062306a36Sopenharmony_ci				    u64 start, u64 size)
72162306a36Sopenharmony_ci{
72262306a36Sopenharmony_ci	struct btrfs_root *root = btrfs_free_space_root(block_group);
72362306a36Sopenharmony_ci	struct btrfs_key key;
72462306a36Sopenharmony_ci	u64 found_start, found_end;
72562306a36Sopenharmony_ci	u64 end = start + size;
72662306a36Sopenharmony_ci	int new_extents = -1;
72762306a36Sopenharmony_ci	int ret;
72862306a36Sopenharmony_ci
72962306a36Sopenharmony_ci	key.objectid = start;
73062306a36Sopenharmony_ci	key.type = (u8)-1;
73162306a36Sopenharmony_ci	key.offset = (u64)-1;
73262306a36Sopenharmony_ci
73362306a36Sopenharmony_ci	ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);
73462306a36Sopenharmony_ci	if (ret)
73562306a36Sopenharmony_ci		goto out;
73662306a36Sopenharmony_ci
73762306a36Sopenharmony_ci	btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
73862306a36Sopenharmony_ci
73962306a36Sopenharmony_ci	ASSERT(key.type == BTRFS_FREE_SPACE_EXTENT_KEY);
74062306a36Sopenharmony_ci
74162306a36Sopenharmony_ci	found_start = key.objectid;
74262306a36Sopenharmony_ci	found_end = key.objectid + key.offset;
74362306a36Sopenharmony_ci	ASSERT(start >= found_start && end <= found_end);
74462306a36Sopenharmony_ci
74562306a36Sopenharmony_ci	/*
74662306a36Sopenharmony_ci	 * Okay, now that we've found the free space extent which contains the
74762306a36Sopenharmony_ci	 * free space that we are removing, there are four cases:
74862306a36Sopenharmony_ci	 *
74962306a36Sopenharmony_ci	 * 1. We're using the whole extent: delete the key we found and
75062306a36Sopenharmony_ci	 * decrement the free space extent count.
75162306a36Sopenharmony_ci	 * 2. We are using part of the extent starting at the beginning: delete
75262306a36Sopenharmony_ci	 * the key we found and insert a new key representing the leftover at
75362306a36Sopenharmony_ci	 * the end. There is no net change in the number of extents.
75462306a36Sopenharmony_ci	 * 3. We are using part of the extent ending at the end: delete the key
75562306a36Sopenharmony_ci	 * we found and insert a new key representing the leftover at the
75662306a36Sopenharmony_ci	 * beginning. There is no net change in the number of extents.
75762306a36Sopenharmony_ci	 * 4. We are using part of the extent in the middle: delete the key we
75862306a36Sopenharmony_ci	 * found and insert two new keys representing the leftovers on each
75962306a36Sopenharmony_ci	 * side. Where we used to have one extent, we now have two, so increment
76062306a36Sopenharmony_ci	 * the extent count. We may need to convert the block group to bitmaps
76162306a36Sopenharmony_ci	 * as a result.
76262306a36Sopenharmony_ci	 */
76362306a36Sopenharmony_ci
76462306a36Sopenharmony_ci	/* Delete the existing key (cases 1-4). */
76562306a36Sopenharmony_ci	ret = btrfs_del_item(trans, root, path);
76662306a36Sopenharmony_ci	if (ret)
76762306a36Sopenharmony_ci		goto out;
76862306a36Sopenharmony_ci
76962306a36Sopenharmony_ci	/* Add a key for leftovers at the beginning (cases 3 and 4). */
77062306a36Sopenharmony_ci	if (start > found_start) {
77162306a36Sopenharmony_ci		key.objectid = found_start;
77262306a36Sopenharmony_ci		key.type = BTRFS_FREE_SPACE_EXTENT_KEY;
77362306a36Sopenharmony_ci		key.offset = start - found_start;
77462306a36Sopenharmony_ci
77562306a36Sopenharmony_ci		btrfs_release_path(path);
77662306a36Sopenharmony_ci		ret = btrfs_insert_empty_item(trans, root, path, &key, 0);
77762306a36Sopenharmony_ci		if (ret)
77862306a36Sopenharmony_ci			goto out;
77962306a36Sopenharmony_ci		new_extents++;
78062306a36Sopenharmony_ci	}
78162306a36Sopenharmony_ci
78262306a36Sopenharmony_ci	/* Add a key for leftovers at the end (cases 2 and 4). */
78362306a36Sopenharmony_ci	if (end < found_end) {
78462306a36Sopenharmony_ci		key.objectid = end;
78562306a36Sopenharmony_ci		key.type = BTRFS_FREE_SPACE_EXTENT_KEY;
78662306a36Sopenharmony_ci		key.offset = found_end - end;
78762306a36Sopenharmony_ci
78862306a36Sopenharmony_ci		btrfs_release_path(path);
78962306a36Sopenharmony_ci		ret = btrfs_insert_empty_item(trans, root, path, &key, 0);
79062306a36Sopenharmony_ci		if (ret)
79162306a36Sopenharmony_ci			goto out;
79262306a36Sopenharmony_ci		new_extents++;
79362306a36Sopenharmony_ci	}
79462306a36Sopenharmony_ci
79562306a36Sopenharmony_ci	btrfs_release_path(path);
79662306a36Sopenharmony_ci	ret = update_free_space_extent_count(trans, block_group, path,
79762306a36Sopenharmony_ci					     new_extents);
79862306a36Sopenharmony_ci
79962306a36Sopenharmony_ciout:
80062306a36Sopenharmony_ci	return ret;
80162306a36Sopenharmony_ci}
80262306a36Sopenharmony_ci
80362306a36Sopenharmony_ciEXPORT_FOR_TESTS
80462306a36Sopenharmony_ciint __remove_from_free_space_tree(struct btrfs_trans_handle *trans,
80562306a36Sopenharmony_ci				  struct btrfs_block_group *block_group,
80662306a36Sopenharmony_ci				  struct btrfs_path *path, u64 start, u64 size)
80762306a36Sopenharmony_ci{
80862306a36Sopenharmony_ci	struct btrfs_free_space_info *info;
80962306a36Sopenharmony_ci	u32 flags;
81062306a36Sopenharmony_ci	int ret;
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci	if (test_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &block_group->runtime_flags)) {
81362306a36Sopenharmony_ci		ret = __add_block_group_free_space(trans, block_group, path);
81462306a36Sopenharmony_ci		if (ret)
81562306a36Sopenharmony_ci			return ret;
81662306a36Sopenharmony_ci	}
81762306a36Sopenharmony_ci
81862306a36Sopenharmony_ci	info = search_free_space_info(NULL, block_group, path, 0);
81962306a36Sopenharmony_ci	if (IS_ERR(info))
82062306a36Sopenharmony_ci		return PTR_ERR(info);
82162306a36Sopenharmony_ci	flags = btrfs_free_space_flags(path->nodes[0], info);
82262306a36Sopenharmony_ci	btrfs_release_path(path);
82362306a36Sopenharmony_ci
82462306a36Sopenharmony_ci	if (flags & BTRFS_FREE_SPACE_USING_BITMAPS) {
82562306a36Sopenharmony_ci		return modify_free_space_bitmap(trans, block_group, path,
82662306a36Sopenharmony_ci						start, size, 1);
82762306a36Sopenharmony_ci	} else {
82862306a36Sopenharmony_ci		return remove_free_space_extent(trans, block_group, path,
82962306a36Sopenharmony_ci						start, size);
83062306a36Sopenharmony_ci	}
83162306a36Sopenharmony_ci}
83262306a36Sopenharmony_ci
83362306a36Sopenharmony_ciint remove_from_free_space_tree(struct btrfs_trans_handle *trans,
83462306a36Sopenharmony_ci				u64 start, u64 size)
83562306a36Sopenharmony_ci{
83662306a36Sopenharmony_ci	struct btrfs_block_group *block_group;
83762306a36Sopenharmony_ci	struct btrfs_path *path;
83862306a36Sopenharmony_ci	int ret;
83962306a36Sopenharmony_ci
84062306a36Sopenharmony_ci	if (!btrfs_fs_compat_ro(trans->fs_info, FREE_SPACE_TREE))
84162306a36Sopenharmony_ci		return 0;
84262306a36Sopenharmony_ci
84362306a36Sopenharmony_ci	path = btrfs_alloc_path();
84462306a36Sopenharmony_ci	if (!path) {
84562306a36Sopenharmony_ci		ret = -ENOMEM;
84662306a36Sopenharmony_ci		goto out;
84762306a36Sopenharmony_ci	}
84862306a36Sopenharmony_ci
84962306a36Sopenharmony_ci	block_group = btrfs_lookup_block_group(trans->fs_info, start);
85062306a36Sopenharmony_ci	if (!block_group) {
85162306a36Sopenharmony_ci		ASSERT(0);
85262306a36Sopenharmony_ci		ret = -ENOENT;
85362306a36Sopenharmony_ci		goto out;
85462306a36Sopenharmony_ci	}
85562306a36Sopenharmony_ci
85662306a36Sopenharmony_ci	mutex_lock(&block_group->free_space_lock);
85762306a36Sopenharmony_ci	ret = __remove_from_free_space_tree(trans, block_group, path, start,
85862306a36Sopenharmony_ci					    size);
85962306a36Sopenharmony_ci	mutex_unlock(&block_group->free_space_lock);
86062306a36Sopenharmony_ci
86162306a36Sopenharmony_ci	btrfs_put_block_group(block_group);
86262306a36Sopenharmony_ciout:
86362306a36Sopenharmony_ci	btrfs_free_path(path);
86462306a36Sopenharmony_ci	if (ret)
86562306a36Sopenharmony_ci		btrfs_abort_transaction(trans, ret);
86662306a36Sopenharmony_ci	return ret;
86762306a36Sopenharmony_ci}
86862306a36Sopenharmony_ci
86962306a36Sopenharmony_cistatic int add_free_space_extent(struct btrfs_trans_handle *trans,
87062306a36Sopenharmony_ci				 struct btrfs_block_group *block_group,
87162306a36Sopenharmony_ci				 struct btrfs_path *path,
87262306a36Sopenharmony_ci				 u64 start, u64 size)
87362306a36Sopenharmony_ci{
87462306a36Sopenharmony_ci	struct btrfs_root *root = btrfs_free_space_root(block_group);
87562306a36Sopenharmony_ci	struct btrfs_key key, new_key;
87662306a36Sopenharmony_ci	u64 found_start, found_end;
87762306a36Sopenharmony_ci	u64 end = start + size;
87862306a36Sopenharmony_ci	int new_extents = 1;
87962306a36Sopenharmony_ci	int ret;
88062306a36Sopenharmony_ci
88162306a36Sopenharmony_ci	/*
88262306a36Sopenharmony_ci	 * We are adding a new extent of free space, but we need to merge
88362306a36Sopenharmony_ci	 * extents. There are four cases here:
88462306a36Sopenharmony_ci	 *
88562306a36Sopenharmony_ci	 * 1. The new extent does not have any immediate neighbors to merge
88662306a36Sopenharmony_ci	 * with: add the new key and increment the free space extent count. We
88762306a36Sopenharmony_ci	 * may need to convert the block group to bitmaps as a result.
88862306a36Sopenharmony_ci	 * 2. The new extent has an immediate neighbor before it: remove the
88962306a36Sopenharmony_ci	 * previous key and insert a new key combining both of them. There is no
89062306a36Sopenharmony_ci	 * net change in the number of extents.
89162306a36Sopenharmony_ci	 * 3. The new extent has an immediate neighbor after it: remove the next
89262306a36Sopenharmony_ci	 * key and insert a new key combining both of them. There is no net
89362306a36Sopenharmony_ci	 * change in the number of extents.
89462306a36Sopenharmony_ci	 * 4. The new extent has immediate neighbors on both sides: remove both
89562306a36Sopenharmony_ci	 * of the keys and insert a new key combining all of them. Where we used
89662306a36Sopenharmony_ci	 * to have two extents, we now have one, so decrement the extent count.
89762306a36Sopenharmony_ci	 */
89862306a36Sopenharmony_ci
89962306a36Sopenharmony_ci	new_key.objectid = start;
90062306a36Sopenharmony_ci	new_key.type = BTRFS_FREE_SPACE_EXTENT_KEY;
90162306a36Sopenharmony_ci	new_key.offset = size;
90262306a36Sopenharmony_ci
90362306a36Sopenharmony_ci	/* Search for a neighbor on the left. */
90462306a36Sopenharmony_ci	if (start == block_group->start)
90562306a36Sopenharmony_ci		goto right;
90662306a36Sopenharmony_ci	key.objectid = start - 1;
90762306a36Sopenharmony_ci	key.type = (u8)-1;
90862306a36Sopenharmony_ci	key.offset = (u64)-1;
90962306a36Sopenharmony_ci
91062306a36Sopenharmony_ci	ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);
91162306a36Sopenharmony_ci	if (ret)
91262306a36Sopenharmony_ci		goto out;
91362306a36Sopenharmony_ci
91462306a36Sopenharmony_ci	btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
91562306a36Sopenharmony_ci
91662306a36Sopenharmony_ci	if (key.type != BTRFS_FREE_SPACE_EXTENT_KEY) {
91762306a36Sopenharmony_ci		ASSERT(key.type == BTRFS_FREE_SPACE_INFO_KEY);
91862306a36Sopenharmony_ci		btrfs_release_path(path);
91962306a36Sopenharmony_ci		goto right;
92062306a36Sopenharmony_ci	}
92162306a36Sopenharmony_ci
92262306a36Sopenharmony_ci	found_start = key.objectid;
92362306a36Sopenharmony_ci	found_end = key.objectid + key.offset;
92462306a36Sopenharmony_ci	ASSERT(found_start >= block_group->start &&
92562306a36Sopenharmony_ci	       found_end > block_group->start);
92662306a36Sopenharmony_ci	ASSERT(found_start < start && found_end <= start);
92762306a36Sopenharmony_ci
92862306a36Sopenharmony_ci	/*
92962306a36Sopenharmony_ci	 * Delete the neighbor on the left and absorb it into the new key (cases
93062306a36Sopenharmony_ci	 * 2 and 4).
93162306a36Sopenharmony_ci	 */
93262306a36Sopenharmony_ci	if (found_end == start) {
93362306a36Sopenharmony_ci		ret = btrfs_del_item(trans, root, path);
93462306a36Sopenharmony_ci		if (ret)
93562306a36Sopenharmony_ci			goto out;
93662306a36Sopenharmony_ci		new_key.objectid = found_start;
93762306a36Sopenharmony_ci		new_key.offset += key.offset;
93862306a36Sopenharmony_ci		new_extents--;
93962306a36Sopenharmony_ci	}
94062306a36Sopenharmony_ci	btrfs_release_path(path);
94162306a36Sopenharmony_ci
94262306a36Sopenharmony_ciright:
94362306a36Sopenharmony_ci	/* Search for a neighbor on the right. */
94462306a36Sopenharmony_ci	if (end == block_group->start + block_group->length)
94562306a36Sopenharmony_ci		goto insert;
94662306a36Sopenharmony_ci	key.objectid = end;
94762306a36Sopenharmony_ci	key.type = (u8)-1;
94862306a36Sopenharmony_ci	key.offset = (u64)-1;
94962306a36Sopenharmony_ci
95062306a36Sopenharmony_ci	ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);
95162306a36Sopenharmony_ci	if (ret)
95262306a36Sopenharmony_ci		goto out;
95362306a36Sopenharmony_ci
95462306a36Sopenharmony_ci	btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
95562306a36Sopenharmony_ci
95662306a36Sopenharmony_ci	if (key.type != BTRFS_FREE_SPACE_EXTENT_KEY) {
95762306a36Sopenharmony_ci		ASSERT(key.type == BTRFS_FREE_SPACE_INFO_KEY);
95862306a36Sopenharmony_ci		btrfs_release_path(path);
95962306a36Sopenharmony_ci		goto insert;
96062306a36Sopenharmony_ci	}
96162306a36Sopenharmony_ci
96262306a36Sopenharmony_ci	found_start = key.objectid;
96362306a36Sopenharmony_ci	found_end = key.objectid + key.offset;
96462306a36Sopenharmony_ci	ASSERT(found_start >= block_group->start &&
96562306a36Sopenharmony_ci	       found_end > block_group->start);
96662306a36Sopenharmony_ci	ASSERT((found_start < start && found_end <= start) ||
96762306a36Sopenharmony_ci	       (found_start >= end && found_end > end));
96862306a36Sopenharmony_ci
96962306a36Sopenharmony_ci	/*
97062306a36Sopenharmony_ci	 * Delete the neighbor on the right and absorb it into the new key
97162306a36Sopenharmony_ci	 * (cases 3 and 4).
97262306a36Sopenharmony_ci	 */
97362306a36Sopenharmony_ci	if (found_start == end) {
97462306a36Sopenharmony_ci		ret = btrfs_del_item(trans, root, path);
97562306a36Sopenharmony_ci		if (ret)
97662306a36Sopenharmony_ci			goto out;
97762306a36Sopenharmony_ci		new_key.offset += key.offset;
97862306a36Sopenharmony_ci		new_extents--;
97962306a36Sopenharmony_ci	}
98062306a36Sopenharmony_ci	btrfs_release_path(path);
98162306a36Sopenharmony_ci
98262306a36Sopenharmony_ciinsert:
98362306a36Sopenharmony_ci	/* Insert the new key (cases 1-4). */
98462306a36Sopenharmony_ci	ret = btrfs_insert_empty_item(trans, root, path, &new_key, 0);
98562306a36Sopenharmony_ci	if (ret)
98662306a36Sopenharmony_ci		goto out;
98762306a36Sopenharmony_ci
98862306a36Sopenharmony_ci	btrfs_release_path(path);
98962306a36Sopenharmony_ci	ret = update_free_space_extent_count(trans, block_group, path,
99062306a36Sopenharmony_ci					     new_extents);
99162306a36Sopenharmony_ci
99262306a36Sopenharmony_ciout:
99362306a36Sopenharmony_ci	return ret;
99462306a36Sopenharmony_ci}
99562306a36Sopenharmony_ci
99662306a36Sopenharmony_ciEXPORT_FOR_TESTS
99762306a36Sopenharmony_ciint __add_to_free_space_tree(struct btrfs_trans_handle *trans,
99862306a36Sopenharmony_ci			     struct btrfs_block_group *block_group,
99962306a36Sopenharmony_ci			     struct btrfs_path *path, u64 start, u64 size)
100062306a36Sopenharmony_ci{
100162306a36Sopenharmony_ci	struct btrfs_free_space_info *info;
100262306a36Sopenharmony_ci	u32 flags;
100362306a36Sopenharmony_ci	int ret;
100462306a36Sopenharmony_ci
100562306a36Sopenharmony_ci	if (test_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &block_group->runtime_flags)) {
100662306a36Sopenharmony_ci		ret = __add_block_group_free_space(trans, block_group, path);
100762306a36Sopenharmony_ci		if (ret)
100862306a36Sopenharmony_ci			return ret;
100962306a36Sopenharmony_ci	}
101062306a36Sopenharmony_ci
101162306a36Sopenharmony_ci	info = search_free_space_info(NULL, block_group, path, 0);
101262306a36Sopenharmony_ci	if (IS_ERR(info))
101362306a36Sopenharmony_ci		return PTR_ERR(info);
101462306a36Sopenharmony_ci	flags = btrfs_free_space_flags(path->nodes[0], info);
101562306a36Sopenharmony_ci	btrfs_release_path(path);
101662306a36Sopenharmony_ci
101762306a36Sopenharmony_ci	if (flags & BTRFS_FREE_SPACE_USING_BITMAPS) {
101862306a36Sopenharmony_ci		return modify_free_space_bitmap(trans, block_group, path,
101962306a36Sopenharmony_ci						start, size, 0);
102062306a36Sopenharmony_ci	} else {
102162306a36Sopenharmony_ci		return add_free_space_extent(trans, block_group, path, start,
102262306a36Sopenharmony_ci					     size);
102362306a36Sopenharmony_ci	}
102462306a36Sopenharmony_ci}
102562306a36Sopenharmony_ci
102662306a36Sopenharmony_ciint add_to_free_space_tree(struct btrfs_trans_handle *trans,
102762306a36Sopenharmony_ci			   u64 start, u64 size)
102862306a36Sopenharmony_ci{
102962306a36Sopenharmony_ci	struct btrfs_block_group *block_group;
103062306a36Sopenharmony_ci	struct btrfs_path *path;
103162306a36Sopenharmony_ci	int ret;
103262306a36Sopenharmony_ci
103362306a36Sopenharmony_ci	if (!btrfs_fs_compat_ro(trans->fs_info, FREE_SPACE_TREE))
103462306a36Sopenharmony_ci		return 0;
103562306a36Sopenharmony_ci
103662306a36Sopenharmony_ci	path = btrfs_alloc_path();
103762306a36Sopenharmony_ci	if (!path) {
103862306a36Sopenharmony_ci		ret = -ENOMEM;
103962306a36Sopenharmony_ci		goto out;
104062306a36Sopenharmony_ci	}
104162306a36Sopenharmony_ci
104262306a36Sopenharmony_ci	block_group = btrfs_lookup_block_group(trans->fs_info, start);
104362306a36Sopenharmony_ci	if (!block_group) {
104462306a36Sopenharmony_ci		ASSERT(0);
104562306a36Sopenharmony_ci		ret = -ENOENT;
104662306a36Sopenharmony_ci		goto out;
104762306a36Sopenharmony_ci	}
104862306a36Sopenharmony_ci
104962306a36Sopenharmony_ci	mutex_lock(&block_group->free_space_lock);
105062306a36Sopenharmony_ci	ret = __add_to_free_space_tree(trans, block_group, path, start, size);
105162306a36Sopenharmony_ci	mutex_unlock(&block_group->free_space_lock);
105262306a36Sopenharmony_ci
105362306a36Sopenharmony_ci	btrfs_put_block_group(block_group);
105462306a36Sopenharmony_ciout:
105562306a36Sopenharmony_ci	btrfs_free_path(path);
105662306a36Sopenharmony_ci	if (ret)
105762306a36Sopenharmony_ci		btrfs_abort_transaction(trans, ret);
105862306a36Sopenharmony_ci	return ret;
105962306a36Sopenharmony_ci}
106062306a36Sopenharmony_ci
106162306a36Sopenharmony_ci/*
106262306a36Sopenharmony_ci * Populate the free space tree by walking the extent tree. Operations on the
106362306a36Sopenharmony_ci * extent tree that happen as a result of writes to the free space tree will go
106462306a36Sopenharmony_ci * through the normal add/remove hooks.
106562306a36Sopenharmony_ci */
106662306a36Sopenharmony_cistatic int populate_free_space_tree(struct btrfs_trans_handle *trans,
106762306a36Sopenharmony_ci				    struct btrfs_block_group *block_group)
106862306a36Sopenharmony_ci{
106962306a36Sopenharmony_ci	struct btrfs_root *extent_root;
107062306a36Sopenharmony_ci	struct btrfs_path *path, *path2;
107162306a36Sopenharmony_ci	struct btrfs_key key;
107262306a36Sopenharmony_ci	u64 start, end;
107362306a36Sopenharmony_ci	int ret;
107462306a36Sopenharmony_ci
107562306a36Sopenharmony_ci	path = btrfs_alloc_path();
107662306a36Sopenharmony_ci	if (!path)
107762306a36Sopenharmony_ci		return -ENOMEM;
107862306a36Sopenharmony_ci	path->reada = READA_FORWARD;
107962306a36Sopenharmony_ci
108062306a36Sopenharmony_ci	path2 = btrfs_alloc_path();
108162306a36Sopenharmony_ci	if (!path2) {
108262306a36Sopenharmony_ci		btrfs_free_path(path);
108362306a36Sopenharmony_ci		return -ENOMEM;
108462306a36Sopenharmony_ci	}
108562306a36Sopenharmony_ci
108662306a36Sopenharmony_ci	ret = add_new_free_space_info(trans, block_group, path2);
108762306a36Sopenharmony_ci	if (ret)
108862306a36Sopenharmony_ci		goto out;
108962306a36Sopenharmony_ci
109062306a36Sopenharmony_ci	mutex_lock(&block_group->free_space_lock);
109162306a36Sopenharmony_ci
109262306a36Sopenharmony_ci	/*
109362306a36Sopenharmony_ci	 * Iterate through all of the extent and metadata items in this block
109462306a36Sopenharmony_ci	 * group, adding the free space between them and the free space at the
109562306a36Sopenharmony_ci	 * end. Note that EXTENT_ITEM and METADATA_ITEM are less than
109662306a36Sopenharmony_ci	 * BLOCK_GROUP_ITEM, so an extent may precede the block group that it's
109762306a36Sopenharmony_ci	 * contained in.
109862306a36Sopenharmony_ci	 */
109962306a36Sopenharmony_ci	key.objectid = block_group->start;
110062306a36Sopenharmony_ci	key.type = BTRFS_EXTENT_ITEM_KEY;
110162306a36Sopenharmony_ci	key.offset = 0;
110262306a36Sopenharmony_ci
110362306a36Sopenharmony_ci	extent_root = btrfs_extent_root(trans->fs_info, key.objectid);
110462306a36Sopenharmony_ci	ret = btrfs_search_slot_for_read(extent_root, &key, path, 1, 0);
110562306a36Sopenharmony_ci	if (ret < 0)
110662306a36Sopenharmony_ci		goto out_locked;
110762306a36Sopenharmony_ci	ASSERT(ret == 0);
110862306a36Sopenharmony_ci
110962306a36Sopenharmony_ci	start = block_group->start;
111062306a36Sopenharmony_ci	end = block_group->start + block_group->length;
111162306a36Sopenharmony_ci	while (1) {
111262306a36Sopenharmony_ci		btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
111362306a36Sopenharmony_ci
111462306a36Sopenharmony_ci		if (key.type == BTRFS_EXTENT_ITEM_KEY ||
111562306a36Sopenharmony_ci		    key.type == BTRFS_METADATA_ITEM_KEY) {
111662306a36Sopenharmony_ci			if (key.objectid >= end)
111762306a36Sopenharmony_ci				break;
111862306a36Sopenharmony_ci
111962306a36Sopenharmony_ci			if (start < key.objectid) {
112062306a36Sopenharmony_ci				ret = __add_to_free_space_tree(trans,
112162306a36Sopenharmony_ci							       block_group,
112262306a36Sopenharmony_ci							       path2, start,
112362306a36Sopenharmony_ci							       key.objectid -
112462306a36Sopenharmony_ci							       start);
112562306a36Sopenharmony_ci				if (ret)
112662306a36Sopenharmony_ci					goto out_locked;
112762306a36Sopenharmony_ci			}
112862306a36Sopenharmony_ci			start = key.objectid;
112962306a36Sopenharmony_ci			if (key.type == BTRFS_METADATA_ITEM_KEY)
113062306a36Sopenharmony_ci				start += trans->fs_info->nodesize;
113162306a36Sopenharmony_ci			else
113262306a36Sopenharmony_ci				start += key.offset;
113362306a36Sopenharmony_ci		} else if (key.type == BTRFS_BLOCK_GROUP_ITEM_KEY) {
113462306a36Sopenharmony_ci			if (key.objectid != block_group->start)
113562306a36Sopenharmony_ci				break;
113662306a36Sopenharmony_ci		}
113762306a36Sopenharmony_ci
113862306a36Sopenharmony_ci		ret = btrfs_next_item(extent_root, path);
113962306a36Sopenharmony_ci		if (ret < 0)
114062306a36Sopenharmony_ci			goto out_locked;
114162306a36Sopenharmony_ci		if (ret)
114262306a36Sopenharmony_ci			break;
114362306a36Sopenharmony_ci	}
114462306a36Sopenharmony_ci	if (start < end) {
114562306a36Sopenharmony_ci		ret = __add_to_free_space_tree(trans, block_group, path2,
114662306a36Sopenharmony_ci					       start, end - start);
114762306a36Sopenharmony_ci		if (ret)
114862306a36Sopenharmony_ci			goto out_locked;
114962306a36Sopenharmony_ci	}
115062306a36Sopenharmony_ci
115162306a36Sopenharmony_ci	ret = 0;
115262306a36Sopenharmony_ciout_locked:
115362306a36Sopenharmony_ci	mutex_unlock(&block_group->free_space_lock);
115462306a36Sopenharmony_ciout:
115562306a36Sopenharmony_ci	btrfs_free_path(path2);
115662306a36Sopenharmony_ci	btrfs_free_path(path);
115762306a36Sopenharmony_ci	return ret;
115862306a36Sopenharmony_ci}
115962306a36Sopenharmony_ci
116062306a36Sopenharmony_ciint btrfs_create_free_space_tree(struct btrfs_fs_info *fs_info)
116162306a36Sopenharmony_ci{
116262306a36Sopenharmony_ci	struct btrfs_trans_handle *trans;
116362306a36Sopenharmony_ci	struct btrfs_root *tree_root = fs_info->tree_root;
116462306a36Sopenharmony_ci	struct btrfs_root *free_space_root;
116562306a36Sopenharmony_ci	struct btrfs_block_group *block_group;
116662306a36Sopenharmony_ci	struct rb_node *node;
116762306a36Sopenharmony_ci	int ret;
116862306a36Sopenharmony_ci
116962306a36Sopenharmony_ci	trans = btrfs_start_transaction(tree_root, 0);
117062306a36Sopenharmony_ci	if (IS_ERR(trans))
117162306a36Sopenharmony_ci		return PTR_ERR(trans);
117262306a36Sopenharmony_ci
117362306a36Sopenharmony_ci	set_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
117462306a36Sopenharmony_ci	set_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
117562306a36Sopenharmony_ci	free_space_root = btrfs_create_tree(trans,
117662306a36Sopenharmony_ci					    BTRFS_FREE_SPACE_TREE_OBJECTID);
117762306a36Sopenharmony_ci	if (IS_ERR(free_space_root)) {
117862306a36Sopenharmony_ci		ret = PTR_ERR(free_space_root);
117962306a36Sopenharmony_ci		goto abort;
118062306a36Sopenharmony_ci	}
118162306a36Sopenharmony_ci	ret = btrfs_global_root_insert(free_space_root);
118262306a36Sopenharmony_ci	if (ret) {
118362306a36Sopenharmony_ci		btrfs_put_root(free_space_root);
118462306a36Sopenharmony_ci		goto abort;
118562306a36Sopenharmony_ci	}
118662306a36Sopenharmony_ci
118762306a36Sopenharmony_ci	node = rb_first_cached(&fs_info->block_group_cache_tree);
118862306a36Sopenharmony_ci	while (node) {
118962306a36Sopenharmony_ci		block_group = rb_entry(node, struct btrfs_block_group,
119062306a36Sopenharmony_ci				       cache_node);
119162306a36Sopenharmony_ci		ret = populate_free_space_tree(trans, block_group);
119262306a36Sopenharmony_ci		if (ret)
119362306a36Sopenharmony_ci			goto abort;
119462306a36Sopenharmony_ci		node = rb_next(node);
119562306a36Sopenharmony_ci	}
119662306a36Sopenharmony_ci
119762306a36Sopenharmony_ci	btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE);
119862306a36Sopenharmony_ci	btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID);
119962306a36Sopenharmony_ci	clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
120062306a36Sopenharmony_ci	ret = btrfs_commit_transaction(trans);
120162306a36Sopenharmony_ci
120262306a36Sopenharmony_ci	/*
120362306a36Sopenharmony_ci	 * Now that we've committed the transaction any reading of our commit
120462306a36Sopenharmony_ci	 * root will be safe, so we can cache from the free space tree now.
120562306a36Sopenharmony_ci	 */
120662306a36Sopenharmony_ci	clear_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
120762306a36Sopenharmony_ci	return ret;
120862306a36Sopenharmony_ci
120962306a36Sopenharmony_ciabort:
121062306a36Sopenharmony_ci	clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
121162306a36Sopenharmony_ci	clear_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
121262306a36Sopenharmony_ci	btrfs_abort_transaction(trans, ret);
121362306a36Sopenharmony_ci	btrfs_end_transaction(trans);
121462306a36Sopenharmony_ci	return ret;
121562306a36Sopenharmony_ci}
121662306a36Sopenharmony_ci
121762306a36Sopenharmony_cistatic int clear_free_space_tree(struct btrfs_trans_handle *trans,
121862306a36Sopenharmony_ci				 struct btrfs_root *root)
121962306a36Sopenharmony_ci{
122062306a36Sopenharmony_ci	struct btrfs_path *path;
122162306a36Sopenharmony_ci	struct btrfs_key key;
122262306a36Sopenharmony_ci	int nr;
122362306a36Sopenharmony_ci	int ret;
122462306a36Sopenharmony_ci
122562306a36Sopenharmony_ci	path = btrfs_alloc_path();
122662306a36Sopenharmony_ci	if (!path)
122762306a36Sopenharmony_ci		return -ENOMEM;
122862306a36Sopenharmony_ci
122962306a36Sopenharmony_ci	key.objectid = 0;
123062306a36Sopenharmony_ci	key.type = 0;
123162306a36Sopenharmony_ci	key.offset = 0;
123262306a36Sopenharmony_ci
123362306a36Sopenharmony_ci	while (1) {
123462306a36Sopenharmony_ci		ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
123562306a36Sopenharmony_ci		if (ret < 0)
123662306a36Sopenharmony_ci			goto out;
123762306a36Sopenharmony_ci
123862306a36Sopenharmony_ci		nr = btrfs_header_nritems(path->nodes[0]);
123962306a36Sopenharmony_ci		if (!nr)
124062306a36Sopenharmony_ci			break;
124162306a36Sopenharmony_ci
124262306a36Sopenharmony_ci		path->slots[0] = 0;
124362306a36Sopenharmony_ci		ret = btrfs_del_items(trans, root, path, 0, nr);
124462306a36Sopenharmony_ci		if (ret)
124562306a36Sopenharmony_ci			goto out;
124662306a36Sopenharmony_ci
124762306a36Sopenharmony_ci		btrfs_release_path(path);
124862306a36Sopenharmony_ci	}
124962306a36Sopenharmony_ci
125062306a36Sopenharmony_ci	ret = 0;
125162306a36Sopenharmony_ciout:
125262306a36Sopenharmony_ci	btrfs_free_path(path);
125362306a36Sopenharmony_ci	return ret;
125462306a36Sopenharmony_ci}
125562306a36Sopenharmony_ci
125662306a36Sopenharmony_ciint btrfs_delete_free_space_tree(struct btrfs_fs_info *fs_info)
125762306a36Sopenharmony_ci{
125862306a36Sopenharmony_ci	struct btrfs_trans_handle *trans;
125962306a36Sopenharmony_ci	struct btrfs_root *tree_root = fs_info->tree_root;
126062306a36Sopenharmony_ci	struct btrfs_key key = {
126162306a36Sopenharmony_ci		.objectid = BTRFS_FREE_SPACE_TREE_OBJECTID,
126262306a36Sopenharmony_ci		.type = BTRFS_ROOT_ITEM_KEY,
126362306a36Sopenharmony_ci		.offset = 0,
126462306a36Sopenharmony_ci	};
126562306a36Sopenharmony_ci	struct btrfs_root *free_space_root = btrfs_global_root(fs_info, &key);
126662306a36Sopenharmony_ci	int ret;
126762306a36Sopenharmony_ci
126862306a36Sopenharmony_ci	trans = btrfs_start_transaction(tree_root, 0);
126962306a36Sopenharmony_ci	if (IS_ERR(trans))
127062306a36Sopenharmony_ci		return PTR_ERR(trans);
127162306a36Sopenharmony_ci
127262306a36Sopenharmony_ci	btrfs_clear_fs_compat_ro(fs_info, FREE_SPACE_TREE);
127362306a36Sopenharmony_ci	btrfs_clear_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID);
127462306a36Sopenharmony_ci
127562306a36Sopenharmony_ci	ret = clear_free_space_tree(trans, free_space_root);
127662306a36Sopenharmony_ci	if (ret)
127762306a36Sopenharmony_ci		goto abort;
127862306a36Sopenharmony_ci
127962306a36Sopenharmony_ci	ret = btrfs_del_root(trans, &free_space_root->root_key);
128062306a36Sopenharmony_ci	if (ret)
128162306a36Sopenharmony_ci		goto abort;
128262306a36Sopenharmony_ci
128362306a36Sopenharmony_ci	btrfs_global_root_delete(free_space_root);
128462306a36Sopenharmony_ci
128562306a36Sopenharmony_ci	spin_lock(&fs_info->trans_lock);
128662306a36Sopenharmony_ci	list_del(&free_space_root->dirty_list);
128762306a36Sopenharmony_ci	spin_unlock(&fs_info->trans_lock);
128862306a36Sopenharmony_ci
128962306a36Sopenharmony_ci	btrfs_tree_lock(free_space_root->node);
129062306a36Sopenharmony_ci	btrfs_clear_buffer_dirty(trans, free_space_root->node);
129162306a36Sopenharmony_ci	btrfs_tree_unlock(free_space_root->node);
129262306a36Sopenharmony_ci	btrfs_free_tree_block(trans, btrfs_root_id(free_space_root),
129362306a36Sopenharmony_ci			      free_space_root->node, 0, 1);
129462306a36Sopenharmony_ci
129562306a36Sopenharmony_ci	btrfs_put_root(free_space_root);
129662306a36Sopenharmony_ci
129762306a36Sopenharmony_ci	return btrfs_commit_transaction(trans);
129862306a36Sopenharmony_ci
129962306a36Sopenharmony_ciabort:
130062306a36Sopenharmony_ci	btrfs_abort_transaction(trans, ret);
130162306a36Sopenharmony_ci	btrfs_end_transaction(trans);
130262306a36Sopenharmony_ci	return ret;
130362306a36Sopenharmony_ci}
130462306a36Sopenharmony_ci
130562306a36Sopenharmony_ciint btrfs_rebuild_free_space_tree(struct btrfs_fs_info *fs_info)
130662306a36Sopenharmony_ci{
130762306a36Sopenharmony_ci	struct btrfs_trans_handle *trans;
130862306a36Sopenharmony_ci	struct btrfs_key key = {
130962306a36Sopenharmony_ci		.objectid = BTRFS_FREE_SPACE_TREE_OBJECTID,
131062306a36Sopenharmony_ci		.type = BTRFS_ROOT_ITEM_KEY,
131162306a36Sopenharmony_ci		.offset = 0,
131262306a36Sopenharmony_ci	};
131362306a36Sopenharmony_ci	struct btrfs_root *free_space_root = btrfs_global_root(fs_info, &key);
131462306a36Sopenharmony_ci	struct rb_node *node;
131562306a36Sopenharmony_ci	int ret;
131662306a36Sopenharmony_ci
131762306a36Sopenharmony_ci	trans = btrfs_start_transaction(free_space_root, 1);
131862306a36Sopenharmony_ci	if (IS_ERR(trans))
131962306a36Sopenharmony_ci		return PTR_ERR(trans);
132062306a36Sopenharmony_ci
132162306a36Sopenharmony_ci	set_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
132262306a36Sopenharmony_ci	set_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
132362306a36Sopenharmony_ci
132462306a36Sopenharmony_ci	ret = clear_free_space_tree(trans, free_space_root);
132562306a36Sopenharmony_ci	if (ret)
132662306a36Sopenharmony_ci		goto abort;
132762306a36Sopenharmony_ci
132862306a36Sopenharmony_ci	node = rb_first_cached(&fs_info->block_group_cache_tree);
132962306a36Sopenharmony_ci	while (node) {
133062306a36Sopenharmony_ci		struct btrfs_block_group *block_group;
133162306a36Sopenharmony_ci
133262306a36Sopenharmony_ci		block_group = rb_entry(node, struct btrfs_block_group,
133362306a36Sopenharmony_ci				       cache_node);
133462306a36Sopenharmony_ci		ret = populate_free_space_tree(trans, block_group);
133562306a36Sopenharmony_ci		if (ret)
133662306a36Sopenharmony_ci			goto abort;
133762306a36Sopenharmony_ci		node = rb_next(node);
133862306a36Sopenharmony_ci	}
133962306a36Sopenharmony_ci
134062306a36Sopenharmony_ci	btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE);
134162306a36Sopenharmony_ci	btrfs_set_fs_compat_ro(fs_info, FREE_SPACE_TREE_VALID);
134262306a36Sopenharmony_ci	clear_bit(BTRFS_FS_CREATING_FREE_SPACE_TREE, &fs_info->flags);
134362306a36Sopenharmony_ci
134462306a36Sopenharmony_ci	ret = btrfs_commit_transaction(trans);
134562306a36Sopenharmony_ci	clear_bit(BTRFS_FS_FREE_SPACE_TREE_UNTRUSTED, &fs_info->flags);
134662306a36Sopenharmony_ci	return ret;
134762306a36Sopenharmony_ciabort:
134862306a36Sopenharmony_ci	btrfs_abort_transaction(trans, ret);
134962306a36Sopenharmony_ci	btrfs_end_transaction(trans);
135062306a36Sopenharmony_ci	return ret;
135162306a36Sopenharmony_ci}
135262306a36Sopenharmony_ci
135362306a36Sopenharmony_cistatic int __add_block_group_free_space(struct btrfs_trans_handle *trans,
135462306a36Sopenharmony_ci					struct btrfs_block_group *block_group,
135562306a36Sopenharmony_ci					struct btrfs_path *path)
135662306a36Sopenharmony_ci{
135762306a36Sopenharmony_ci	int ret;
135862306a36Sopenharmony_ci
135962306a36Sopenharmony_ci	clear_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &block_group->runtime_flags);
136062306a36Sopenharmony_ci
136162306a36Sopenharmony_ci	ret = add_new_free_space_info(trans, block_group, path);
136262306a36Sopenharmony_ci	if (ret)
136362306a36Sopenharmony_ci		return ret;
136462306a36Sopenharmony_ci
136562306a36Sopenharmony_ci	return __add_to_free_space_tree(trans, block_group, path,
136662306a36Sopenharmony_ci					block_group->start,
136762306a36Sopenharmony_ci					block_group->length);
136862306a36Sopenharmony_ci}
136962306a36Sopenharmony_ci
137062306a36Sopenharmony_ciint add_block_group_free_space(struct btrfs_trans_handle *trans,
137162306a36Sopenharmony_ci			       struct btrfs_block_group *block_group)
137262306a36Sopenharmony_ci{
137362306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info = trans->fs_info;
137462306a36Sopenharmony_ci	struct btrfs_path *path = NULL;
137562306a36Sopenharmony_ci	int ret = 0;
137662306a36Sopenharmony_ci
137762306a36Sopenharmony_ci	if (!btrfs_fs_compat_ro(fs_info, FREE_SPACE_TREE))
137862306a36Sopenharmony_ci		return 0;
137962306a36Sopenharmony_ci
138062306a36Sopenharmony_ci	mutex_lock(&block_group->free_space_lock);
138162306a36Sopenharmony_ci	if (!test_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &block_group->runtime_flags))
138262306a36Sopenharmony_ci		goto out;
138362306a36Sopenharmony_ci
138462306a36Sopenharmony_ci	path = btrfs_alloc_path();
138562306a36Sopenharmony_ci	if (!path) {
138662306a36Sopenharmony_ci		ret = -ENOMEM;
138762306a36Sopenharmony_ci		goto out;
138862306a36Sopenharmony_ci	}
138962306a36Sopenharmony_ci
139062306a36Sopenharmony_ci	ret = __add_block_group_free_space(trans, block_group, path);
139162306a36Sopenharmony_ci
139262306a36Sopenharmony_ciout:
139362306a36Sopenharmony_ci	btrfs_free_path(path);
139462306a36Sopenharmony_ci	mutex_unlock(&block_group->free_space_lock);
139562306a36Sopenharmony_ci	if (ret)
139662306a36Sopenharmony_ci		btrfs_abort_transaction(trans, ret);
139762306a36Sopenharmony_ci	return ret;
139862306a36Sopenharmony_ci}
139962306a36Sopenharmony_ci
140062306a36Sopenharmony_ciint remove_block_group_free_space(struct btrfs_trans_handle *trans,
140162306a36Sopenharmony_ci				  struct btrfs_block_group *block_group)
140262306a36Sopenharmony_ci{
140362306a36Sopenharmony_ci	struct btrfs_root *root = btrfs_free_space_root(block_group);
140462306a36Sopenharmony_ci	struct btrfs_path *path;
140562306a36Sopenharmony_ci	struct btrfs_key key, found_key;
140662306a36Sopenharmony_ci	struct extent_buffer *leaf;
140762306a36Sopenharmony_ci	u64 start, end;
140862306a36Sopenharmony_ci	int done = 0, nr;
140962306a36Sopenharmony_ci	int ret;
141062306a36Sopenharmony_ci
141162306a36Sopenharmony_ci	if (!btrfs_fs_compat_ro(trans->fs_info, FREE_SPACE_TREE))
141262306a36Sopenharmony_ci		return 0;
141362306a36Sopenharmony_ci
141462306a36Sopenharmony_ci	if (test_bit(BLOCK_GROUP_FLAG_NEEDS_FREE_SPACE, &block_group->runtime_flags)) {
141562306a36Sopenharmony_ci		/* We never added this block group to the free space tree. */
141662306a36Sopenharmony_ci		return 0;
141762306a36Sopenharmony_ci	}
141862306a36Sopenharmony_ci
141962306a36Sopenharmony_ci	path = btrfs_alloc_path();
142062306a36Sopenharmony_ci	if (!path) {
142162306a36Sopenharmony_ci		ret = -ENOMEM;
142262306a36Sopenharmony_ci		goto out;
142362306a36Sopenharmony_ci	}
142462306a36Sopenharmony_ci
142562306a36Sopenharmony_ci	start = block_group->start;
142662306a36Sopenharmony_ci	end = block_group->start + block_group->length;
142762306a36Sopenharmony_ci
142862306a36Sopenharmony_ci	key.objectid = end - 1;
142962306a36Sopenharmony_ci	key.type = (u8)-1;
143062306a36Sopenharmony_ci	key.offset = (u64)-1;
143162306a36Sopenharmony_ci
143262306a36Sopenharmony_ci	while (!done) {
143362306a36Sopenharmony_ci		ret = btrfs_search_prev_slot(trans, root, &key, path, -1, 1);
143462306a36Sopenharmony_ci		if (ret)
143562306a36Sopenharmony_ci			goto out;
143662306a36Sopenharmony_ci
143762306a36Sopenharmony_ci		leaf = path->nodes[0];
143862306a36Sopenharmony_ci		nr = 0;
143962306a36Sopenharmony_ci		path->slots[0]++;
144062306a36Sopenharmony_ci		while (path->slots[0] > 0) {
144162306a36Sopenharmony_ci			btrfs_item_key_to_cpu(leaf, &found_key, path->slots[0] - 1);
144262306a36Sopenharmony_ci
144362306a36Sopenharmony_ci			if (found_key.type == BTRFS_FREE_SPACE_INFO_KEY) {
144462306a36Sopenharmony_ci				ASSERT(found_key.objectid == block_group->start);
144562306a36Sopenharmony_ci				ASSERT(found_key.offset == block_group->length);
144662306a36Sopenharmony_ci				done = 1;
144762306a36Sopenharmony_ci				nr++;
144862306a36Sopenharmony_ci				path->slots[0]--;
144962306a36Sopenharmony_ci				break;
145062306a36Sopenharmony_ci			} else if (found_key.type == BTRFS_FREE_SPACE_EXTENT_KEY ||
145162306a36Sopenharmony_ci				   found_key.type == BTRFS_FREE_SPACE_BITMAP_KEY) {
145262306a36Sopenharmony_ci				ASSERT(found_key.objectid >= start);
145362306a36Sopenharmony_ci				ASSERT(found_key.objectid < end);
145462306a36Sopenharmony_ci				ASSERT(found_key.objectid + found_key.offset <= end);
145562306a36Sopenharmony_ci				nr++;
145662306a36Sopenharmony_ci				path->slots[0]--;
145762306a36Sopenharmony_ci			} else {
145862306a36Sopenharmony_ci				ASSERT(0);
145962306a36Sopenharmony_ci			}
146062306a36Sopenharmony_ci		}
146162306a36Sopenharmony_ci
146262306a36Sopenharmony_ci		ret = btrfs_del_items(trans, root, path, path->slots[0], nr);
146362306a36Sopenharmony_ci		if (ret)
146462306a36Sopenharmony_ci			goto out;
146562306a36Sopenharmony_ci		btrfs_release_path(path);
146662306a36Sopenharmony_ci	}
146762306a36Sopenharmony_ci
146862306a36Sopenharmony_ci	ret = 0;
146962306a36Sopenharmony_ciout:
147062306a36Sopenharmony_ci	btrfs_free_path(path);
147162306a36Sopenharmony_ci	if (ret)
147262306a36Sopenharmony_ci		btrfs_abort_transaction(trans, ret);
147362306a36Sopenharmony_ci	return ret;
147462306a36Sopenharmony_ci}
147562306a36Sopenharmony_ci
147662306a36Sopenharmony_cistatic int load_free_space_bitmaps(struct btrfs_caching_control *caching_ctl,
147762306a36Sopenharmony_ci				   struct btrfs_path *path,
147862306a36Sopenharmony_ci				   u32 expected_extent_count)
147962306a36Sopenharmony_ci{
148062306a36Sopenharmony_ci	struct btrfs_block_group *block_group;
148162306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info;
148262306a36Sopenharmony_ci	struct btrfs_root *root;
148362306a36Sopenharmony_ci	struct btrfs_key key;
148462306a36Sopenharmony_ci	int prev_bit = 0, bit;
148562306a36Sopenharmony_ci	/* Initialize to silence GCC. */
148662306a36Sopenharmony_ci	u64 extent_start = 0;
148762306a36Sopenharmony_ci	u64 end, offset;
148862306a36Sopenharmony_ci	u64 total_found = 0;
148962306a36Sopenharmony_ci	u32 extent_count = 0;
149062306a36Sopenharmony_ci	int ret;
149162306a36Sopenharmony_ci
149262306a36Sopenharmony_ci	block_group = caching_ctl->block_group;
149362306a36Sopenharmony_ci	fs_info = block_group->fs_info;
149462306a36Sopenharmony_ci	root = btrfs_free_space_root(block_group);
149562306a36Sopenharmony_ci
149662306a36Sopenharmony_ci	end = block_group->start + block_group->length;
149762306a36Sopenharmony_ci
149862306a36Sopenharmony_ci	while (1) {
149962306a36Sopenharmony_ci		ret = btrfs_next_item(root, path);
150062306a36Sopenharmony_ci		if (ret < 0)
150162306a36Sopenharmony_ci			goto out;
150262306a36Sopenharmony_ci		if (ret)
150362306a36Sopenharmony_ci			break;
150462306a36Sopenharmony_ci
150562306a36Sopenharmony_ci		btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
150662306a36Sopenharmony_ci
150762306a36Sopenharmony_ci		if (key.type == BTRFS_FREE_SPACE_INFO_KEY)
150862306a36Sopenharmony_ci			break;
150962306a36Sopenharmony_ci
151062306a36Sopenharmony_ci		ASSERT(key.type == BTRFS_FREE_SPACE_BITMAP_KEY);
151162306a36Sopenharmony_ci		ASSERT(key.objectid < end && key.objectid + key.offset <= end);
151262306a36Sopenharmony_ci
151362306a36Sopenharmony_ci		offset = key.objectid;
151462306a36Sopenharmony_ci		while (offset < key.objectid + key.offset) {
151562306a36Sopenharmony_ci			bit = free_space_test_bit(block_group, path, offset);
151662306a36Sopenharmony_ci			if (prev_bit == 0 && bit == 1) {
151762306a36Sopenharmony_ci				extent_start = offset;
151862306a36Sopenharmony_ci			} else if (prev_bit == 1 && bit == 0) {
151962306a36Sopenharmony_ci				u64 space_added;
152062306a36Sopenharmony_ci
152162306a36Sopenharmony_ci				ret = btrfs_add_new_free_space(block_group,
152262306a36Sopenharmony_ci							       extent_start,
152362306a36Sopenharmony_ci							       offset,
152462306a36Sopenharmony_ci							       &space_added);
152562306a36Sopenharmony_ci				if (ret)
152662306a36Sopenharmony_ci					goto out;
152762306a36Sopenharmony_ci				total_found += space_added;
152862306a36Sopenharmony_ci				if (total_found > CACHING_CTL_WAKE_UP) {
152962306a36Sopenharmony_ci					total_found = 0;
153062306a36Sopenharmony_ci					wake_up(&caching_ctl->wait);
153162306a36Sopenharmony_ci				}
153262306a36Sopenharmony_ci				extent_count++;
153362306a36Sopenharmony_ci			}
153462306a36Sopenharmony_ci			prev_bit = bit;
153562306a36Sopenharmony_ci			offset += fs_info->sectorsize;
153662306a36Sopenharmony_ci		}
153762306a36Sopenharmony_ci	}
153862306a36Sopenharmony_ci	if (prev_bit == 1) {
153962306a36Sopenharmony_ci		ret = btrfs_add_new_free_space(block_group, extent_start, end, NULL);
154062306a36Sopenharmony_ci		if (ret)
154162306a36Sopenharmony_ci			goto out;
154262306a36Sopenharmony_ci		extent_count++;
154362306a36Sopenharmony_ci	}
154462306a36Sopenharmony_ci
154562306a36Sopenharmony_ci	if (extent_count != expected_extent_count) {
154662306a36Sopenharmony_ci		btrfs_err(fs_info,
154762306a36Sopenharmony_ci			  "incorrect extent count for %llu; counted %u, expected %u",
154862306a36Sopenharmony_ci			  block_group->start, extent_count,
154962306a36Sopenharmony_ci			  expected_extent_count);
155062306a36Sopenharmony_ci		ASSERT(0);
155162306a36Sopenharmony_ci		ret = -EIO;
155262306a36Sopenharmony_ci		goto out;
155362306a36Sopenharmony_ci	}
155462306a36Sopenharmony_ci
155562306a36Sopenharmony_ci	ret = 0;
155662306a36Sopenharmony_ciout:
155762306a36Sopenharmony_ci	return ret;
155862306a36Sopenharmony_ci}
155962306a36Sopenharmony_ci
156062306a36Sopenharmony_cistatic int load_free_space_extents(struct btrfs_caching_control *caching_ctl,
156162306a36Sopenharmony_ci				   struct btrfs_path *path,
156262306a36Sopenharmony_ci				   u32 expected_extent_count)
156362306a36Sopenharmony_ci{
156462306a36Sopenharmony_ci	struct btrfs_block_group *block_group;
156562306a36Sopenharmony_ci	struct btrfs_fs_info *fs_info;
156662306a36Sopenharmony_ci	struct btrfs_root *root;
156762306a36Sopenharmony_ci	struct btrfs_key key;
156862306a36Sopenharmony_ci	u64 end;
156962306a36Sopenharmony_ci	u64 total_found = 0;
157062306a36Sopenharmony_ci	u32 extent_count = 0;
157162306a36Sopenharmony_ci	int ret;
157262306a36Sopenharmony_ci
157362306a36Sopenharmony_ci	block_group = caching_ctl->block_group;
157462306a36Sopenharmony_ci	fs_info = block_group->fs_info;
157562306a36Sopenharmony_ci	root = btrfs_free_space_root(block_group);
157662306a36Sopenharmony_ci
157762306a36Sopenharmony_ci	end = block_group->start + block_group->length;
157862306a36Sopenharmony_ci
157962306a36Sopenharmony_ci	while (1) {
158062306a36Sopenharmony_ci		u64 space_added;
158162306a36Sopenharmony_ci
158262306a36Sopenharmony_ci		ret = btrfs_next_item(root, path);
158362306a36Sopenharmony_ci		if (ret < 0)
158462306a36Sopenharmony_ci			goto out;
158562306a36Sopenharmony_ci		if (ret)
158662306a36Sopenharmony_ci			break;
158762306a36Sopenharmony_ci
158862306a36Sopenharmony_ci		btrfs_item_key_to_cpu(path->nodes[0], &key, path->slots[0]);
158962306a36Sopenharmony_ci
159062306a36Sopenharmony_ci		if (key.type == BTRFS_FREE_SPACE_INFO_KEY)
159162306a36Sopenharmony_ci			break;
159262306a36Sopenharmony_ci
159362306a36Sopenharmony_ci		ASSERT(key.type == BTRFS_FREE_SPACE_EXTENT_KEY);
159462306a36Sopenharmony_ci		ASSERT(key.objectid < end && key.objectid + key.offset <= end);
159562306a36Sopenharmony_ci
159662306a36Sopenharmony_ci		ret = btrfs_add_new_free_space(block_group, key.objectid,
159762306a36Sopenharmony_ci					       key.objectid + key.offset,
159862306a36Sopenharmony_ci					       &space_added);
159962306a36Sopenharmony_ci		if (ret)
160062306a36Sopenharmony_ci			goto out;
160162306a36Sopenharmony_ci		total_found += space_added;
160262306a36Sopenharmony_ci		if (total_found > CACHING_CTL_WAKE_UP) {
160362306a36Sopenharmony_ci			total_found = 0;
160462306a36Sopenharmony_ci			wake_up(&caching_ctl->wait);
160562306a36Sopenharmony_ci		}
160662306a36Sopenharmony_ci		extent_count++;
160762306a36Sopenharmony_ci	}
160862306a36Sopenharmony_ci
160962306a36Sopenharmony_ci	if (extent_count != expected_extent_count) {
161062306a36Sopenharmony_ci		btrfs_err(fs_info,
161162306a36Sopenharmony_ci			  "incorrect extent count for %llu; counted %u, expected %u",
161262306a36Sopenharmony_ci			  block_group->start, extent_count,
161362306a36Sopenharmony_ci			  expected_extent_count);
161462306a36Sopenharmony_ci		ASSERT(0);
161562306a36Sopenharmony_ci		ret = -EIO;
161662306a36Sopenharmony_ci		goto out;
161762306a36Sopenharmony_ci	}
161862306a36Sopenharmony_ci
161962306a36Sopenharmony_ci	ret = 0;
162062306a36Sopenharmony_ciout:
162162306a36Sopenharmony_ci	return ret;
162262306a36Sopenharmony_ci}
162362306a36Sopenharmony_ci
162462306a36Sopenharmony_ciint load_free_space_tree(struct btrfs_caching_control *caching_ctl)
162562306a36Sopenharmony_ci{
162662306a36Sopenharmony_ci	struct btrfs_block_group *block_group;
162762306a36Sopenharmony_ci	struct btrfs_free_space_info *info;
162862306a36Sopenharmony_ci	struct btrfs_path *path;
162962306a36Sopenharmony_ci	u32 extent_count, flags;
163062306a36Sopenharmony_ci	int ret;
163162306a36Sopenharmony_ci
163262306a36Sopenharmony_ci	block_group = caching_ctl->block_group;
163362306a36Sopenharmony_ci
163462306a36Sopenharmony_ci	path = btrfs_alloc_path();
163562306a36Sopenharmony_ci	if (!path)
163662306a36Sopenharmony_ci		return -ENOMEM;
163762306a36Sopenharmony_ci
163862306a36Sopenharmony_ci	/*
163962306a36Sopenharmony_ci	 * Just like caching_thread() doesn't want to deadlock on the extent
164062306a36Sopenharmony_ci	 * tree, we don't want to deadlock on the free space tree.
164162306a36Sopenharmony_ci	 */
164262306a36Sopenharmony_ci	path->skip_locking = 1;
164362306a36Sopenharmony_ci	path->search_commit_root = 1;
164462306a36Sopenharmony_ci	path->reada = READA_FORWARD;
164562306a36Sopenharmony_ci
164662306a36Sopenharmony_ci	info = search_free_space_info(NULL, block_group, path, 0);
164762306a36Sopenharmony_ci	if (IS_ERR(info)) {
164862306a36Sopenharmony_ci		ret = PTR_ERR(info);
164962306a36Sopenharmony_ci		goto out;
165062306a36Sopenharmony_ci	}
165162306a36Sopenharmony_ci	extent_count = btrfs_free_space_extent_count(path->nodes[0], info);
165262306a36Sopenharmony_ci	flags = btrfs_free_space_flags(path->nodes[0], info);
165362306a36Sopenharmony_ci
165462306a36Sopenharmony_ci	/*
165562306a36Sopenharmony_ci	 * We left path pointing to the free space info item, so now
165662306a36Sopenharmony_ci	 * load_free_space_foo can just iterate through the free space tree from
165762306a36Sopenharmony_ci	 * there.
165862306a36Sopenharmony_ci	 */
165962306a36Sopenharmony_ci	if (flags & BTRFS_FREE_SPACE_USING_BITMAPS)
166062306a36Sopenharmony_ci		ret = load_free_space_bitmaps(caching_ctl, path, extent_count);
166162306a36Sopenharmony_ci	else
166262306a36Sopenharmony_ci		ret = load_free_space_extents(caching_ctl, path, extent_count);
166362306a36Sopenharmony_ci
166462306a36Sopenharmony_ciout:
166562306a36Sopenharmony_ci	btrfs_free_path(path);
166662306a36Sopenharmony_ci	return ret;
166762306a36Sopenharmony_ci}
1668