18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci#include <linux/err.h>
48c2ecf20Sopenharmony_ci#include <linux/slab.h>
58c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
68c2ecf20Sopenharmony_ci#include "ctree.h"
78c2ecf20Sopenharmony_ci#include "volumes.h"
88c2ecf20Sopenharmony_ci#include "extent_map.h"
98c2ecf20Sopenharmony_ci#include "compression.h"
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci
128c2ecf20Sopenharmony_cistatic struct kmem_cache *extent_map_cache;
138c2ecf20Sopenharmony_ci
148c2ecf20Sopenharmony_ciint __init extent_map_init(void)
158c2ecf20Sopenharmony_ci{
168c2ecf20Sopenharmony_ci	extent_map_cache = kmem_cache_create("btrfs_extent_map",
178c2ecf20Sopenharmony_ci			sizeof(struct extent_map), 0,
188c2ecf20Sopenharmony_ci			SLAB_MEM_SPREAD, NULL);
198c2ecf20Sopenharmony_ci	if (!extent_map_cache)
208c2ecf20Sopenharmony_ci		return -ENOMEM;
218c2ecf20Sopenharmony_ci	return 0;
228c2ecf20Sopenharmony_ci}
238c2ecf20Sopenharmony_ci
248c2ecf20Sopenharmony_civoid __cold extent_map_exit(void)
258c2ecf20Sopenharmony_ci{
268c2ecf20Sopenharmony_ci	kmem_cache_destroy(extent_map_cache);
278c2ecf20Sopenharmony_ci}
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci/**
308c2ecf20Sopenharmony_ci * extent_map_tree_init - initialize extent map tree
318c2ecf20Sopenharmony_ci * @tree:		tree to initialize
328c2ecf20Sopenharmony_ci *
338c2ecf20Sopenharmony_ci * Initialize the extent tree @tree.  Should be called for each new inode
348c2ecf20Sopenharmony_ci * or other user of the extent_map interface.
358c2ecf20Sopenharmony_ci */
368c2ecf20Sopenharmony_civoid extent_map_tree_init(struct extent_map_tree *tree)
378c2ecf20Sopenharmony_ci{
388c2ecf20Sopenharmony_ci	tree->map = RB_ROOT_CACHED;
398c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&tree->modified_extents);
408c2ecf20Sopenharmony_ci	rwlock_init(&tree->lock);
418c2ecf20Sopenharmony_ci}
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci/**
448c2ecf20Sopenharmony_ci * alloc_extent_map - allocate new extent map structure
458c2ecf20Sopenharmony_ci *
468c2ecf20Sopenharmony_ci * Allocate a new extent_map structure.  The new structure is
478c2ecf20Sopenharmony_ci * returned with a reference count of one and needs to be
488c2ecf20Sopenharmony_ci * freed using free_extent_map()
498c2ecf20Sopenharmony_ci */
508c2ecf20Sopenharmony_cistruct extent_map *alloc_extent_map(void)
518c2ecf20Sopenharmony_ci{
528c2ecf20Sopenharmony_ci	struct extent_map *em;
538c2ecf20Sopenharmony_ci	em = kmem_cache_zalloc(extent_map_cache, GFP_NOFS);
548c2ecf20Sopenharmony_ci	if (!em)
558c2ecf20Sopenharmony_ci		return NULL;
568c2ecf20Sopenharmony_ci	RB_CLEAR_NODE(&em->rb_node);
578c2ecf20Sopenharmony_ci	em->flags = 0;
588c2ecf20Sopenharmony_ci	em->compress_type = BTRFS_COMPRESS_NONE;
598c2ecf20Sopenharmony_ci	em->generation = 0;
608c2ecf20Sopenharmony_ci	refcount_set(&em->refs, 1);
618c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&em->list);
628c2ecf20Sopenharmony_ci	return em;
638c2ecf20Sopenharmony_ci}
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci/**
668c2ecf20Sopenharmony_ci * free_extent_map - drop reference count of an extent_map
678c2ecf20Sopenharmony_ci * @em:		extent map being released
688c2ecf20Sopenharmony_ci *
698c2ecf20Sopenharmony_ci * Drops the reference out on @em by one and free the structure
708c2ecf20Sopenharmony_ci * if the reference count hits zero.
718c2ecf20Sopenharmony_ci */
728c2ecf20Sopenharmony_civoid free_extent_map(struct extent_map *em)
738c2ecf20Sopenharmony_ci{
748c2ecf20Sopenharmony_ci	if (!em)
758c2ecf20Sopenharmony_ci		return;
768c2ecf20Sopenharmony_ci	WARN_ON(refcount_read(&em->refs) == 0);
778c2ecf20Sopenharmony_ci	if (refcount_dec_and_test(&em->refs)) {
788c2ecf20Sopenharmony_ci		WARN_ON(extent_map_in_tree(em));
798c2ecf20Sopenharmony_ci		WARN_ON(!list_empty(&em->list));
808c2ecf20Sopenharmony_ci		if (test_bit(EXTENT_FLAG_FS_MAPPING, &em->flags))
818c2ecf20Sopenharmony_ci			kfree(em->map_lookup);
828c2ecf20Sopenharmony_ci		kmem_cache_free(extent_map_cache, em);
838c2ecf20Sopenharmony_ci	}
848c2ecf20Sopenharmony_ci}
858c2ecf20Sopenharmony_ci
868c2ecf20Sopenharmony_ci/* simple helper to do math around the end of an extent, handling wrap */
878c2ecf20Sopenharmony_cistatic u64 range_end(u64 start, u64 len)
888c2ecf20Sopenharmony_ci{
898c2ecf20Sopenharmony_ci	if (start + len < start)
908c2ecf20Sopenharmony_ci		return (u64)-1;
918c2ecf20Sopenharmony_ci	return start + len;
928c2ecf20Sopenharmony_ci}
938c2ecf20Sopenharmony_ci
948c2ecf20Sopenharmony_cistatic int tree_insert(struct rb_root_cached *root, struct extent_map *em)
958c2ecf20Sopenharmony_ci{
968c2ecf20Sopenharmony_ci	struct rb_node **p = &root->rb_root.rb_node;
978c2ecf20Sopenharmony_ci	struct rb_node *parent = NULL;
988c2ecf20Sopenharmony_ci	struct extent_map *entry = NULL;
998c2ecf20Sopenharmony_ci	struct rb_node *orig_parent = NULL;
1008c2ecf20Sopenharmony_ci	u64 end = range_end(em->start, em->len);
1018c2ecf20Sopenharmony_ci	bool leftmost = true;
1028c2ecf20Sopenharmony_ci
1038c2ecf20Sopenharmony_ci	while (*p) {
1048c2ecf20Sopenharmony_ci		parent = *p;
1058c2ecf20Sopenharmony_ci		entry = rb_entry(parent, struct extent_map, rb_node);
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci		if (em->start < entry->start) {
1088c2ecf20Sopenharmony_ci			p = &(*p)->rb_left;
1098c2ecf20Sopenharmony_ci		} else if (em->start >= extent_map_end(entry)) {
1108c2ecf20Sopenharmony_ci			p = &(*p)->rb_right;
1118c2ecf20Sopenharmony_ci			leftmost = false;
1128c2ecf20Sopenharmony_ci		} else {
1138c2ecf20Sopenharmony_ci			return -EEXIST;
1148c2ecf20Sopenharmony_ci		}
1158c2ecf20Sopenharmony_ci	}
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	orig_parent = parent;
1188c2ecf20Sopenharmony_ci	while (parent && em->start >= extent_map_end(entry)) {
1198c2ecf20Sopenharmony_ci		parent = rb_next(parent);
1208c2ecf20Sopenharmony_ci		entry = rb_entry(parent, struct extent_map, rb_node);
1218c2ecf20Sopenharmony_ci	}
1228c2ecf20Sopenharmony_ci	if (parent)
1238c2ecf20Sopenharmony_ci		if (end > entry->start && em->start < extent_map_end(entry))
1248c2ecf20Sopenharmony_ci			return -EEXIST;
1258c2ecf20Sopenharmony_ci
1268c2ecf20Sopenharmony_ci	parent = orig_parent;
1278c2ecf20Sopenharmony_ci	entry = rb_entry(parent, struct extent_map, rb_node);
1288c2ecf20Sopenharmony_ci	while (parent && em->start < entry->start) {
1298c2ecf20Sopenharmony_ci		parent = rb_prev(parent);
1308c2ecf20Sopenharmony_ci		entry = rb_entry(parent, struct extent_map, rb_node);
1318c2ecf20Sopenharmony_ci	}
1328c2ecf20Sopenharmony_ci	if (parent)
1338c2ecf20Sopenharmony_ci		if (end > entry->start && em->start < extent_map_end(entry))
1348c2ecf20Sopenharmony_ci			return -EEXIST;
1358c2ecf20Sopenharmony_ci
1368c2ecf20Sopenharmony_ci	rb_link_node(&em->rb_node, orig_parent, p);
1378c2ecf20Sopenharmony_ci	rb_insert_color_cached(&em->rb_node, root, leftmost);
1388c2ecf20Sopenharmony_ci	return 0;
1398c2ecf20Sopenharmony_ci}
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci/*
1428c2ecf20Sopenharmony_ci * search through the tree for an extent_map with a given offset.  If
1438c2ecf20Sopenharmony_ci * it can't be found, try to find some neighboring extents
1448c2ecf20Sopenharmony_ci */
1458c2ecf20Sopenharmony_cistatic struct rb_node *__tree_search(struct rb_root *root, u64 offset,
1468c2ecf20Sopenharmony_ci				     struct rb_node **prev_ret,
1478c2ecf20Sopenharmony_ci				     struct rb_node **next_ret)
1488c2ecf20Sopenharmony_ci{
1498c2ecf20Sopenharmony_ci	struct rb_node *n = root->rb_node;
1508c2ecf20Sopenharmony_ci	struct rb_node *prev = NULL;
1518c2ecf20Sopenharmony_ci	struct rb_node *orig_prev = NULL;
1528c2ecf20Sopenharmony_ci	struct extent_map *entry;
1538c2ecf20Sopenharmony_ci	struct extent_map *prev_entry = NULL;
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_ci	while (n) {
1568c2ecf20Sopenharmony_ci		entry = rb_entry(n, struct extent_map, rb_node);
1578c2ecf20Sopenharmony_ci		prev = n;
1588c2ecf20Sopenharmony_ci		prev_entry = entry;
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ci		if (offset < entry->start)
1618c2ecf20Sopenharmony_ci			n = n->rb_left;
1628c2ecf20Sopenharmony_ci		else if (offset >= extent_map_end(entry))
1638c2ecf20Sopenharmony_ci			n = n->rb_right;
1648c2ecf20Sopenharmony_ci		else
1658c2ecf20Sopenharmony_ci			return n;
1668c2ecf20Sopenharmony_ci	}
1678c2ecf20Sopenharmony_ci
1688c2ecf20Sopenharmony_ci	if (prev_ret) {
1698c2ecf20Sopenharmony_ci		orig_prev = prev;
1708c2ecf20Sopenharmony_ci		while (prev && offset >= extent_map_end(prev_entry)) {
1718c2ecf20Sopenharmony_ci			prev = rb_next(prev);
1728c2ecf20Sopenharmony_ci			prev_entry = rb_entry(prev, struct extent_map, rb_node);
1738c2ecf20Sopenharmony_ci		}
1748c2ecf20Sopenharmony_ci		*prev_ret = prev;
1758c2ecf20Sopenharmony_ci		prev = orig_prev;
1768c2ecf20Sopenharmony_ci	}
1778c2ecf20Sopenharmony_ci
1788c2ecf20Sopenharmony_ci	if (next_ret) {
1798c2ecf20Sopenharmony_ci		prev_entry = rb_entry(prev, struct extent_map, rb_node);
1808c2ecf20Sopenharmony_ci		while (prev && offset < prev_entry->start) {
1818c2ecf20Sopenharmony_ci			prev = rb_prev(prev);
1828c2ecf20Sopenharmony_ci			prev_entry = rb_entry(prev, struct extent_map, rb_node);
1838c2ecf20Sopenharmony_ci		}
1848c2ecf20Sopenharmony_ci		*next_ret = prev;
1858c2ecf20Sopenharmony_ci	}
1868c2ecf20Sopenharmony_ci	return NULL;
1878c2ecf20Sopenharmony_ci}
1888c2ecf20Sopenharmony_ci
1898c2ecf20Sopenharmony_ci/* check to see if two extent_map structs are adjacent and safe to merge */
1908c2ecf20Sopenharmony_cistatic int mergable_maps(struct extent_map *prev, struct extent_map *next)
1918c2ecf20Sopenharmony_ci{
1928c2ecf20Sopenharmony_ci	if (test_bit(EXTENT_FLAG_PINNED, &prev->flags))
1938c2ecf20Sopenharmony_ci		return 0;
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci	/*
1968c2ecf20Sopenharmony_ci	 * don't merge compressed extents, we need to know their
1978c2ecf20Sopenharmony_ci	 * actual size
1988c2ecf20Sopenharmony_ci	 */
1998c2ecf20Sopenharmony_ci	if (test_bit(EXTENT_FLAG_COMPRESSED, &prev->flags))
2008c2ecf20Sopenharmony_ci		return 0;
2018c2ecf20Sopenharmony_ci
2028c2ecf20Sopenharmony_ci	if (test_bit(EXTENT_FLAG_LOGGING, &prev->flags) ||
2038c2ecf20Sopenharmony_ci	    test_bit(EXTENT_FLAG_LOGGING, &next->flags))
2048c2ecf20Sopenharmony_ci		return 0;
2058c2ecf20Sopenharmony_ci
2068c2ecf20Sopenharmony_ci	/*
2078c2ecf20Sopenharmony_ci	 * We don't want to merge stuff that hasn't been written to the log yet
2088c2ecf20Sopenharmony_ci	 * since it may not reflect exactly what is on disk, and that would be
2098c2ecf20Sopenharmony_ci	 * bad.
2108c2ecf20Sopenharmony_ci	 */
2118c2ecf20Sopenharmony_ci	if (!list_empty(&prev->list) || !list_empty(&next->list))
2128c2ecf20Sopenharmony_ci		return 0;
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	ASSERT(next->block_start != EXTENT_MAP_DELALLOC &&
2158c2ecf20Sopenharmony_ci	       prev->block_start != EXTENT_MAP_DELALLOC);
2168c2ecf20Sopenharmony_ci
2178c2ecf20Sopenharmony_ci	if (prev->map_lookup || next->map_lookup)
2188c2ecf20Sopenharmony_ci		ASSERT(test_bit(EXTENT_FLAG_FS_MAPPING, &prev->flags) &&
2198c2ecf20Sopenharmony_ci		       test_bit(EXTENT_FLAG_FS_MAPPING, &next->flags));
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci	if (extent_map_end(prev) == next->start &&
2228c2ecf20Sopenharmony_ci	    prev->flags == next->flags &&
2238c2ecf20Sopenharmony_ci	    prev->map_lookup == next->map_lookup &&
2248c2ecf20Sopenharmony_ci	    ((next->block_start == EXTENT_MAP_HOLE &&
2258c2ecf20Sopenharmony_ci	      prev->block_start == EXTENT_MAP_HOLE) ||
2268c2ecf20Sopenharmony_ci	     (next->block_start == EXTENT_MAP_INLINE &&
2278c2ecf20Sopenharmony_ci	      prev->block_start == EXTENT_MAP_INLINE) ||
2288c2ecf20Sopenharmony_ci	     (next->block_start < EXTENT_MAP_LAST_BYTE - 1 &&
2298c2ecf20Sopenharmony_ci	      next->block_start == extent_map_block_end(prev)))) {
2308c2ecf20Sopenharmony_ci		return 1;
2318c2ecf20Sopenharmony_ci	}
2328c2ecf20Sopenharmony_ci	return 0;
2338c2ecf20Sopenharmony_ci}
2348c2ecf20Sopenharmony_ci
2358c2ecf20Sopenharmony_cistatic void try_merge_map(struct extent_map_tree *tree, struct extent_map *em)
2368c2ecf20Sopenharmony_ci{
2378c2ecf20Sopenharmony_ci	struct extent_map *merge = NULL;
2388c2ecf20Sopenharmony_ci	struct rb_node *rb;
2398c2ecf20Sopenharmony_ci
2408c2ecf20Sopenharmony_ci	/*
2418c2ecf20Sopenharmony_ci	 * We can't modify an extent map that is in the tree and that is being
2428c2ecf20Sopenharmony_ci	 * used by another task, as it can cause that other task to see it in
2438c2ecf20Sopenharmony_ci	 * inconsistent state during the merging. We always have 1 reference for
2448c2ecf20Sopenharmony_ci	 * the tree and 1 for this task (which is unpinning the extent map or
2458c2ecf20Sopenharmony_ci	 * clearing the logging flag), so anything > 2 means it's being used by
2468c2ecf20Sopenharmony_ci	 * other tasks too.
2478c2ecf20Sopenharmony_ci	 */
2488c2ecf20Sopenharmony_ci	if (refcount_read(&em->refs) > 2)
2498c2ecf20Sopenharmony_ci		return;
2508c2ecf20Sopenharmony_ci
2518c2ecf20Sopenharmony_ci	if (em->start != 0) {
2528c2ecf20Sopenharmony_ci		rb = rb_prev(&em->rb_node);
2538c2ecf20Sopenharmony_ci		if (rb)
2548c2ecf20Sopenharmony_ci			merge = rb_entry(rb, struct extent_map, rb_node);
2558c2ecf20Sopenharmony_ci		if (rb && mergable_maps(merge, em)) {
2568c2ecf20Sopenharmony_ci			em->start = merge->start;
2578c2ecf20Sopenharmony_ci			em->orig_start = merge->orig_start;
2588c2ecf20Sopenharmony_ci			em->len += merge->len;
2598c2ecf20Sopenharmony_ci			em->block_len += merge->block_len;
2608c2ecf20Sopenharmony_ci			em->block_start = merge->block_start;
2618c2ecf20Sopenharmony_ci			em->mod_len = (em->mod_len + em->mod_start) - merge->mod_start;
2628c2ecf20Sopenharmony_ci			em->mod_start = merge->mod_start;
2638c2ecf20Sopenharmony_ci			em->generation = max(em->generation, merge->generation);
2648c2ecf20Sopenharmony_ci
2658c2ecf20Sopenharmony_ci			rb_erase_cached(&merge->rb_node, &tree->map);
2668c2ecf20Sopenharmony_ci			RB_CLEAR_NODE(&merge->rb_node);
2678c2ecf20Sopenharmony_ci			free_extent_map(merge);
2688c2ecf20Sopenharmony_ci		}
2698c2ecf20Sopenharmony_ci	}
2708c2ecf20Sopenharmony_ci
2718c2ecf20Sopenharmony_ci	rb = rb_next(&em->rb_node);
2728c2ecf20Sopenharmony_ci	if (rb)
2738c2ecf20Sopenharmony_ci		merge = rb_entry(rb, struct extent_map, rb_node);
2748c2ecf20Sopenharmony_ci	if (rb && mergable_maps(em, merge)) {
2758c2ecf20Sopenharmony_ci		em->len += merge->len;
2768c2ecf20Sopenharmony_ci		em->block_len += merge->block_len;
2778c2ecf20Sopenharmony_ci		rb_erase_cached(&merge->rb_node, &tree->map);
2788c2ecf20Sopenharmony_ci		RB_CLEAR_NODE(&merge->rb_node);
2798c2ecf20Sopenharmony_ci		em->mod_len = (merge->mod_start + merge->mod_len) - em->mod_start;
2808c2ecf20Sopenharmony_ci		em->generation = max(em->generation, merge->generation);
2818c2ecf20Sopenharmony_ci		free_extent_map(merge);
2828c2ecf20Sopenharmony_ci	}
2838c2ecf20Sopenharmony_ci}
2848c2ecf20Sopenharmony_ci
2858c2ecf20Sopenharmony_ci/**
2868c2ecf20Sopenharmony_ci * unpin_extent_cache - unpin an extent from the cache
2878c2ecf20Sopenharmony_ci * @tree:	tree to unpin the extent in
2888c2ecf20Sopenharmony_ci * @start:	logical offset in the file
2898c2ecf20Sopenharmony_ci * @len:	length of the extent
2908c2ecf20Sopenharmony_ci * @gen:	generation that this extent has been modified in
2918c2ecf20Sopenharmony_ci *
2928c2ecf20Sopenharmony_ci * Called after an extent has been written to disk properly.  Set the generation
2938c2ecf20Sopenharmony_ci * to the generation that actually added the file item to the inode so we know
2948c2ecf20Sopenharmony_ci * we need to sync this extent when we call fsync().
2958c2ecf20Sopenharmony_ci */
2968c2ecf20Sopenharmony_ciint unpin_extent_cache(struct extent_map_tree *tree, u64 start, u64 len,
2978c2ecf20Sopenharmony_ci		       u64 gen)
2988c2ecf20Sopenharmony_ci{
2998c2ecf20Sopenharmony_ci	int ret = 0;
3008c2ecf20Sopenharmony_ci	struct extent_map *em;
3018c2ecf20Sopenharmony_ci	bool prealloc = false;
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci	write_lock(&tree->lock);
3048c2ecf20Sopenharmony_ci	em = lookup_extent_mapping(tree, start, len);
3058c2ecf20Sopenharmony_ci
3068c2ecf20Sopenharmony_ci	WARN_ON(!em || em->start != start);
3078c2ecf20Sopenharmony_ci
3088c2ecf20Sopenharmony_ci	if (!em)
3098c2ecf20Sopenharmony_ci		goto out;
3108c2ecf20Sopenharmony_ci
3118c2ecf20Sopenharmony_ci	em->generation = gen;
3128c2ecf20Sopenharmony_ci	clear_bit(EXTENT_FLAG_PINNED, &em->flags);
3138c2ecf20Sopenharmony_ci	em->mod_start = em->start;
3148c2ecf20Sopenharmony_ci	em->mod_len = em->len;
3158c2ecf20Sopenharmony_ci
3168c2ecf20Sopenharmony_ci	if (test_bit(EXTENT_FLAG_FILLING, &em->flags)) {
3178c2ecf20Sopenharmony_ci		prealloc = true;
3188c2ecf20Sopenharmony_ci		clear_bit(EXTENT_FLAG_FILLING, &em->flags);
3198c2ecf20Sopenharmony_ci	}
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci	try_merge_map(tree, em);
3228c2ecf20Sopenharmony_ci
3238c2ecf20Sopenharmony_ci	if (prealloc) {
3248c2ecf20Sopenharmony_ci		em->mod_start = em->start;
3258c2ecf20Sopenharmony_ci		em->mod_len = em->len;
3268c2ecf20Sopenharmony_ci	}
3278c2ecf20Sopenharmony_ci
3288c2ecf20Sopenharmony_ci	free_extent_map(em);
3298c2ecf20Sopenharmony_ciout:
3308c2ecf20Sopenharmony_ci	write_unlock(&tree->lock);
3318c2ecf20Sopenharmony_ci	return ret;
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci}
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_civoid clear_em_logging(struct extent_map_tree *tree, struct extent_map *em)
3368c2ecf20Sopenharmony_ci{
3378c2ecf20Sopenharmony_ci	clear_bit(EXTENT_FLAG_LOGGING, &em->flags);
3388c2ecf20Sopenharmony_ci	if (extent_map_in_tree(em))
3398c2ecf20Sopenharmony_ci		try_merge_map(tree, em);
3408c2ecf20Sopenharmony_ci}
3418c2ecf20Sopenharmony_ci
3428c2ecf20Sopenharmony_cistatic inline void setup_extent_mapping(struct extent_map_tree *tree,
3438c2ecf20Sopenharmony_ci					struct extent_map *em,
3448c2ecf20Sopenharmony_ci					int modified)
3458c2ecf20Sopenharmony_ci{
3468c2ecf20Sopenharmony_ci	refcount_inc(&em->refs);
3478c2ecf20Sopenharmony_ci	em->mod_start = em->start;
3488c2ecf20Sopenharmony_ci	em->mod_len = em->len;
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_ci	if (modified)
3518c2ecf20Sopenharmony_ci		list_move(&em->list, &tree->modified_extents);
3528c2ecf20Sopenharmony_ci	else
3538c2ecf20Sopenharmony_ci		try_merge_map(tree, em);
3548c2ecf20Sopenharmony_ci}
3558c2ecf20Sopenharmony_ci
3568c2ecf20Sopenharmony_cistatic void extent_map_device_set_bits(struct extent_map *em, unsigned bits)
3578c2ecf20Sopenharmony_ci{
3588c2ecf20Sopenharmony_ci	struct map_lookup *map = em->map_lookup;
3598c2ecf20Sopenharmony_ci	u64 stripe_size = em->orig_block_len;
3608c2ecf20Sopenharmony_ci	int i;
3618c2ecf20Sopenharmony_ci
3628c2ecf20Sopenharmony_ci	for (i = 0; i < map->num_stripes; i++) {
3638c2ecf20Sopenharmony_ci		struct btrfs_bio_stripe *stripe = &map->stripes[i];
3648c2ecf20Sopenharmony_ci		struct btrfs_device *device = stripe->dev;
3658c2ecf20Sopenharmony_ci
3668c2ecf20Sopenharmony_ci		set_extent_bits_nowait(&device->alloc_state, stripe->physical,
3678c2ecf20Sopenharmony_ci				 stripe->physical + stripe_size - 1, bits);
3688c2ecf20Sopenharmony_ci	}
3698c2ecf20Sopenharmony_ci}
3708c2ecf20Sopenharmony_ci
3718c2ecf20Sopenharmony_cistatic void extent_map_device_clear_bits(struct extent_map *em, unsigned bits)
3728c2ecf20Sopenharmony_ci{
3738c2ecf20Sopenharmony_ci	struct map_lookup *map = em->map_lookup;
3748c2ecf20Sopenharmony_ci	u64 stripe_size = em->orig_block_len;
3758c2ecf20Sopenharmony_ci	int i;
3768c2ecf20Sopenharmony_ci
3778c2ecf20Sopenharmony_ci	for (i = 0; i < map->num_stripes; i++) {
3788c2ecf20Sopenharmony_ci		struct btrfs_bio_stripe *stripe = &map->stripes[i];
3798c2ecf20Sopenharmony_ci		struct btrfs_device *device = stripe->dev;
3808c2ecf20Sopenharmony_ci
3818c2ecf20Sopenharmony_ci		__clear_extent_bit(&device->alloc_state, stripe->physical,
3828c2ecf20Sopenharmony_ci				   stripe->physical + stripe_size - 1, bits,
3838c2ecf20Sopenharmony_ci				   0, 0, NULL, GFP_NOWAIT, NULL);
3848c2ecf20Sopenharmony_ci	}
3858c2ecf20Sopenharmony_ci}
3868c2ecf20Sopenharmony_ci
3878c2ecf20Sopenharmony_ci/**
3888c2ecf20Sopenharmony_ci * add_extent_mapping - add new extent map to the extent tree
3898c2ecf20Sopenharmony_ci * @tree:	tree to insert new map in
3908c2ecf20Sopenharmony_ci * @em:		map to insert
3918c2ecf20Sopenharmony_ci *
3928c2ecf20Sopenharmony_ci * Insert @em into @tree or perform a simple forward/backward merge with
3938c2ecf20Sopenharmony_ci * existing mappings.  The extent_map struct passed in will be inserted
3948c2ecf20Sopenharmony_ci * into the tree directly, with an additional reference taken, or a
3958c2ecf20Sopenharmony_ci * reference dropped if the merge attempt was successful.
3968c2ecf20Sopenharmony_ci */
3978c2ecf20Sopenharmony_ciint add_extent_mapping(struct extent_map_tree *tree,
3988c2ecf20Sopenharmony_ci		       struct extent_map *em, int modified)
3998c2ecf20Sopenharmony_ci{
4008c2ecf20Sopenharmony_ci	int ret = 0;
4018c2ecf20Sopenharmony_ci
4028c2ecf20Sopenharmony_ci	lockdep_assert_held_write(&tree->lock);
4038c2ecf20Sopenharmony_ci
4048c2ecf20Sopenharmony_ci	ret = tree_insert(&tree->map, em);
4058c2ecf20Sopenharmony_ci	if (ret)
4068c2ecf20Sopenharmony_ci		goto out;
4078c2ecf20Sopenharmony_ci
4088c2ecf20Sopenharmony_ci	setup_extent_mapping(tree, em, modified);
4098c2ecf20Sopenharmony_ci	if (test_bit(EXTENT_FLAG_FS_MAPPING, &em->flags)) {
4108c2ecf20Sopenharmony_ci		extent_map_device_set_bits(em, CHUNK_ALLOCATED);
4118c2ecf20Sopenharmony_ci		extent_map_device_clear_bits(em, CHUNK_TRIMMED);
4128c2ecf20Sopenharmony_ci	}
4138c2ecf20Sopenharmony_ciout:
4148c2ecf20Sopenharmony_ci	return ret;
4158c2ecf20Sopenharmony_ci}
4168c2ecf20Sopenharmony_ci
4178c2ecf20Sopenharmony_cistatic struct extent_map *
4188c2ecf20Sopenharmony_ci__lookup_extent_mapping(struct extent_map_tree *tree,
4198c2ecf20Sopenharmony_ci			u64 start, u64 len, int strict)
4208c2ecf20Sopenharmony_ci{
4218c2ecf20Sopenharmony_ci	struct extent_map *em;
4228c2ecf20Sopenharmony_ci	struct rb_node *rb_node;
4238c2ecf20Sopenharmony_ci	struct rb_node *prev = NULL;
4248c2ecf20Sopenharmony_ci	struct rb_node *next = NULL;
4258c2ecf20Sopenharmony_ci	u64 end = range_end(start, len);
4268c2ecf20Sopenharmony_ci
4278c2ecf20Sopenharmony_ci	rb_node = __tree_search(&tree->map.rb_root, start, &prev, &next);
4288c2ecf20Sopenharmony_ci	if (!rb_node) {
4298c2ecf20Sopenharmony_ci		if (prev)
4308c2ecf20Sopenharmony_ci			rb_node = prev;
4318c2ecf20Sopenharmony_ci		else if (next)
4328c2ecf20Sopenharmony_ci			rb_node = next;
4338c2ecf20Sopenharmony_ci		else
4348c2ecf20Sopenharmony_ci			return NULL;
4358c2ecf20Sopenharmony_ci	}
4368c2ecf20Sopenharmony_ci
4378c2ecf20Sopenharmony_ci	em = rb_entry(rb_node, struct extent_map, rb_node);
4388c2ecf20Sopenharmony_ci
4398c2ecf20Sopenharmony_ci	if (strict && !(end > em->start && start < extent_map_end(em)))
4408c2ecf20Sopenharmony_ci		return NULL;
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_ci	refcount_inc(&em->refs);
4438c2ecf20Sopenharmony_ci	return em;
4448c2ecf20Sopenharmony_ci}
4458c2ecf20Sopenharmony_ci
4468c2ecf20Sopenharmony_ci/**
4478c2ecf20Sopenharmony_ci * lookup_extent_mapping - lookup extent_map
4488c2ecf20Sopenharmony_ci * @tree:	tree to lookup in
4498c2ecf20Sopenharmony_ci * @start:	byte offset to start the search
4508c2ecf20Sopenharmony_ci * @len:	length of the lookup range
4518c2ecf20Sopenharmony_ci *
4528c2ecf20Sopenharmony_ci * Find and return the first extent_map struct in @tree that intersects the
4538c2ecf20Sopenharmony_ci * [start, len] range.  There may be additional objects in the tree that
4548c2ecf20Sopenharmony_ci * intersect, so check the object returned carefully to make sure that no
4558c2ecf20Sopenharmony_ci * additional lookups are needed.
4568c2ecf20Sopenharmony_ci */
4578c2ecf20Sopenharmony_cistruct extent_map *lookup_extent_mapping(struct extent_map_tree *tree,
4588c2ecf20Sopenharmony_ci					 u64 start, u64 len)
4598c2ecf20Sopenharmony_ci{
4608c2ecf20Sopenharmony_ci	return __lookup_extent_mapping(tree, start, len, 1);
4618c2ecf20Sopenharmony_ci}
4628c2ecf20Sopenharmony_ci
4638c2ecf20Sopenharmony_ci/**
4648c2ecf20Sopenharmony_ci * search_extent_mapping - find a nearby extent map
4658c2ecf20Sopenharmony_ci * @tree:	tree to lookup in
4668c2ecf20Sopenharmony_ci * @start:	byte offset to start the search
4678c2ecf20Sopenharmony_ci * @len:	length of the lookup range
4688c2ecf20Sopenharmony_ci *
4698c2ecf20Sopenharmony_ci * Find and return the first extent_map struct in @tree that intersects the
4708c2ecf20Sopenharmony_ci * [start, len] range.
4718c2ecf20Sopenharmony_ci *
4728c2ecf20Sopenharmony_ci * If one can't be found, any nearby extent may be returned
4738c2ecf20Sopenharmony_ci */
4748c2ecf20Sopenharmony_cistruct extent_map *search_extent_mapping(struct extent_map_tree *tree,
4758c2ecf20Sopenharmony_ci					 u64 start, u64 len)
4768c2ecf20Sopenharmony_ci{
4778c2ecf20Sopenharmony_ci	return __lookup_extent_mapping(tree, start, len, 0);
4788c2ecf20Sopenharmony_ci}
4798c2ecf20Sopenharmony_ci
4808c2ecf20Sopenharmony_ci/**
4818c2ecf20Sopenharmony_ci * remove_extent_mapping - removes an extent_map from the extent tree
4828c2ecf20Sopenharmony_ci * @tree:	extent tree to remove from
4838c2ecf20Sopenharmony_ci * @em:		extent map being removed
4848c2ecf20Sopenharmony_ci *
4858c2ecf20Sopenharmony_ci * Removes @em from @tree.  No reference counts are dropped, and no checks
4868c2ecf20Sopenharmony_ci * are done to see if the range is in use
4878c2ecf20Sopenharmony_ci */
4888c2ecf20Sopenharmony_civoid remove_extent_mapping(struct extent_map_tree *tree, struct extent_map *em)
4898c2ecf20Sopenharmony_ci{
4908c2ecf20Sopenharmony_ci	WARN_ON(test_bit(EXTENT_FLAG_PINNED, &em->flags));
4918c2ecf20Sopenharmony_ci	rb_erase_cached(&em->rb_node, &tree->map);
4928c2ecf20Sopenharmony_ci	if (!test_bit(EXTENT_FLAG_LOGGING, &em->flags))
4938c2ecf20Sopenharmony_ci		list_del_init(&em->list);
4948c2ecf20Sopenharmony_ci	if (test_bit(EXTENT_FLAG_FS_MAPPING, &em->flags))
4958c2ecf20Sopenharmony_ci		extent_map_device_clear_bits(em, CHUNK_ALLOCATED);
4968c2ecf20Sopenharmony_ci	RB_CLEAR_NODE(&em->rb_node);
4978c2ecf20Sopenharmony_ci}
4988c2ecf20Sopenharmony_ci
4998c2ecf20Sopenharmony_civoid replace_extent_mapping(struct extent_map_tree *tree,
5008c2ecf20Sopenharmony_ci			    struct extent_map *cur,
5018c2ecf20Sopenharmony_ci			    struct extent_map *new,
5028c2ecf20Sopenharmony_ci			    int modified)
5038c2ecf20Sopenharmony_ci{
5048c2ecf20Sopenharmony_ci	WARN_ON(test_bit(EXTENT_FLAG_PINNED, &cur->flags));
5058c2ecf20Sopenharmony_ci	ASSERT(extent_map_in_tree(cur));
5068c2ecf20Sopenharmony_ci	if (!test_bit(EXTENT_FLAG_LOGGING, &cur->flags))
5078c2ecf20Sopenharmony_ci		list_del_init(&cur->list);
5088c2ecf20Sopenharmony_ci	rb_replace_node_cached(&cur->rb_node, &new->rb_node, &tree->map);
5098c2ecf20Sopenharmony_ci	RB_CLEAR_NODE(&cur->rb_node);
5108c2ecf20Sopenharmony_ci
5118c2ecf20Sopenharmony_ci	setup_extent_mapping(tree, new, modified);
5128c2ecf20Sopenharmony_ci}
5138c2ecf20Sopenharmony_ci
5148c2ecf20Sopenharmony_cistatic struct extent_map *next_extent_map(struct extent_map *em)
5158c2ecf20Sopenharmony_ci{
5168c2ecf20Sopenharmony_ci	struct rb_node *next;
5178c2ecf20Sopenharmony_ci
5188c2ecf20Sopenharmony_ci	next = rb_next(&em->rb_node);
5198c2ecf20Sopenharmony_ci	if (!next)
5208c2ecf20Sopenharmony_ci		return NULL;
5218c2ecf20Sopenharmony_ci	return container_of(next, struct extent_map, rb_node);
5228c2ecf20Sopenharmony_ci}
5238c2ecf20Sopenharmony_ci
5248c2ecf20Sopenharmony_cistatic struct extent_map *prev_extent_map(struct extent_map *em)
5258c2ecf20Sopenharmony_ci{
5268c2ecf20Sopenharmony_ci	struct rb_node *prev;
5278c2ecf20Sopenharmony_ci
5288c2ecf20Sopenharmony_ci	prev = rb_prev(&em->rb_node);
5298c2ecf20Sopenharmony_ci	if (!prev)
5308c2ecf20Sopenharmony_ci		return NULL;
5318c2ecf20Sopenharmony_ci	return container_of(prev, struct extent_map, rb_node);
5328c2ecf20Sopenharmony_ci}
5338c2ecf20Sopenharmony_ci
5348c2ecf20Sopenharmony_ci/*
5358c2ecf20Sopenharmony_ci * Helper for btrfs_get_extent.  Given an existing extent in the tree,
5368c2ecf20Sopenharmony_ci * the existing extent is the nearest extent to map_start,
5378c2ecf20Sopenharmony_ci * and an extent that you want to insert, deal with overlap and insert
5388c2ecf20Sopenharmony_ci * the best fitted new extent into the tree.
5398c2ecf20Sopenharmony_ci */
5408c2ecf20Sopenharmony_cistatic noinline int merge_extent_mapping(struct extent_map_tree *em_tree,
5418c2ecf20Sopenharmony_ci					 struct extent_map *existing,
5428c2ecf20Sopenharmony_ci					 struct extent_map *em,
5438c2ecf20Sopenharmony_ci					 u64 map_start)
5448c2ecf20Sopenharmony_ci{
5458c2ecf20Sopenharmony_ci	struct extent_map *prev;
5468c2ecf20Sopenharmony_ci	struct extent_map *next;
5478c2ecf20Sopenharmony_ci	u64 start;
5488c2ecf20Sopenharmony_ci	u64 end;
5498c2ecf20Sopenharmony_ci	u64 start_diff;
5508c2ecf20Sopenharmony_ci
5518c2ecf20Sopenharmony_ci	BUG_ON(map_start < em->start || map_start >= extent_map_end(em));
5528c2ecf20Sopenharmony_ci
5538c2ecf20Sopenharmony_ci	if (existing->start > map_start) {
5548c2ecf20Sopenharmony_ci		next = existing;
5558c2ecf20Sopenharmony_ci		prev = prev_extent_map(next);
5568c2ecf20Sopenharmony_ci	} else {
5578c2ecf20Sopenharmony_ci		prev = existing;
5588c2ecf20Sopenharmony_ci		next = next_extent_map(prev);
5598c2ecf20Sopenharmony_ci	}
5608c2ecf20Sopenharmony_ci
5618c2ecf20Sopenharmony_ci	start = prev ? extent_map_end(prev) : em->start;
5628c2ecf20Sopenharmony_ci	start = max_t(u64, start, em->start);
5638c2ecf20Sopenharmony_ci	end = next ? next->start : extent_map_end(em);
5648c2ecf20Sopenharmony_ci	end = min_t(u64, end, extent_map_end(em));
5658c2ecf20Sopenharmony_ci	start_diff = start - em->start;
5668c2ecf20Sopenharmony_ci	em->start = start;
5678c2ecf20Sopenharmony_ci	em->len = end - start;
5688c2ecf20Sopenharmony_ci	if (em->block_start < EXTENT_MAP_LAST_BYTE &&
5698c2ecf20Sopenharmony_ci	    !test_bit(EXTENT_FLAG_COMPRESSED, &em->flags)) {
5708c2ecf20Sopenharmony_ci		em->block_start += start_diff;
5718c2ecf20Sopenharmony_ci		em->block_len = em->len;
5728c2ecf20Sopenharmony_ci	}
5738c2ecf20Sopenharmony_ci	return add_extent_mapping(em_tree, em, 0);
5748c2ecf20Sopenharmony_ci}
5758c2ecf20Sopenharmony_ci
5768c2ecf20Sopenharmony_ci/**
5778c2ecf20Sopenharmony_ci * btrfs_add_extent_mapping - add extent mapping into em_tree
5788c2ecf20Sopenharmony_ci * @fs_info - used for tracepoint
5798c2ecf20Sopenharmony_ci * @em_tree - the extent tree into which we want to insert the extent mapping
5808c2ecf20Sopenharmony_ci * @em_in   - extent we are inserting
5818c2ecf20Sopenharmony_ci * @start   - start of the logical range btrfs_get_extent() is requesting
5828c2ecf20Sopenharmony_ci * @len     - length of the logical range btrfs_get_extent() is requesting
5838c2ecf20Sopenharmony_ci *
5848c2ecf20Sopenharmony_ci * Note that @em_in's range may be different from [start, start+len),
5858c2ecf20Sopenharmony_ci * but they must be overlapped.
5868c2ecf20Sopenharmony_ci *
5878c2ecf20Sopenharmony_ci * Insert @em_in into @em_tree. In case there is an overlapping range, handle
5888c2ecf20Sopenharmony_ci * the -EEXIST by either:
5898c2ecf20Sopenharmony_ci * a) Returning the existing extent in @em_in if @start is within the
5908c2ecf20Sopenharmony_ci *    existing em.
5918c2ecf20Sopenharmony_ci * b) Merge the existing extent with @em_in passed in.
5928c2ecf20Sopenharmony_ci *
5938c2ecf20Sopenharmony_ci * Return 0 on success, otherwise -EEXIST.
5948c2ecf20Sopenharmony_ci *
5958c2ecf20Sopenharmony_ci */
5968c2ecf20Sopenharmony_ciint btrfs_add_extent_mapping(struct btrfs_fs_info *fs_info,
5978c2ecf20Sopenharmony_ci			     struct extent_map_tree *em_tree,
5988c2ecf20Sopenharmony_ci			     struct extent_map **em_in, u64 start, u64 len)
5998c2ecf20Sopenharmony_ci{
6008c2ecf20Sopenharmony_ci	int ret;
6018c2ecf20Sopenharmony_ci	struct extent_map *em = *em_in;
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_ci	ret = add_extent_mapping(em_tree, em, 0);
6048c2ecf20Sopenharmony_ci	/* it is possible that someone inserted the extent into the tree
6058c2ecf20Sopenharmony_ci	 * while we had the lock dropped.  It is also possible that
6068c2ecf20Sopenharmony_ci	 * an overlapping map exists in the tree
6078c2ecf20Sopenharmony_ci	 */
6088c2ecf20Sopenharmony_ci	if (ret == -EEXIST) {
6098c2ecf20Sopenharmony_ci		struct extent_map *existing;
6108c2ecf20Sopenharmony_ci
6118c2ecf20Sopenharmony_ci		ret = 0;
6128c2ecf20Sopenharmony_ci
6138c2ecf20Sopenharmony_ci		existing = search_extent_mapping(em_tree, start, len);
6148c2ecf20Sopenharmony_ci
6158c2ecf20Sopenharmony_ci		trace_btrfs_handle_em_exist(fs_info, existing, em, start, len);
6168c2ecf20Sopenharmony_ci
6178c2ecf20Sopenharmony_ci		/*
6188c2ecf20Sopenharmony_ci		 * existing will always be non-NULL, since there must be
6198c2ecf20Sopenharmony_ci		 * extent causing the -EEXIST.
6208c2ecf20Sopenharmony_ci		 */
6218c2ecf20Sopenharmony_ci		if (start >= existing->start &&
6228c2ecf20Sopenharmony_ci		    start < extent_map_end(existing)) {
6238c2ecf20Sopenharmony_ci			free_extent_map(em);
6248c2ecf20Sopenharmony_ci			*em_in = existing;
6258c2ecf20Sopenharmony_ci			ret = 0;
6268c2ecf20Sopenharmony_ci		} else {
6278c2ecf20Sopenharmony_ci			u64 orig_start = em->start;
6288c2ecf20Sopenharmony_ci			u64 orig_len = em->len;
6298c2ecf20Sopenharmony_ci
6308c2ecf20Sopenharmony_ci			/*
6318c2ecf20Sopenharmony_ci			 * The existing extent map is the one nearest to
6328c2ecf20Sopenharmony_ci			 * the [start, start + len) range which overlaps
6338c2ecf20Sopenharmony_ci			 */
6348c2ecf20Sopenharmony_ci			ret = merge_extent_mapping(em_tree, existing,
6358c2ecf20Sopenharmony_ci						   em, start);
6368c2ecf20Sopenharmony_ci			if (ret) {
6378c2ecf20Sopenharmony_ci				free_extent_map(em);
6388c2ecf20Sopenharmony_ci				*em_in = NULL;
6398c2ecf20Sopenharmony_ci				WARN_ONCE(ret,
6408c2ecf20Sopenharmony_ci"unexpected error %d: merge existing(start %llu len %llu) with em(start %llu len %llu)\n",
6418c2ecf20Sopenharmony_ci					  ret, existing->start, existing->len,
6428c2ecf20Sopenharmony_ci					  orig_start, orig_len);
6438c2ecf20Sopenharmony_ci			}
6448c2ecf20Sopenharmony_ci			free_extent_map(existing);
6458c2ecf20Sopenharmony_ci		}
6468c2ecf20Sopenharmony_ci	}
6478c2ecf20Sopenharmony_ci
6488c2ecf20Sopenharmony_ci	ASSERT(ret == 0 || ret == -EEXIST);
6498c2ecf20Sopenharmony_ci	return ret;
6508c2ecf20Sopenharmony_ci}
651