18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Copyright (C) 2009 Oracle.  All rights reserved.
48c2ecf20Sopenharmony_ci */
58c2ecf20Sopenharmony_ci
68c2ecf20Sopenharmony_ci#include <linux/sched.h>
78c2ecf20Sopenharmony_ci#include <linux/slab.h>
88c2ecf20Sopenharmony_ci#include <linux/sort.h>
98c2ecf20Sopenharmony_ci#include "ctree.h"
108c2ecf20Sopenharmony_ci#include "delayed-ref.h"
118c2ecf20Sopenharmony_ci#include "transaction.h"
128c2ecf20Sopenharmony_ci#include "qgroup.h"
138c2ecf20Sopenharmony_ci#include "space-info.h"
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_cistruct kmem_cache *btrfs_delayed_ref_head_cachep;
168c2ecf20Sopenharmony_cistruct kmem_cache *btrfs_delayed_tree_ref_cachep;
178c2ecf20Sopenharmony_cistruct kmem_cache *btrfs_delayed_data_ref_cachep;
188c2ecf20Sopenharmony_cistruct kmem_cache *btrfs_delayed_extent_op_cachep;
198c2ecf20Sopenharmony_ci/*
208c2ecf20Sopenharmony_ci * delayed back reference update tracking.  For subvolume trees
218c2ecf20Sopenharmony_ci * we queue up extent allocations and backref maintenance for
228c2ecf20Sopenharmony_ci * delayed processing.   This avoids deep call chains where we
238c2ecf20Sopenharmony_ci * add extents in the middle of btrfs_search_slot, and it allows
248c2ecf20Sopenharmony_ci * us to buffer up frequently modified backrefs in an rb tree instead
258c2ecf20Sopenharmony_ci * of hammering updates on the extent allocation tree.
268c2ecf20Sopenharmony_ci */
278c2ecf20Sopenharmony_ci
288c2ecf20Sopenharmony_cibool btrfs_check_space_for_delayed_refs(struct btrfs_fs_info *fs_info)
298c2ecf20Sopenharmony_ci{
308c2ecf20Sopenharmony_ci	struct btrfs_block_rsv *delayed_refs_rsv = &fs_info->delayed_refs_rsv;
318c2ecf20Sopenharmony_ci	struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv;
328c2ecf20Sopenharmony_ci	bool ret = false;
338c2ecf20Sopenharmony_ci	u64 reserved;
348c2ecf20Sopenharmony_ci
358c2ecf20Sopenharmony_ci	spin_lock(&global_rsv->lock);
368c2ecf20Sopenharmony_ci	reserved = global_rsv->reserved;
378c2ecf20Sopenharmony_ci	spin_unlock(&global_rsv->lock);
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci	/*
408c2ecf20Sopenharmony_ci	 * Since the global reserve is just kind of magic we don't really want
418c2ecf20Sopenharmony_ci	 * to rely on it to save our bacon, so if our size is more than the
428c2ecf20Sopenharmony_ci	 * delayed_refs_rsv and the global rsv then it's time to think about
438c2ecf20Sopenharmony_ci	 * bailing.
448c2ecf20Sopenharmony_ci	 */
458c2ecf20Sopenharmony_ci	spin_lock(&delayed_refs_rsv->lock);
468c2ecf20Sopenharmony_ci	reserved += delayed_refs_rsv->reserved;
478c2ecf20Sopenharmony_ci	if (delayed_refs_rsv->size >= reserved)
488c2ecf20Sopenharmony_ci		ret = true;
498c2ecf20Sopenharmony_ci	spin_unlock(&delayed_refs_rsv->lock);
508c2ecf20Sopenharmony_ci	return ret;
518c2ecf20Sopenharmony_ci}
528c2ecf20Sopenharmony_ci
538c2ecf20Sopenharmony_ciint btrfs_should_throttle_delayed_refs(struct btrfs_trans_handle *trans)
548c2ecf20Sopenharmony_ci{
558c2ecf20Sopenharmony_ci	u64 num_entries =
568c2ecf20Sopenharmony_ci		atomic_read(&trans->transaction->delayed_refs.num_entries);
578c2ecf20Sopenharmony_ci	u64 avg_runtime;
588c2ecf20Sopenharmony_ci	u64 val;
598c2ecf20Sopenharmony_ci
608c2ecf20Sopenharmony_ci	smp_mb();
618c2ecf20Sopenharmony_ci	avg_runtime = trans->fs_info->avg_delayed_ref_runtime;
628c2ecf20Sopenharmony_ci	val = num_entries * avg_runtime;
638c2ecf20Sopenharmony_ci	if (val >= NSEC_PER_SEC)
648c2ecf20Sopenharmony_ci		return 1;
658c2ecf20Sopenharmony_ci	if (val >= NSEC_PER_SEC / 2)
668c2ecf20Sopenharmony_ci		return 2;
678c2ecf20Sopenharmony_ci
688c2ecf20Sopenharmony_ci	return btrfs_check_space_for_delayed_refs(trans->fs_info);
698c2ecf20Sopenharmony_ci}
708c2ecf20Sopenharmony_ci
718c2ecf20Sopenharmony_ci/**
728c2ecf20Sopenharmony_ci * btrfs_delayed_refs_rsv_release - release a ref head's reservation.
738c2ecf20Sopenharmony_ci * @fs_info - the fs_info for our fs.
748c2ecf20Sopenharmony_ci * @nr - the number of items to drop.
758c2ecf20Sopenharmony_ci *
768c2ecf20Sopenharmony_ci * This drops the delayed ref head's count from the delayed refs rsv and frees
778c2ecf20Sopenharmony_ci * any excess reservation we had.
788c2ecf20Sopenharmony_ci */
798c2ecf20Sopenharmony_civoid btrfs_delayed_refs_rsv_release(struct btrfs_fs_info *fs_info, int nr)
808c2ecf20Sopenharmony_ci{
818c2ecf20Sopenharmony_ci	struct btrfs_block_rsv *block_rsv = &fs_info->delayed_refs_rsv;
828c2ecf20Sopenharmony_ci	u64 num_bytes = btrfs_calc_insert_metadata_size(fs_info, nr);
838c2ecf20Sopenharmony_ci	u64 released = 0;
848c2ecf20Sopenharmony_ci
858c2ecf20Sopenharmony_ci	released = btrfs_block_rsv_release(fs_info, block_rsv, num_bytes, NULL);
868c2ecf20Sopenharmony_ci	if (released)
878c2ecf20Sopenharmony_ci		trace_btrfs_space_reservation(fs_info, "delayed_refs_rsv",
888c2ecf20Sopenharmony_ci					      0, released, 0);
898c2ecf20Sopenharmony_ci}
908c2ecf20Sopenharmony_ci
918c2ecf20Sopenharmony_ci/*
928c2ecf20Sopenharmony_ci * btrfs_update_delayed_refs_rsv - adjust the size of the delayed refs rsv
938c2ecf20Sopenharmony_ci * @trans - the trans that may have generated delayed refs
948c2ecf20Sopenharmony_ci *
958c2ecf20Sopenharmony_ci * This is to be called anytime we may have adjusted trans->delayed_ref_updates,
968c2ecf20Sopenharmony_ci * it'll calculate the additional size and add it to the delayed_refs_rsv.
978c2ecf20Sopenharmony_ci */
988c2ecf20Sopenharmony_civoid btrfs_update_delayed_refs_rsv(struct btrfs_trans_handle *trans)
998c2ecf20Sopenharmony_ci{
1008c2ecf20Sopenharmony_ci	struct btrfs_fs_info *fs_info = trans->fs_info;
1018c2ecf20Sopenharmony_ci	struct btrfs_block_rsv *delayed_rsv = &fs_info->delayed_refs_rsv;
1028c2ecf20Sopenharmony_ci	u64 num_bytes;
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci	if (!trans->delayed_ref_updates)
1058c2ecf20Sopenharmony_ci		return;
1068c2ecf20Sopenharmony_ci
1078c2ecf20Sopenharmony_ci	num_bytes = btrfs_calc_insert_metadata_size(fs_info,
1088c2ecf20Sopenharmony_ci						    trans->delayed_ref_updates);
1098c2ecf20Sopenharmony_ci	spin_lock(&delayed_rsv->lock);
1108c2ecf20Sopenharmony_ci	delayed_rsv->size += num_bytes;
1118c2ecf20Sopenharmony_ci	delayed_rsv->full = 0;
1128c2ecf20Sopenharmony_ci	spin_unlock(&delayed_rsv->lock);
1138c2ecf20Sopenharmony_ci	trans->delayed_ref_updates = 0;
1148c2ecf20Sopenharmony_ci}
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci/**
1178c2ecf20Sopenharmony_ci * btrfs_migrate_to_delayed_refs_rsv - transfer bytes to our delayed refs rsv.
1188c2ecf20Sopenharmony_ci * @fs_info - the fs info for our fs.
1198c2ecf20Sopenharmony_ci * @src - the source block rsv to transfer from.
1208c2ecf20Sopenharmony_ci * @num_bytes - the number of bytes to transfer.
1218c2ecf20Sopenharmony_ci *
1228c2ecf20Sopenharmony_ci * This transfers up to the num_bytes amount from the src rsv to the
1238c2ecf20Sopenharmony_ci * delayed_refs_rsv.  Any extra bytes are returned to the space info.
1248c2ecf20Sopenharmony_ci */
1258c2ecf20Sopenharmony_civoid btrfs_migrate_to_delayed_refs_rsv(struct btrfs_fs_info *fs_info,
1268c2ecf20Sopenharmony_ci				       struct btrfs_block_rsv *src,
1278c2ecf20Sopenharmony_ci				       u64 num_bytes)
1288c2ecf20Sopenharmony_ci{
1298c2ecf20Sopenharmony_ci	struct btrfs_block_rsv *delayed_refs_rsv = &fs_info->delayed_refs_rsv;
1308c2ecf20Sopenharmony_ci	u64 to_free = 0;
1318c2ecf20Sopenharmony_ci
1328c2ecf20Sopenharmony_ci	spin_lock(&src->lock);
1338c2ecf20Sopenharmony_ci	src->reserved -= num_bytes;
1348c2ecf20Sopenharmony_ci	src->size -= num_bytes;
1358c2ecf20Sopenharmony_ci	spin_unlock(&src->lock);
1368c2ecf20Sopenharmony_ci
1378c2ecf20Sopenharmony_ci	spin_lock(&delayed_refs_rsv->lock);
1388c2ecf20Sopenharmony_ci	if (delayed_refs_rsv->size > delayed_refs_rsv->reserved) {
1398c2ecf20Sopenharmony_ci		u64 delta = delayed_refs_rsv->size -
1408c2ecf20Sopenharmony_ci			delayed_refs_rsv->reserved;
1418c2ecf20Sopenharmony_ci		if (num_bytes > delta) {
1428c2ecf20Sopenharmony_ci			to_free = num_bytes - delta;
1438c2ecf20Sopenharmony_ci			num_bytes = delta;
1448c2ecf20Sopenharmony_ci		}
1458c2ecf20Sopenharmony_ci	} else {
1468c2ecf20Sopenharmony_ci		to_free = num_bytes;
1478c2ecf20Sopenharmony_ci		num_bytes = 0;
1488c2ecf20Sopenharmony_ci	}
1498c2ecf20Sopenharmony_ci
1508c2ecf20Sopenharmony_ci	if (num_bytes)
1518c2ecf20Sopenharmony_ci		delayed_refs_rsv->reserved += num_bytes;
1528c2ecf20Sopenharmony_ci	if (delayed_refs_rsv->reserved >= delayed_refs_rsv->size)
1538c2ecf20Sopenharmony_ci		delayed_refs_rsv->full = 1;
1548c2ecf20Sopenharmony_ci	spin_unlock(&delayed_refs_rsv->lock);
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci	if (num_bytes)
1578c2ecf20Sopenharmony_ci		trace_btrfs_space_reservation(fs_info, "delayed_refs_rsv",
1588c2ecf20Sopenharmony_ci					      0, num_bytes, 1);
1598c2ecf20Sopenharmony_ci	if (to_free)
1608c2ecf20Sopenharmony_ci		btrfs_space_info_free_bytes_may_use(fs_info,
1618c2ecf20Sopenharmony_ci				delayed_refs_rsv->space_info, to_free);
1628c2ecf20Sopenharmony_ci}
1638c2ecf20Sopenharmony_ci
1648c2ecf20Sopenharmony_ci/**
1658c2ecf20Sopenharmony_ci * btrfs_delayed_refs_rsv_refill - refill based on our delayed refs usage.
1668c2ecf20Sopenharmony_ci * @fs_info - the fs_info for our fs.
1678c2ecf20Sopenharmony_ci * @flush - control how we can flush for this reservation.
1688c2ecf20Sopenharmony_ci *
1698c2ecf20Sopenharmony_ci * This will refill the delayed block_rsv up to 1 items size worth of space and
1708c2ecf20Sopenharmony_ci * will return -ENOSPC if we can't make the reservation.
1718c2ecf20Sopenharmony_ci */
1728c2ecf20Sopenharmony_ciint btrfs_delayed_refs_rsv_refill(struct btrfs_fs_info *fs_info,
1738c2ecf20Sopenharmony_ci				  enum btrfs_reserve_flush_enum flush)
1748c2ecf20Sopenharmony_ci{
1758c2ecf20Sopenharmony_ci	struct btrfs_block_rsv *block_rsv = &fs_info->delayed_refs_rsv;
1768c2ecf20Sopenharmony_ci	u64 limit = btrfs_calc_insert_metadata_size(fs_info, 1);
1778c2ecf20Sopenharmony_ci	u64 num_bytes = 0;
1788c2ecf20Sopenharmony_ci	int ret = -ENOSPC;
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	spin_lock(&block_rsv->lock);
1818c2ecf20Sopenharmony_ci	if (block_rsv->reserved < block_rsv->size) {
1828c2ecf20Sopenharmony_ci		num_bytes = block_rsv->size - block_rsv->reserved;
1838c2ecf20Sopenharmony_ci		num_bytes = min(num_bytes, limit);
1848c2ecf20Sopenharmony_ci	}
1858c2ecf20Sopenharmony_ci	spin_unlock(&block_rsv->lock);
1868c2ecf20Sopenharmony_ci
1878c2ecf20Sopenharmony_ci	if (!num_bytes)
1888c2ecf20Sopenharmony_ci		return 0;
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_ci	ret = btrfs_reserve_metadata_bytes(fs_info->extent_root, block_rsv,
1918c2ecf20Sopenharmony_ci					   num_bytes, flush);
1928c2ecf20Sopenharmony_ci	if (ret)
1938c2ecf20Sopenharmony_ci		return ret;
1948c2ecf20Sopenharmony_ci	btrfs_block_rsv_add_bytes(block_rsv, num_bytes, 0);
1958c2ecf20Sopenharmony_ci	trace_btrfs_space_reservation(fs_info, "delayed_refs_rsv",
1968c2ecf20Sopenharmony_ci				      0, num_bytes, 1);
1978c2ecf20Sopenharmony_ci	return 0;
1988c2ecf20Sopenharmony_ci}
1998c2ecf20Sopenharmony_ci
2008c2ecf20Sopenharmony_ci/*
2018c2ecf20Sopenharmony_ci * compare two delayed tree backrefs with same bytenr and type
2028c2ecf20Sopenharmony_ci */
2038c2ecf20Sopenharmony_cistatic int comp_tree_refs(struct btrfs_delayed_tree_ref *ref1,
2048c2ecf20Sopenharmony_ci			  struct btrfs_delayed_tree_ref *ref2)
2058c2ecf20Sopenharmony_ci{
2068c2ecf20Sopenharmony_ci	if (ref1->node.type == BTRFS_TREE_BLOCK_REF_KEY) {
2078c2ecf20Sopenharmony_ci		if (ref1->root < ref2->root)
2088c2ecf20Sopenharmony_ci			return -1;
2098c2ecf20Sopenharmony_ci		if (ref1->root > ref2->root)
2108c2ecf20Sopenharmony_ci			return 1;
2118c2ecf20Sopenharmony_ci	} else {
2128c2ecf20Sopenharmony_ci		if (ref1->parent < ref2->parent)
2138c2ecf20Sopenharmony_ci			return -1;
2148c2ecf20Sopenharmony_ci		if (ref1->parent > ref2->parent)
2158c2ecf20Sopenharmony_ci			return 1;
2168c2ecf20Sopenharmony_ci	}
2178c2ecf20Sopenharmony_ci	return 0;
2188c2ecf20Sopenharmony_ci}
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_ci/*
2218c2ecf20Sopenharmony_ci * compare two delayed data backrefs with same bytenr and type
2228c2ecf20Sopenharmony_ci */
2238c2ecf20Sopenharmony_cistatic int comp_data_refs(struct btrfs_delayed_data_ref *ref1,
2248c2ecf20Sopenharmony_ci			  struct btrfs_delayed_data_ref *ref2)
2258c2ecf20Sopenharmony_ci{
2268c2ecf20Sopenharmony_ci	if (ref1->node.type == BTRFS_EXTENT_DATA_REF_KEY) {
2278c2ecf20Sopenharmony_ci		if (ref1->root < ref2->root)
2288c2ecf20Sopenharmony_ci			return -1;
2298c2ecf20Sopenharmony_ci		if (ref1->root > ref2->root)
2308c2ecf20Sopenharmony_ci			return 1;
2318c2ecf20Sopenharmony_ci		if (ref1->objectid < ref2->objectid)
2328c2ecf20Sopenharmony_ci			return -1;
2338c2ecf20Sopenharmony_ci		if (ref1->objectid > ref2->objectid)
2348c2ecf20Sopenharmony_ci			return 1;
2358c2ecf20Sopenharmony_ci		if (ref1->offset < ref2->offset)
2368c2ecf20Sopenharmony_ci			return -1;
2378c2ecf20Sopenharmony_ci		if (ref1->offset > ref2->offset)
2388c2ecf20Sopenharmony_ci			return 1;
2398c2ecf20Sopenharmony_ci	} else {
2408c2ecf20Sopenharmony_ci		if (ref1->parent < ref2->parent)
2418c2ecf20Sopenharmony_ci			return -1;
2428c2ecf20Sopenharmony_ci		if (ref1->parent > ref2->parent)
2438c2ecf20Sopenharmony_ci			return 1;
2448c2ecf20Sopenharmony_ci	}
2458c2ecf20Sopenharmony_ci	return 0;
2468c2ecf20Sopenharmony_ci}
2478c2ecf20Sopenharmony_ci
2488c2ecf20Sopenharmony_cistatic int comp_refs(struct btrfs_delayed_ref_node *ref1,
2498c2ecf20Sopenharmony_ci		     struct btrfs_delayed_ref_node *ref2,
2508c2ecf20Sopenharmony_ci		     bool check_seq)
2518c2ecf20Sopenharmony_ci{
2528c2ecf20Sopenharmony_ci	int ret = 0;
2538c2ecf20Sopenharmony_ci
2548c2ecf20Sopenharmony_ci	if (ref1->type < ref2->type)
2558c2ecf20Sopenharmony_ci		return -1;
2568c2ecf20Sopenharmony_ci	if (ref1->type > ref2->type)
2578c2ecf20Sopenharmony_ci		return 1;
2588c2ecf20Sopenharmony_ci	if (ref1->type == BTRFS_TREE_BLOCK_REF_KEY ||
2598c2ecf20Sopenharmony_ci	    ref1->type == BTRFS_SHARED_BLOCK_REF_KEY)
2608c2ecf20Sopenharmony_ci		ret = comp_tree_refs(btrfs_delayed_node_to_tree_ref(ref1),
2618c2ecf20Sopenharmony_ci				     btrfs_delayed_node_to_tree_ref(ref2));
2628c2ecf20Sopenharmony_ci	else
2638c2ecf20Sopenharmony_ci		ret = comp_data_refs(btrfs_delayed_node_to_data_ref(ref1),
2648c2ecf20Sopenharmony_ci				     btrfs_delayed_node_to_data_ref(ref2));
2658c2ecf20Sopenharmony_ci	if (ret)
2668c2ecf20Sopenharmony_ci		return ret;
2678c2ecf20Sopenharmony_ci	if (check_seq) {
2688c2ecf20Sopenharmony_ci		if (ref1->seq < ref2->seq)
2698c2ecf20Sopenharmony_ci			return -1;
2708c2ecf20Sopenharmony_ci		if (ref1->seq > ref2->seq)
2718c2ecf20Sopenharmony_ci			return 1;
2728c2ecf20Sopenharmony_ci	}
2738c2ecf20Sopenharmony_ci	return 0;
2748c2ecf20Sopenharmony_ci}
2758c2ecf20Sopenharmony_ci
2768c2ecf20Sopenharmony_ci/* insert a new ref to head ref rbtree */
2778c2ecf20Sopenharmony_cistatic struct btrfs_delayed_ref_head *htree_insert(struct rb_root_cached *root,
2788c2ecf20Sopenharmony_ci						   struct rb_node *node)
2798c2ecf20Sopenharmony_ci{
2808c2ecf20Sopenharmony_ci	struct rb_node **p = &root->rb_root.rb_node;
2818c2ecf20Sopenharmony_ci	struct rb_node *parent_node = NULL;
2828c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_head *entry;
2838c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_head *ins;
2848c2ecf20Sopenharmony_ci	u64 bytenr;
2858c2ecf20Sopenharmony_ci	bool leftmost = true;
2868c2ecf20Sopenharmony_ci
2878c2ecf20Sopenharmony_ci	ins = rb_entry(node, struct btrfs_delayed_ref_head, href_node);
2888c2ecf20Sopenharmony_ci	bytenr = ins->bytenr;
2898c2ecf20Sopenharmony_ci	while (*p) {
2908c2ecf20Sopenharmony_ci		parent_node = *p;
2918c2ecf20Sopenharmony_ci		entry = rb_entry(parent_node, struct btrfs_delayed_ref_head,
2928c2ecf20Sopenharmony_ci				 href_node);
2938c2ecf20Sopenharmony_ci
2948c2ecf20Sopenharmony_ci		if (bytenr < entry->bytenr) {
2958c2ecf20Sopenharmony_ci			p = &(*p)->rb_left;
2968c2ecf20Sopenharmony_ci		} else if (bytenr > entry->bytenr) {
2978c2ecf20Sopenharmony_ci			p = &(*p)->rb_right;
2988c2ecf20Sopenharmony_ci			leftmost = false;
2998c2ecf20Sopenharmony_ci		} else {
3008c2ecf20Sopenharmony_ci			return entry;
3018c2ecf20Sopenharmony_ci		}
3028c2ecf20Sopenharmony_ci	}
3038c2ecf20Sopenharmony_ci
3048c2ecf20Sopenharmony_ci	rb_link_node(node, parent_node, p);
3058c2ecf20Sopenharmony_ci	rb_insert_color_cached(node, root, leftmost);
3068c2ecf20Sopenharmony_ci	return NULL;
3078c2ecf20Sopenharmony_ci}
3088c2ecf20Sopenharmony_ci
3098c2ecf20Sopenharmony_cistatic struct btrfs_delayed_ref_node* tree_insert(struct rb_root_cached *root,
3108c2ecf20Sopenharmony_ci		struct btrfs_delayed_ref_node *ins)
3118c2ecf20Sopenharmony_ci{
3128c2ecf20Sopenharmony_ci	struct rb_node **p = &root->rb_root.rb_node;
3138c2ecf20Sopenharmony_ci	struct rb_node *node = &ins->ref_node;
3148c2ecf20Sopenharmony_ci	struct rb_node *parent_node = NULL;
3158c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_node *entry;
3168c2ecf20Sopenharmony_ci	bool leftmost = true;
3178c2ecf20Sopenharmony_ci
3188c2ecf20Sopenharmony_ci	while (*p) {
3198c2ecf20Sopenharmony_ci		int comp;
3208c2ecf20Sopenharmony_ci
3218c2ecf20Sopenharmony_ci		parent_node = *p;
3228c2ecf20Sopenharmony_ci		entry = rb_entry(parent_node, struct btrfs_delayed_ref_node,
3238c2ecf20Sopenharmony_ci				 ref_node);
3248c2ecf20Sopenharmony_ci		comp = comp_refs(ins, entry, true);
3258c2ecf20Sopenharmony_ci		if (comp < 0) {
3268c2ecf20Sopenharmony_ci			p = &(*p)->rb_left;
3278c2ecf20Sopenharmony_ci		} else if (comp > 0) {
3288c2ecf20Sopenharmony_ci			p = &(*p)->rb_right;
3298c2ecf20Sopenharmony_ci			leftmost = false;
3308c2ecf20Sopenharmony_ci		} else {
3318c2ecf20Sopenharmony_ci			return entry;
3328c2ecf20Sopenharmony_ci		}
3338c2ecf20Sopenharmony_ci	}
3348c2ecf20Sopenharmony_ci
3358c2ecf20Sopenharmony_ci	rb_link_node(node, parent_node, p);
3368c2ecf20Sopenharmony_ci	rb_insert_color_cached(node, root, leftmost);
3378c2ecf20Sopenharmony_ci	return NULL;
3388c2ecf20Sopenharmony_ci}
3398c2ecf20Sopenharmony_ci
3408c2ecf20Sopenharmony_cistatic struct btrfs_delayed_ref_head *find_first_ref_head(
3418c2ecf20Sopenharmony_ci		struct btrfs_delayed_ref_root *dr)
3428c2ecf20Sopenharmony_ci{
3438c2ecf20Sopenharmony_ci	struct rb_node *n;
3448c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_head *entry;
3458c2ecf20Sopenharmony_ci
3468c2ecf20Sopenharmony_ci	n = rb_first_cached(&dr->href_root);
3478c2ecf20Sopenharmony_ci	if (!n)
3488c2ecf20Sopenharmony_ci		return NULL;
3498c2ecf20Sopenharmony_ci
3508c2ecf20Sopenharmony_ci	entry = rb_entry(n, struct btrfs_delayed_ref_head, href_node);
3518c2ecf20Sopenharmony_ci
3528c2ecf20Sopenharmony_ci	return entry;
3538c2ecf20Sopenharmony_ci}
3548c2ecf20Sopenharmony_ci
3558c2ecf20Sopenharmony_ci/*
3568c2ecf20Sopenharmony_ci * Find a head entry based on bytenr. This returns the delayed ref head if it
3578c2ecf20Sopenharmony_ci * was able to find one, or NULL if nothing was in that spot.  If return_bigger
3588c2ecf20Sopenharmony_ci * is given, the next bigger entry is returned if no exact match is found.
3598c2ecf20Sopenharmony_ci */
3608c2ecf20Sopenharmony_cistatic struct btrfs_delayed_ref_head *find_ref_head(
3618c2ecf20Sopenharmony_ci		struct btrfs_delayed_ref_root *dr, u64 bytenr,
3628c2ecf20Sopenharmony_ci		bool return_bigger)
3638c2ecf20Sopenharmony_ci{
3648c2ecf20Sopenharmony_ci	struct rb_root *root = &dr->href_root.rb_root;
3658c2ecf20Sopenharmony_ci	struct rb_node *n;
3668c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_head *entry;
3678c2ecf20Sopenharmony_ci
3688c2ecf20Sopenharmony_ci	n = root->rb_node;
3698c2ecf20Sopenharmony_ci	entry = NULL;
3708c2ecf20Sopenharmony_ci	while (n) {
3718c2ecf20Sopenharmony_ci		entry = rb_entry(n, struct btrfs_delayed_ref_head, href_node);
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci		if (bytenr < entry->bytenr)
3748c2ecf20Sopenharmony_ci			n = n->rb_left;
3758c2ecf20Sopenharmony_ci		else if (bytenr > entry->bytenr)
3768c2ecf20Sopenharmony_ci			n = n->rb_right;
3778c2ecf20Sopenharmony_ci		else
3788c2ecf20Sopenharmony_ci			return entry;
3798c2ecf20Sopenharmony_ci	}
3808c2ecf20Sopenharmony_ci	if (entry && return_bigger) {
3818c2ecf20Sopenharmony_ci		if (bytenr > entry->bytenr) {
3828c2ecf20Sopenharmony_ci			n = rb_next(&entry->href_node);
3838c2ecf20Sopenharmony_ci			if (!n)
3848c2ecf20Sopenharmony_ci				return NULL;
3858c2ecf20Sopenharmony_ci			entry = rb_entry(n, struct btrfs_delayed_ref_head,
3868c2ecf20Sopenharmony_ci					 href_node);
3878c2ecf20Sopenharmony_ci		}
3888c2ecf20Sopenharmony_ci		return entry;
3898c2ecf20Sopenharmony_ci	}
3908c2ecf20Sopenharmony_ci	return NULL;
3918c2ecf20Sopenharmony_ci}
3928c2ecf20Sopenharmony_ci
3938c2ecf20Sopenharmony_ciint btrfs_delayed_ref_lock(struct btrfs_delayed_ref_root *delayed_refs,
3948c2ecf20Sopenharmony_ci			   struct btrfs_delayed_ref_head *head)
3958c2ecf20Sopenharmony_ci{
3968c2ecf20Sopenharmony_ci	lockdep_assert_held(&delayed_refs->lock);
3978c2ecf20Sopenharmony_ci	if (mutex_trylock(&head->mutex))
3988c2ecf20Sopenharmony_ci		return 0;
3998c2ecf20Sopenharmony_ci
4008c2ecf20Sopenharmony_ci	refcount_inc(&head->refs);
4018c2ecf20Sopenharmony_ci	spin_unlock(&delayed_refs->lock);
4028c2ecf20Sopenharmony_ci
4038c2ecf20Sopenharmony_ci	mutex_lock(&head->mutex);
4048c2ecf20Sopenharmony_ci	spin_lock(&delayed_refs->lock);
4058c2ecf20Sopenharmony_ci	if (RB_EMPTY_NODE(&head->href_node)) {
4068c2ecf20Sopenharmony_ci		mutex_unlock(&head->mutex);
4078c2ecf20Sopenharmony_ci		btrfs_put_delayed_ref_head(head);
4088c2ecf20Sopenharmony_ci		return -EAGAIN;
4098c2ecf20Sopenharmony_ci	}
4108c2ecf20Sopenharmony_ci	btrfs_put_delayed_ref_head(head);
4118c2ecf20Sopenharmony_ci	return 0;
4128c2ecf20Sopenharmony_ci}
4138c2ecf20Sopenharmony_ci
4148c2ecf20Sopenharmony_cistatic inline void drop_delayed_ref(struct btrfs_trans_handle *trans,
4158c2ecf20Sopenharmony_ci				    struct btrfs_delayed_ref_root *delayed_refs,
4168c2ecf20Sopenharmony_ci				    struct btrfs_delayed_ref_head *head,
4178c2ecf20Sopenharmony_ci				    struct btrfs_delayed_ref_node *ref)
4188c2ecf20Sopenharmony_ci{
4198c2ecf20Sopenharmony_ci	lockdep_assert_held(&head->lock);
4208c2ecf20Sopenharmony_ci	rb_erase_cached(&ref->ref_node, &head->ref_tree);
4218c2ecf20Sopenharmony_ci	RB_CLEAR_NODE(&ref->ref_node);
4228c2ecf20Sopenharmony_ci	if (!list_empty(&ref->add_list))
4238c2ecf20Sopenharmony_ci		list_del(&ref->add_list);
4248c2ecf20Sopenharmony_ci	ref->in_tree = 0;
4258c2ecf20Sopenharmony_ci	btrfs_put_delayed_ref(ref);
4268c2ecf20Sopenharmony_ci	atomic_dec(&delayed_refs->num_entries);
4278c2ecf20Sopenharmony_ci}
4288c2ecf20Sopenharmony_ci
4298c2ecf20Sopenharmony_cistatic bool merge_ref(struct btrfs_trans_handle *trans,
4308c2ecf20Sopenharmony_ci		      struct btrfs_delayed_ref_root *delayed_refs,
4318c2ecf20Sopenharmony_ci		      struct btrfs_delayed_ref_head *head,
4328c2ecf20Sopenharmony_ci		      struct btrfs_delayed_ref_node *ref,
4338c2ecf20Sopenharmony_ci		      u64 seq)
4348c2ecf20Sopenharmony_ci{
4358c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_node *next;
4368c2ecf20Sopenharmony_ci	struct rb_node *node = rb_next(&ref->ref_node);
4378c2ecf20Sopenharmony_ci	bool done = false;
4388c2ecf20Sopenharmony_ci
4398c2ecf20Sopenharmony_ci	while (!done && node) {
4408c2ecf20Sopenharmony_ci		int mod;
4418c2ecf20Sopenharmony_ci
4428c2ecf20Sopenharmony_ci		next = rb_entry(node, struct btrfs_delayed_ref_node, ref_node);
4438c2ecf20Sopenharmony_ci		node = rb_next(node);
4448c2ecf20Sopenharmony_ci		if (seq && next->seq >= seq)
4458c2ecf20Sopenharmony_ci			break;
4468c2ecf20Sopenharmony_ci		if (comp_refs(ref, next, false))
4478c2ecf20Sopenharmony_ci			break;
4488c2ecf20Sopenharmony_ci
4498c2ecf20Sopenharmony_ci		if (ref->action == next->action) {
4508c2ecf20Sopenharmony_ci			mod = next->ref_mod;
4518c2ecf20Sopenharmony_ci		} else {
4528c2ecf20Sopenharmony_ci			if (ref->ref_mod < next->ref_mod) {
4538c2ecf20Sopenharmony_ci				swap(ref, next);
4548c2ecf20Sopenharmony_ci				done = true;
4558c2ecf20Sopenharmony_ci			}
4568c2ecf20Sopenharmony_ci			mod = -next->ref_mod;
4578c2ecf20Sopenharmony_ci		}
4588c2ecf20Sopenharmony_ci
4598c2ecf20Sopenharmony_ci		drop_delayed_ref(trans, delayed_refs, head, next);
4608c2ecf20Sopenharmony_ci		ref->ref_mod += mod;
4618c2ecf20Sopenharmony_ci		if (ref->ref_mod == 0) {
4628c2ecf20Sopenharmony_ci			drop_delayed_ref(trans, delayed_refs, head, ref);
4638c2ecf20Sopenharmony_ci			done = true;
4648c2ecf20Sopenharmony_ci		} else {
4658c2ecf20Sopenharmony_ci			/*
4668c2ecf20Sopenharmony_ci			 * Can't have multiples of the same ref on a tree block.
4678c2ecf20Sopenharmony_ci			 */
4688c2ecf20Sopenharmony_ci			WARN_ON(ref->type == BTRFS_TREE_BLOCK_REF_KEY ||
4698c2ecf20Sopenharmony_ci				ref->type == BTRFS_SHARED_BLOCK_REF_KEY);
4708c2ecf20Sopenharmony_ci		}
4718c2ecf20Sopenharmony_ci	}
4728c2ecf20Sopenharmony_ci
4738c2ecf20Sopenharmony_ci	return done;
4748c2ecf20Sopenharmony_ci}
4758c2ecf20Sopenharmony_ci
4768c2ecf20Sopenharmony_civoid btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans,
4778c2ecf20Sopenharmony_ci			      struct btrfs_delayed_ref_root *delayed_refs,
4788c2ecf20Sopenharmony_ci			      struct btrfs_delayed_ref_head *head)
4798c2ecf20Sopenharmony_ci{
4808c2ecf20Sopenharmony_ci	struct btrfs_fs_info *fs_info = trans->fs_info;
4818c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_node *ref;
4828c2ecf20Sopenharmony_ci	struct rb_node *node;
4838c2ecf20Sopenharmony_ci	u64 seq = 0;
4848c2ecf20Sopenharmony_ci
4858c2ecf20Sopenharmony_ci	lockdep_assert_held(&head->lock);
4868c2ecf20Sopenharmony_ci
4878c2ecf20Sopenharmony_ci	if (RB_EMPTY_ROOT(&head->ref_tree.rb_root))
4888c2ecf20Sopenharmony_ci		return;
4898c2ecf20Sopenharmony_ci
4908c2ecf20Sopenharmony_ci	/* We don't have too many refs to merge for data. */
4918c2ecf20Sopenharmony_ci	if (head->is_data)
4928c2ecf20Sopenharmony_ci		return;
4938c2ecf20Sopenharmony_ci
4948c2ecf20Sopenharmony_ci	read_lock(&fs_info->tree_mod_log_lock);
4958c2ecf20Sopenharmony_ci	if (!list_empty(&fs_info->tree_mod_seq_list)) {
4968c2ecf20Sopenharmony_ci		struct seq_list *elem;
4978c2ecf20Sopenharmony_ci
4988c2ecf20Sopenharmony_ci		elem = list_first_entry(&fs_info->tree_mod_seq_list,
4998c2ecf20Sopenharmony_ci					struct seq_list, list);
5008c2ecf20Sopenharmony_ci		seq = elem->seq;
5018c2ecf20Sopenharmony_ci	}
5028c2ecf20Sopenharmony_ci	read_unlock(&fs_info->tree_mod_log_lock);
5038c2ecf20Sopenharmony_ci
5048c2ecf20Sopenharmony_ciagain:
5058c2ecf20Sopenharmony_ci	for (node = rb_first_cached(&head->ref_tree); node;
5068c2ecf20Sopenharmony_ci	     node = rb_next(node)) {
5078c2ecf20Sopenharmony_ci		ref = rb_entry(node, struct btrfs_delayed_ref_node, ref_node);
5088c2ecf20Sopenharmony_ci		if (seq && ref->seq >= seq)
5098c2ecf20Sopenharmony_ci			continue;
5108c2ecf20Sopenharmony_ci		if (merge_ref(trans, delayed_refs, head, ref, seq))
5118c2ecf20Sopenharmony_ci			goto again;
5128c2ecf20Sopenharmony_ci	}
5138c2ecf20Sopenharmony_ci}
5148c2ecf20Sopenharmony_ci
5158c2ecf20Sopenharmony_ciint btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info, u64 seq)
5168c2ecf20Sopenharmony_ci{
5178c2ecf20Sopenharmony_ci	struct seq_list *elem;
5188c2ecf20Sopenharmony_ci	int ret = 0;
5198c2ecf20Sopenharmony_ci
5208c2ecf20Sopenharmony_ci	read_lock(&fs_info->tree_mod_log_lock);
5218c2ecf20Sopenharmony_ci	if (!list_empty(&fs_info->tree_mod_seq_list)) {
5228c2ecf20Sopenharmony_ci		elem = list_first_entry(&fs_info->tree_mod_seq_list,
5238c2ecf20Sopenharmony_ci					struct seq_list, list);
5248c2ecf20Sopenharmony_ci		if (seq >= elem->seq) {
5258c2ecf20Sopenharmony_ci			btrfs_debug(fs_info,
5268c2ecf20Sopenharmony_ci				"holding back delayed_ref %#x.%x, lowest is %#x.%x",
5278c2ecf20Sopenharmony_ci				(u32)(seq >> 32), (u32)seq,
5288c2ecf20Sopenharmony_ci				(u32)(elem->seq >> 32), (u32)elem->seq);
5298c2ecf20Sopenharmony_ci			ret = 1;
5308c2ecf20Sopenharmony_ci		}
5318c2ecf20Sopenharmony_ci	}
5328c2ecf20Sopenharmony_ci
5338c2ecf20Sopenharmony_ci	read_unlock(&fs_info->tree_mod_log_lock);
5348c2ecf20Sopenharmony_ci	return ret;
5358c2ecf20Sopenharmony_ci}
5368c2ecf20Sopenharmony_ci
5378c2ecf20Sopenharmony_cistruct btrfs_delayed_ref_head *btrfs_select_ref_head(
5388c2ecf20Sopenharmony_ci		struct btrfs_delayed_ref_root *delayed_refs)
5398c2ecf20Sopenharmony_ci{
5408c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_head *head;
5418c2ecf20Sopenharmony_ci
5428c2ecf20Sopenharmony_ciagain:
5438c2ecf20Sopenharmony_ci	head = find_ref_head(delayed_refs, delayed_refs->run_delayed_start,
5448c2ecf20Sopenharmony_ci			     true);
5458c2ecf20Sopenharmony_ci	if (!head && delayed_refs->run_delayed_start != 0) {
5468c2ecf20Sopenharmony_ci		delayed_refs->run_delayed_start = 0;
5478c2ecf20Sopenharmony_ci		head = find_first_ref_head(delayed_refs);
5488c2ecf20Sopenharmony_ci	}
5498c2ecf20Sopenharmony_ci	if (!head)
5508c2ecf20Sopenharmony_ci		return NULL;
5518c2ecf20Sopenharmony_ci
5528c2ecf20Sopenharmony_ci	while (head->processing) {
5538c2ecf20Sopenharmony_ci		struct rb_node *node;
5548c2ecf20Sopenharmony_ci
5558c2ecf20Sopenharmony_ci		node = rb_next(&head->href_node);
5568c2ecf20Sopenharmony_ci		if (!node) {
5578c2ecf20Sopenharmony_ci			if (delayed_refs->run_delayed_start == 0)
5588c2ecf20Sopenharmony_ci				return NULL;
5598c2ecf20Sopenharmony_ci			delayed_refs->run_delayed_start = 0;
5608c2ecf20Sopenharmony_ci			goto again;
5618c2ecf20Sopenharmony_ci		}
5628c2ecf20Sopenharmony_ci		head = rb_entry(node, struct btrfs_delayed_ref_head,
5638c2ecf20Sopenharmony_ci				href_node);
5648c2ecf20Sopenharmony_ci	}
5658c2ecf20Sopenharmony_ci
5668c2ecf20Sopenharmony_ci	head->processing = 1;
5678c2ecf20Sopenharmony_ci	WARN_ON(delayed_refs->num_heads_ready == 0);
5688c2ecf20Sopenharmony_ci	delayed_refs->num_heads_ready--;
5698c2ecf20Sopenharmony_ci	delayed_refs->run_delayed_start = head->bytenr +
5708c2ecf20Sopenharmony_ci		head->num_bytes;
5718c2ecf20Sopenharmony_ci	return head;
5728c2ecf20Sopenharmony_ci}
5738c2ecf20Sopenharmony_ci
5748c2ecf20Sopenharmony_civoid btrfs_delete_ref_head(struct btrfs_delayed_ref_root *delayed_refs,
5758c2ecf20Sopenharmony_ci			   struct btrfs_delayed_ref_head *head)
5768c2ecf20Sopenharmony_ci{
5778c2ecf20Sopenharmony_ci	lockdep_assert_held(&delayed_refs->lock);
5788c2ecf20Sopenharmony_ci	lockdep_assert_held(&head->lock);
5798c2ecf20Sopenharmony_ci
5808c2ecf20Sopenharmony_ci	rb_erase_cached(&head->href_node, &delayed_refs->href_root);
5818c2ecf20Sopenharmony_ci	RB_CLEAR_NODE(&head->href_node);
5828c2ecf20Sopenharmony_ci	atomic_dec(&delayed_refs->num_entries);
5838c2ecf20Sopenharmony_ci	delayed_refs->num_heads--;
5848c2ecf20Sopenharmony_ci	if (head->processing == 0)
5858c2ecf20Sopenharmony_ci		delayed_refs->num_heads_ready--;
5868c2ecf20Sopenharmony_ci}
5878c2ecf20Sopenharmony_ci
5888c2ecf20Sopenharmony_ci/*
5898c2ecf20Sopenharmony_ci * Helper to insert the ref_node to the tail or merge with tail.
5908c2ecf20Sopenharmony_ci *
5918c2ecf20Sopenharmony_ci * Return 0 for insert.
5928c2ecf20Sopenharmony_ci * Return >0 for merge.
5938c2ecf20Sopenharmony_ci */
5948c2ecf20Sopenharmony_cistatic int insert_delayed_ref(struct btrfs_trans_handle *trans,
5958c2ecf20Sopenharmony_ci			      struct btrfs_delayed_ref_root *root,
5968c2ecf20Sopenharmony_ci			      struct btrfs_delayed_ref_head *href,
5978c2ecf20Sopenharmony_ci			      struct btrfs_delayed_ref_node *ref)
5988c2ecf20Sopenharmony_ci{
5998c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_node *exist;
6008c2ecf20Sopenharmony_ci	int mod;
6018c2ecf20Sopenharmony_ci	int ret = 0;
6028c2ecf20Sopenharmony_ci
6038c2ecf20Sopenharmony_ci	spin_lock(&href->lock);
6048c2ecf20Sopenharmony_ci	exist = tree_insert(&href->ref_tree, ref);
6058c2ecf20Sopenharmony_ci	if (!exist)
6068c2ecf20Sopenharmony_ci		goto inserted;
6078c2ecf20Sopenharmony_ci
6088c2ecf20Sopenharmony_ci	/* Now we are sure we can merge */
6098c2ecf20Sopenharmony_ci	ret = 1;
6108c2ecf20Sopenharmony_ci	if (exist->action == ref->action) {
6118c2ecf20Sopenharmony_ci		mod = ref->ref_mod;
6128c2ecf20Sopenharmony_ci	} else {
6138c2ecf20Sopenharmony_ci		/* Need to change action */
6148c2ecf20Sopenharmony_ci		if (exist->ref_mod < ref->ref_mod) {
6158c2ecf20Sopenharmony_ci			exist->action = ref->action;
6168c2ecf20Sopenharmony_ci			mod = -exist->ref_mod;
6178c2ecf20Sopenharmony_ci			exist->ref_mod = ref->ref_mod;
6188c2ecf20Sopenharmony_ci			if (ref->action == BTRFS_ADD_DELAYED_REF)
6198c2ecf20Sopenharmony_ci				list_add_tail(&exist->add_list,
6208c2ecf20Sopenharmony_ci					      &href->ref_add_list);
6218c2ecf20Sopenharmony_ci			else if (ref->action == BTRFS_DROP_DELAYED_REF) {
6228c2ecf20Sopenharmony_ci				ASSERT(!list_empty(&exist->add_list));
6238c2ecf20Sopenharmony_ci				list_del(&exist->add_list);
6248c2ecf20Sopenharmony_ci			} else {
6258c2ecf20Sopenharmony_ci				ASSERT(0);
6268c2ecf20Sopenharmony_ci			}
6278c2ecf20Sopenharmony_ci		} else
6288c2ecf20Sopenharmony_ci			mod = -ref->ref_mod;
6298c2ecf20Sopenharmony_ci	}
6308c2ecf20Sopenharmony_ci	exist->ref_mod += mod;
6318c2ecf20Sopenharmony_ci
6328c2ecf20Sopenharmony_ci	/* remove existing tail if its ref_mod is zero */
6338c2ecf20Sopenharmony_ci	if (exist->ref_mod == 0)
6348c2ecf20Sopenharmony_ci		drop_delayed_ref(trans, root, href, exist);
6358c2ecf20Sopenharmony_ci	spin_unlock(&href->lock);
6368c2ecf20Sopenharmony_ci	return ret;
6378c2ecf20Sopenharmony_ciinserted:
6388c2ecf20Sopenharmony_ci	if (ref->action == BTRFS_ADD_DELAYED_REF)
6398c2ecf20Sopenharmony_ci		list_add_tail(&ref->add_list, &href->ref_add_list);
6408c2ecf20Sopenharmony_ci	atomic_inc(&root->num_entries);
6418c2ecf20Sopenharmony_ci	spin_unlock(&href->lock);
6428c2ecf20Sopenharmony_ci	return ret;
6438c2ecf20Sopenharmony_ci}
6448c2ecf20Sopenharmony_ci
6458c2ecf20Sopenharmony_ci/*
6468c2ecf20Sopenharmony_ci * helper function to update the accounting in the head ref
6478c2ecf20Sopenharmony_ci * existing and update must have the same bytenr
6488c2ecf20Sopenharmony_ci */
6498c2ecf20Sopenharmony_cistatic noinline void update_existing_head_ref(struct btrfs_trans_handle *trans,
6508c2ecf20Sopenharmony_ci			 struct btrfs_delayed_ref_head *existing,
6518c2ecf20Sopenharmony_ci			 struct btrfs_delayed_ref_head *update)
6528c2ecf20Sopenharmony_ci{
6538c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_root *delayed_refs =
6548c2ecf20Sopenharmony_ci		&trans->transaction->delayed_refs;
6558c2ecf20Sopenharmony_ci	struct btrfs_fs_info *fs_info = trans->fs_info;
6568c2ecf20Sopenharmony_ci	u64 flags = btrfs_ref_head_to_space_flags(existing);
6578c2ecf20Sopenharmony_ci	int old_ref_mod;
6588c2ecf20Sopenharmony_ci
6598c2ecf20Sopenharmony_ci	BUG_ON(existing->is_data != update->is_data);
6608c2ecf20Sopenharmony_ci
6618c2ecf20Sopenharmony_ci	spin_lock(&existing->lock);
6628c2ecf20Sopenharmony_ci	if (update->must_insert_reserved) {
6638c2ecf20Sopenharmony_ci		/* if the extent was freed and then
6648c2ecf20Sopenharmony_ci		 * reallocated before the delayed ref
6658c2ecf20Sopenharmony_ci		 * entries were processed, we can end up
6668c2ecf20Sopenharmony_ci		 * with an existing head ref without
6678c2ecf20Sopenharmony_ci		 * the must_insert_reserved flag set.
6688c2ecf20Sopenharmony_ci		 * Set it again here
6698c2ecf20Sopenharmony_ci		 */
6708c2ecf20Sopenharmony_ci		existing->must_insert_reserved = update->must_insert_reserved;
6718c2ecf20Sopenharmony_ci
6728c2ecf20Sopenharmony_ci		/*
6738c2ecf20Sopenharmony_ci		 * update the num_bytes so we make sure the accounting
6748c2ecf20Sopenharmony_ci		 * is done correctly
6758c2ecf20Sopenharmony_ci		 */
6768c2ecf20Sopenharmony_ci		existing->num_bytes = update->num_bytes;
6778c2ecf20Sopenharmony_ci
6788c2ecf20Sopenharmony_ci	}
6798c2ecf20Sopenharmony_ci
6808c2ecf20Sopenharmony_ci	if (update->extent_op) {
6818c2ecf20Sopenharmony_ci		if (!existing->extent_op) {
6828c2ecf20Sopenharmony_ci			existing->extent_op = update->extent_op;
6838c2ecf20Sopenharmony_ci		} else {
6848c2ecf20Sopenharmony_ci			if (update->extent_op->update_key) {
6858c2ecf20Sopenharmony_ci				memcpy(&existing->extent_op->key,
6868c2ecf20Sopenharmony_ci				       &update->extent_op->key,
6878c2ecf20Sopenharmony_ci				       sizeof(update->extent_op->key));
6888c2ecf20Sopenharmony_ci				existing->extent_op->update_key = true;
6898c2ecf20Sopenharmony_ci			}
6908c2ecf20Sopenharmony_ci			if (update->extent_op->update_flags) {
6918c2ecf20Sopenharmony_ci				existing->extent_op->flags_to_set |=
6928c2ecf20Sopenharmony_ci					update->extent_op->flags_to_set;
6938c2ecf20Sopenharmony_ci				existing->extent_op->update_flags = true;
6948c2ecf20Sopenharmony_ci			}
6958c2ecf20Sopenharmony_ci			btrfs_free_delayed_extent_op(update->extent_op);
6968c2ecf20Sopenharmony_ci		}
6978c2ecf20Sopenharmony_ci	}
6988c2ecf20Sopenharmony_ci	/*
6998c2ecf20Sopenharmony_ci	 * update the reference mod on the head to reflect this new operation,
7008c2ecf20Sopenharmony_ci	 * only need the lock for this case cause we could be processing it
7018c2ecf20Sopenharmony_ci	 * currently, for refs we just added we know we're a-ok.
7028c2ecf20Sopenharmony_ci	 */
7038c2ecf20Sopenharmony_ci	old_ref_mod = existing->total_ref_mod;
7048c2ecf20Sopenharmony_ci	existing->ref_mod += update->ref_mod;
7058c2ecf20Sopenharmony_ci	existing->total_ref_mod += update->ref_mod;
7068c2ecf20Sopenharmony_ci
7078c2ecf20Sopenharmony_ci	/*
7088c2ecf20Sopenharmony_ci	 * If we are going to from a positive ref mod to a negative or vice
7098c2ecf20Sopenharmony_ci	 * versa we need to make sure to adjust pending_csums accordingly.
7108c2ecf20Sopenharmony_ci	 */
7118c2ecf20Sopenharmony_ci	if (existing->is_data) {
7128c2ecf20Sopenharmony_ci		u64 csum_leaves =
7138c2ecf20Sopenharmony_ci			btrfs_csum_bytes_to_leaves(fs_info,
7148c2ecf20Sopenharmony_ci						   existing->num_bytes);
7158c2ecf20Sopenharmony_ci
7168c2ecf20Sopenharmony_ci		if (existing->total_ref_mod >= 0 && old_ref_mod < 0) {
7178c2ecf20Sopenharmony_ci			delayed_refs->pending_csums -= existing->num_bytes;
7188c2ecf20Sopenharmony_ci			btrfs_delayed_refs_rsv_release(fs_info, csum_leaves);
7198c2ecf20Sopenharmony_ci		}
7208c2ecf20Sopenharmony_ci		if (existing->total_ref_mod < 0 && old_ref_mod >= 0) {
7218c2ecf20Sopenharmony_ci			delayed_refs->pending_csums += existing->num_bytes;
7228c2ecf20Sopenharmony_ci			trans->delayed_ref_updates += csum_leaves;
7238c2ecf20Sopenharmony_ci		}
7248c2ecf20Sopenharmony_ci	}
7258c2ecf20Sopenharmony_ci
7268c2ecf20Sopenharmony_ci	/*
7278c2ecf20Sopenharmony_ci	 * This handles the following conditions:
7288c2ecf20Sopenharmony_ci	 *
7298c2ecf20Sopenharmony_ci	 * 1. We had a ref mod of 0 or more and went negative, indicating that
7308c2ecf20Sopenharmony_ci	 *    we may be freeing space, so add our space to the
7318c2ecf20Sopenharmony_ci	 *    total_bytes_pinned counter.
7328c2ecf20Sopenharmony_ci	 * 2. We were negative and went to 0 or positive, so no longer can say
7338c2ecf20Sopenharmony_ci	 *    that the space would be pinned, decrement our counter from the
7348c2ecf20Sopenharmony_ci	 *    total_bytes_pinned counter.
7358c2ecf20Sopenharmony_ci	 * 3. We are now at 0 and have ->must_insert_reserved set, which means
7368c2ecf20Sopenharmony_ci	 *    this was a new allocation and then we dropped it, and thus must
7378c2ecf20Sopenharmony_ci	 *    add our space to the total_bytes_pinned counter.
7388c2ecf20Sopenharmony_ci	 */
7398c2ecf20Sopenharmony_ci	if (existing->total_ref_mod < 0 && old_ref_mod >= 0)
7408c2ecf20Sopenharmony_ci		btrfs_mod_total_bytes_pinned(fs_info, flags, existing->num_bytes);
7418c2ecf20Sopenharmony_ci	else if (existing->total_ref_mod >= 0 && old_ref_mod < 0)
7428c2ecf20Sopenharmony_ci		btrfs_mod_total_bytes_pinned(fs_info, flags, -existing->num_bytes);
7438c2ecf20Sopenharmony_ci	else if (existing->total_ref_mod == 0 && existing->must_insert_reserved)
7448c2ecf20Sopenharmony_ci		btrfs_mod_total_bytes_pinned(fs_info, flags, existing->num_bytes);
7458c2ecf20Sopenharmony_ci
7468c2ecf20Sopenharmony_ci	spin_unlock(&existing->lock);
7478c2ecf20Sopenharmony_ci}
7488c2ecf20Sopenharmony_ci
7498c2ecf20Sopenharmony_cistatic void init_delayed_ref_head(struct btrfs_delayed_ref_head *head_ref,
7508c2ecf20Sopenharmony_ci				  struct btrfs_qgroup_extent_record *qrecord,
7518c2ecf20Sopenharmony_ci				  u64 bytenr, u64 num_bytes, u64 ref_root,
7528c2ecf20Sopenharmony_ci				  u64 reserved, int action, bool is_data,
7538c2ecf20Sopenharmony_ci				  bool is_system)
7548c2ecf20Sopenharmony_ci{
7558c2ecf20Sopenharmony_ci	int count_mod = 1;
7568c2ecf20Sopenharmony_ci	int must_insert_reserved = 0;
7578c2ecf20Sopenharmony_ci
7588c2ecf20Sopenharmony_ci	/* If reserved is provided, it must be a data extent. */
7598c2ecf20Sopenharmony_ci	BUG_ON(!is_data && reserved);
7608c2ecf20Sopenharmony_ci
7618c2ecf20Sopenharmony_ci	/*
7628c2ecf20Sopenharmony_ci	 * The head node stores the sum of all the mods, so dropping a ref
7638c2ecf20Sopenharmony_ci	 * should drop the sum in the head node by one.
7648c2ecf20Sopenharmony_ci	 */
7658c2ecf20Sopenharmony_ci	if (action == BTRFS_UPDATE_DELAYED_HEAD)
7668c2ecf20Sopenharmony_ci		count_mod = 0;
7678c2ecf20Sopenharmony_ci	else if (action == BTRFS_DROP_DELAYED_REF)
7688c2ecf20Sopenharmony_ci		count_mod = -1;
7698c2ecf20Sopenharmony_ci
7708c2ecf20Sopenharmony_ci	/*
7718c2ecf20Sopenharmony_ci	 * BTRFS_ADD_DELAYED_EXTENT means that we need to update the reserved
7728c2ecf20Sopenharmony_ci	 * accounting when the extent is finally added, or if a later
7738c2ecf20Sopenharmony_ci	 * modification deletes the delayed ref without ever inserting the
7748c2ecf20Sopenharmony_ci	 * extent into the extent allocation tree.  ref->must_insert_reserved
7758c2ecf20Sopenharmony_ci	 * is the flag used to record that accounting mods are required.
7768c2ecf20Sopenharmony_ci	 *
7778c2ecf20Sopenharmony_ci	 * Once we record must_insert_reserved, switch the action to
7788c2ecf20Sopenharmony_ci	 * BTRFS_ADD_DELAYED_REF because other special casing is not required.
7798c2ecf20Sopenharmony_ci	 */
7808c2ecf20Sopenharmony_ci	if (action == BTRFS_ADD_DELAYED_EXTENT)
7818c2ecf20Sopenharmony_ci		must_insert_reserved = 1;
7828c2ecf20Sopenharmony_ci	else
7838c2ecf20Sopenharmony_ci		must_insert_reserved = 0;
7848c2ecf20Sopenharmony_ci
7858c2ecf20Sopenharmony_ci	refcount_set(&head_ref->refs, 1);
7868c2ecf20Sopenharmony_ci	head_ref->bytenr = bytenr;
7878c2ecf20Sopenharmony_ci	head_ref->num_bytes = num_bytes;
7888c2ecf20Sopenharmony_ci	head_ref->ref_mod = count_mod;
7898c2ecf20Sopenharmony_ci	head_ref->must_insert_reserved = must_insert_reserved;
7908c2ecf20Sopenharmony_ci	head_ref->is_data = is_data;
7918c2ecf20Sopenharmony_ci	head_ref->is_system = is_system;
7928c2ecf20Sopenharmony_ci	head_ref->ref_tree = RB_ROOT_CACHED;
7938c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&head_ref->ref_add_list);
7948c2ecf20Sopenharmony_ci	RB_CLEAR_NODE(&head_ref->href_node);
7958c2ecf20Sopenharmony_ci	head_ref->processing = 0;
7968c2ecf20Sopenharmony_ci	head_ref->total_ref_mod = count_mod;
7978c2ecf20Sopenharmony_ci	spin_lock_init(&head_ref->lock);
7988c2ecf20Sopenharmony_ci	mutex_init(&head_ref->mutex);
7998c2ecf20Sopenharmony_ci
8008c2ecf20Sopenharmony_ci	if (qrecord) {
8018c2ecf20Sopenharmony_ci		if (ref_root && reserved) {
8028c2ecf20Sopenharmony_ci			qrecord->data_rsv = reserved;
8038c2ecf20Sopenharmony_ci			qrecord->data_rsv_refroot = ref_root;
8048c2ecf20Sopenharmony_ci		}
8058c2ecf20Sopenharmony_ci		qrecord->bytenr = bytenr;
8068c2ecf20Sopenharmony_ci		qrecord->num_bytes = num_bytes;
8078c2ecf20Sopenharmony_ci		qrecord->old_roots = NULL;
8088c2ecf20Sopenharmony_ci	}
8098c2ecf20Sopenharmony_ci}
8108c2ecf20Sopenharmony_ci
8118c2ecf20Sopenharmony_ci/*
8128c2ecf20Sopenharmony_ci * helper function to actually insert a head node into the rbtree.
8138c2ecf20Sopenharmony_ci * this does all the dirty work in terms of maintaining the correct
8148c2ecf20Sopenharmony_ci * overall modification count.
8158c2ecf20Sopenharmony_ci */
8168c2ecf20Sopenharmony_cistatic noinline struct btrfs_delayed_ref_head *
8178c2ecf20Sopenharmony_ciadd_delayed_ref_head(struct btrfs_trans_handle *trans,
8188c2ecf20Sopenharmony_ci		     struct btrfs_delayed_ref_head *head_ref,
8198c2ecf20Sopenharmony_ci		     struct btrfs_qgroup_extent_record *qrecord,
8208c2ecf20Sopenharmony_ci		     int action, int *qrecord_inserted_ret)
8218c2ecf20Sopenharmony_ci{
8228c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_head *existing;
8238c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_root *delayed_refs;
8248c2ecf20Sopenharmony_ci	int qrecord_inserted = 0;
8258c2ecf20Sopenharmony_ci
8268c2ecf20Sopenharmony_ci	delayed_refs = &trans->transaction->delayed_refs;
8278c2ecf20Sopenharmony_ci
8288c2ecf20Sopenharmony_ci	/* Record qgroup extent info if provided */
8298c2ecf20Sopenharmony_ci	if (qrecord) {
8308c2ecf20Sopenharmony_ci		if (btrfs_qgroup_trace_extent_nolock(trans->fs_info,
8318c2ecf20Sopenharmony_ci					delayed_refs, qrecord))
8328c2ecf20Sopenharmony_ci			kfree(qrecord);
8338c2ecf20Sopenharmony_ci		else
8348c2ecf20Sopenharmony_ci			qrecord_inserted = 1;
8358c2ecf20Sopenharmony_ci	}
8368c2ecf20Sopenharmony_ci
8378c2ecf20Sopenharmony_ci	trace_add_delayed_ref_head(trans->fs_info, head_ref, action);
8388c2ecf20Sopenharmony_ci
8398c2ecf20Sopenharmony_ci	existing = htree_insert(&delayed_refs->href_root,
8408c2ecf20Sopenharmony_ci				&head_ref->href_node);
8418c2ecf20Sopenharmony_ci	if (existing) {
8428c2ecf20Sopenharmony_ci		update_existing_head_ref(trans, existing, head_ref);
8438c2ecf20Sopenharmony_ci		/*
8448c2ecf20Sopenharmony_ci		 * we've updated the existing ref, free the newly
8458c2ecf20Sopenharmony_ci		 * allocated ref
8468c2ecf20Sopenharmony_ci		 */
8478c2ecf20Sopenharmony_ci		kmem_cache_free(btrfs_delayed_ref_head_cachep, head_ref);
8488c2ecf20Sopenharmony_ci		head_ref = existing;
8498c2ecf20Sopenharmony_ci	} else {
8508c2ecf20Sopenharmony_ci		u64 flags = btrfs_ref_head_to_space_flags(head_ref);
8518c2ecf20Sopenharmony_ci
8528c2ecf20Sopenharmony_ci		if (head_ref->is_data && head_ref->ref_mod < 0) {
8538c2ecf20Sopenharmony_ci			delayed_refs->pending_csums += head_ref->num_bytes;
8548c2ecf20Sopenharmony_ci			trans->delayed_ref_updates +=
8558c2ecf20Sopenharmony_ci				btrfs_csum_bytes_to_leaves(trans->fs_info,
8568c2ecf20Sopenharmony_ci							   head_ref->num_bytes);
8578c2ecf20Sopenharmony_ci		}
8588c2ecf20Sopenharmony_ci		if (head_ref->ref_mod < 0)
8598c2ecf20Sopenharmony_ci			btrfs_mod_total_bytes_pinned(trans->fs_info, flags,
8608c2ecf20Sopenharmony_ci						     head_ref->num_bytes);
8618c2ecf20Sopenharmony_ci		delayed_refs->num_heads++;
8628c2ecf20Sopenharmony_ci		delayed_refs->num_heads_ready++;
8638c2ecf20Sopenharmony_ci		atomic_inc(&delayed_refs->num_entries);
8648c2ecf20Sopenharmony_ci		trans->delayed_ref_updates++;
8658c2ecf20Sopenharmony_ci	}
8668c2ecf20Sopenharmony_ci	if (qrecord_inserted_ret)
8678c2ecf20Sopenharmony_ci		*qrecord_inserted_ret = qrecord_inserted;
8688c2ecf20Sopenharmony_ci
8698c2ecf20Sopenharmony_ci	return head_ref;
8708c2ecf20Sopenharmony_ci}
8718c2ecf20Sopenharmony_ci
8728c2ecf20Sopenharmony_ci/*
8738c2ecf20Sopenharmony_ci * init_delayed_ref_common - Initialize the structure which represents a
8748c2ecf20Sopenharmony_ci *			     modification to a an extent.
8758c2ecf20Sopenharmony_ci *
8768c2ecf20Sopenharmony_ci * @fs_info:    Internal to the mounted filesystem mount structure.
8778c2ecf20Sopenharmony_ci *
8788c2ecf20Sopenharmony_ci * @ref:	The structure which is going to be initialized.
8798c2ecf20Sopenharmony_ci *
8808c2ecf20Sopenharmony_ci * @bytenr:	The logical address of the extent for which a modification is
8818c2ecf20Sopenharmony_ci *		going to be recorded.
8828c2ecf20Sopenharmony_ci *
8838c2ecf20Sopenharmony_ci * @num_bytes:  Size of the extent whose modification is being recorded.
8848c2ecf20Sopenharmony_ci *
8858c2ecf20Sopenharmony_ci * @ref_root:	The id of the root where this modification has originated, this
8868c2ecf20Sopenharmony_ci *		can be either one of the well-known metadata trees or the
8878c2ecf20Sopenharmony_ci *		subvolume id which references this extent.
8888c2ecf20Sopenharmony_ci *
8898c2ecf20Sopenharmony_ci * @action:	Can be one of BTRFS_ADD_DELAYED_REF/BTRFS_DROP_DELAYED_REF or
8908c2ecf20Sopenharmony_ci *		BTRFS_ADD_DELAYED_EXTENT
8918c2ecf20Sopenharmony_ci *
8928c2ecf20Sopenharmony_ci * @ref_type:	Holds the type of the extent which is being recorded, can be
8938c2ecf20Sopenharmony_ci *		one of BTRFS_SHARED_BLOCK_REF_KEY/BTRFS_TREE_BLOCK_REF_KEY
8948c2ecf20Sopenharmony_ci *		when recording a metadata extent or BTRFS_SHARED_DATA_REF_KEY/
8958c2ecf20Sopenharmony_ci *		BTRFS_EXTENT_DATA_REF_KEY when recording data extent
8968c2ecf20Sopenharmony_ci */
8978c2ecf20Sopenharmony_cistatic void init_delayed_ref_common(struct btrfs_fs_info *fs_info,
8988c2ecf20Sopenharmony_ci				    struct btrfs_delayed_ref_node *ref,
8998c2ecf20Sopenharmony_ci				    u64 bytenr, u64 num_bytes, u64 ref_root,
9008c2ecf20Sopenharmony_ci				    int action, u8 ref_type)
9018c2ecf20Sopenharmony_ci{
9028c2ecf20Sopenharmony_ci	u64 seq = 0;
9038c2ecf20Sopenharmony_ci
9048c2ecf20Sopenharmony_ci	if (action == BTRFS_ADD_DELAYED_EXTENT)
9058c2ecf20Sopenharmony_ci		action = BTRFS_ADD_DELAYED_REF;
9068c2ecf20Sopenharmony_ci
9078c2ecf20Sopenharmony_ci	if (is_fstree(ref_root))
9088c2ecf20Sopenharmony_ci		seq = atomic64_read(&fs_info->tree_mod_seq);
9098c2ecf20Sopenharmony_ci
9108c2ecf20Sopenharmony_ci	refcount_set(&ref->refs, 1);
9118c2ecf20Sopenharmony_ci	ref->bytenr = bytenr;
9128c2ecf20Sopenharmony_ci	ref->num_bytes = num_bytes;
9138c2ecf20Sopenharmony_ci	ref->ref_mod = 1;
9148c2ecf20Sopenharmony_ci	ref->action = action;
9158c2ecf20Sopenharmony_ci	ref->is_head = 0;
9168c2ecf20Sopenharmony_ci	ref->in_tree = 1;
9178c2ecf20Sopenharmony_ci	ref->seq = seq;
9188c2ecf20Sopenharmony_ci	ref->type = ref_type;
9198c2ecf20Sopenharmony_ci	RB_CLEAR_NODE(&ref->ref_node);
9208c2ecf20Sopenharmony_ci	INIT_LIST_HEAD(&ref->add_list);
9218c2ecf20Sopenharmony_ci}
9228c2ecf20Sopenharmony_ci
9238c2ecf20Sopenharmony_ci/*
9248c2ecf20Sopenharmony_ci * add a delayed tree ref.  This does all of the accounting required
9258c2ecf20Sopenharmony_ci * to make sure the delayed ref is eventually processed before this
9268c2ecf20Sopenharmony_ci * transaction commits.
9278c2ecf20Sopenharmony_ci */
9288c2ecf20Sopenharmony_ciint btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans,
9298c2ecf20Sopenharmony_ci			       struct btrfs_ref *generic_ref,
9308c2ecf20Sopenharmony_ci			       struct btrfs_delayed_extent_op *extent_op)
9318c2ecf20Sopenharmony_ci{
9328c2ecf20Sopenharmony_ci	struct btrfs_fs_info *fs_info = trans->fs_info;
9338c2ecf20Sopenharmony_ci	struct btrfs_delayed_tree_ref *ref;
9348c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_head *head_ref;
9358c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_root *delayed_refs;
9368c2ecf20Sopenharmony_ci	struct btrfs_qgroup_extent_record *record = NULL;
9378c2ecf20Sopenharmony_ci	int qrecord_inserted;
9388c2ecf20Sopenharmony_ci	bool is_system;
9398c2ecf20Sopenharmony_ci	int action = generic_ref->action;
9408c2ecf20Sopenharmony_ci	int level = generic_ref->tree_ref.level;
9418c2ecf20Sopenharmony_ci	int ret;
9428c2ecf20Sopenharmony_ci	u64 bytenr = generic_ref->bytenr;
9438c2ecf20Sopenharmony_ci	u64 num_bytes = generic_ref->len;
9448c2ecf20Sopenharmony_ci	u64 parent = generic_ref->parent;
9458c2ecf20Sopenharmony_ci	u8 ref_type;
9468c2ecf20Sopenharmony_ci
9478c2ecf20Sopenharmony_ci	is_system = (generic_ref->real_root == BTRFS_CHUNK_TREE_OBJECTID);
9488c2ecf20Sopenharmony_ci
9498c2ecf20Sopenharmony_ci	ASSERT(generic_ref->type == BTRFS_REF_METADATA && generic_ref->action);
9508c2ecf20Sopenharmony_ci	BUG_ON(extent_op && extent_op->is_data);
9518c2ecf20Sopenharmony_ci	ref = kmem_cache_alloc(btrfs_delayed_tree_ref_cachep, GFP_NOFS);
9528c2ecf20Sopenharmony_ci	if (!ref)
9538c2ecf20Sopenharmony_ci		return -ENOMEM;
9548c2ecf20Sopenharmony_ci
9558c2ecf20Sopenharmony_ci	head_ref = kmem_cache_alloc(btrfs_delayed_ref_head_cachep, GFP_NOFS);
9568c2ecf20Sopenharmony_ci	if (!head_ref) {
9578c2ecf20Sopenharmony_ci		kmem_cache_free(btrfs_delayed_tree_ref_cachep, ref);
9588c2ecf20Sopenharmony_ci		return -ENOMEM;
9598c2ecf20Sopenharmony_ci	}
9608c2ecf20Sopenharmony_ci
9618c2ecf20Sopenharmony_ci	if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) &&
9628c2ecf20Sopenharmony_ci	    is_fstree(generic_ref->real_root) &&
9638c2ecf20Sopenharmony_ci	    is_fstree(generic_ref->tree_ref.root) &&
9648c2ecf20Sopenharmony_ci	    !generic_ref->skip_qgroup) {
9658c2ecf20Sopenharmony_ci		record = kzalloc(sizeof(*record), GFP_NOFS);
9668c2ecf20Sopenharmony_ci		if (!record) {
9678c2ecf20Sopenharmony_ci			kmem_cache_free(btrfs_delayed_tree_ref_cachep, ref);
9688c2ecf20Sopenharmony_ci			kmem_cache_free(btrfs_delayed_ref_head_cachep, head_ref);
9698c2ecf20Sopenharmony_ci			return -ENOMEM;
9708c2ecf20Sopenharmony_ci		}
9718c2ecf20Sopenharmony_ci	}
9728c2ecf20Sopenharmony_ci
9738c2ecf20Sopenharmony_ci	if (parent)
9748c2ecf20Sopenharmony_ci		ref_type = BTRFS_SHARED_BLOCK_REF_KEY;
9758c2ecf20Sopenharmony_ci	else
9768c2ecf20Sopenharmony_ci		ref_type = BTRFS_TREE_BLOCK_REF_KEY;
9778c2ecf20Sopenharmony_ci
9788c2ecf20Sopenharmony_ci	init_delayed_ref_common(fs_info, &ref->node, bytenr, num_bytes,
9798c2ecf20Sopenharmony_ci				generic_ref->tree_ref.root, action, ref_type);
9808c2ecf20Sopenharmony_ci	ref->root = generic_ref->tree_ref.root;
9818c2ecf20Sopenharmony_ci	ref->parent = parent;
9828c2ecf20Sopenharmony_ci	ref->level = level;
9838c2ecf20Sopenharmony_ci
9848c2ecf20Sopenharmony_ci	init_delayed_ref_head(head_ref, record, bytenr, num_bytes,
9858c2ecf20Sopenharmony_ci			      generic_ref->tree_ref.root, 0, action, false,
9868c2ecf20Sopenharmony_ci			      is_system);
9878c2ecf20Sopenharmony_ci	head_ref->extent_op = extent_op;
9888c2ecf20Sopenharmony_ci
9898c2ecf20Sopenharmony_ci	delayed_refs = &trans->transaction->delayed_refs;
9908c2ecf20Sopenharmony_ci	spin_lock(&delayed_refs->lock);
9918c2ecf20Sopenharmony_ci
9928c2ecf20Sopenharmony_ci	/*
9938c2ecf20Sopenharmony_ci	 * insert both the head node and the new ref without dropping
9948c2ecf20Sopenharmony_ci	 * the spin lock
9958c2ecf20Sopenharmony_ci	 */
9968c2ecf20Sopenharmony_ci	head_ref = add_delayed_ref_head(trans, head_ref, record,
9978c2ecf20Sopenharmony_ci					action, &qrecord_inserted);
9988c2ecf20Sopenharmony_ci
9998c2ecf20Sopenharmony_ci	ret = insert_delayed_ref(trans, delayed_refs, head_ref, &ref->node);
10008c2ecf20Sopenharmony_ci	spin_unlock(&delayed_refs->lock);
10018c2ecf20Sopenharmony_ci
10028c2ecf20Sopenharmony_ci	/*
10038c2ecf20Sopenharmony_ci	 * Need to update the delayed_refs_rsv with any changes we may have
10048c2ecf20Sopenharmony_ci	 * made.
10058c2ecf20Sopenharmony_ci	 */
10068c2ecf20Sopenharmony_ci	btrfs_update_delayed_refs_rsv(trans);
10078c2ecf20Sopenharmony_ci
10088c2ecf20Sopenharmony_ci	trace_add_delayed_tree_ref(fs_info, &ref->node, ref,
10098c2ecf20Sopenharmony_ci				   action == BTRFS_ADD_DELAYED_EXTENT ?
10108c2ecf20Sopenharmony_ci				   BTRFS_ADD_DELAYED_REF : action);
10118c2ecf20Sopenharmony_ci	if (ret > 0)
10128c2ecf20Sopenharmony_ci		kmem_cache_free(btrfs_delayed_tree_ref_cachep, ref);
10138c2ecf20Sopenharmony_ci
10148c2ecf20Sopenharmony_ci	if (qrecord_inserted)
10158c2ecf20Sopenharmony_ci		btrfs_qgroup_trace_extent_post(fs_info, record);
10168c2ecf20Sopenharmony_ci
10178c2ecf20Sopenharmony_ci	return 0;
10188c2ecf20Sopenharmony_ci}
10198c2ecf20Sopenharmony_ci
10208c2ecf20Sopenharmony_ci/*
10218c2ecf20Sopenharmony_ci * add a delayed data ref. it's similar to btrfs_add_delayed_tree_ref.
10228c2ecf20Sopenharmony_ci */
10238c2ecf20Sopenharmony_ciint btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans,
10248c2ecf20Sopenharmony_ci			       struct btrfs_ref *generic_ref,
10258c2ecf20Sopenharmony_ci			       u64 reserved)
10268c2ecf20Sopenharmony_ci{
10278c2ecf20Sopenharmony_ci	struct btrfs_fs_info *fs_info = trans->fs_info;
10288c2ecf20Sopenharmony_ci	struct btrfs_delayed_data_ref *ref;
10298c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_head *head_ref;
10308c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_root *delayed_refs;
10318c2ecf20Sopenharmony_ci	struct btrfs_qgroup_extent_record *record = NULL;
10328c2ecf20Sopenharmony_ci	int qrecord_inserted;
10338c2ecf20Sopenharmony_ci	int action = generic_ref->action;
10348c2ecf20Sopenharmony_ci	int ret;
10358c2ecf20Sopenharmony_ci	u64 bytenr = generic_ref->bytenr;
10368c2ecf20Sopenharmony_ci	u64 num_bytes = generic_ref->len;
10378c2ecf20Sopenharmony_ci	u64 parent = generic_ref->parent;
10388c2ecf20Sopenharmony_ci	u64 ref_root = generic_ref->data_ref.ref_root;
10398c2ecf20Sopenharmony_ci	u64 owner = generic_ref->data_ref.ino;
10408c2ecf20Sopenharmony_ci	u64 offset = generic_ref->data_ref.offset;
10418c2ecf20Sopenharmony_ci	u8 ref_type;
10428c2ecf20Sopenharmony_ci
10438c2ecf20Sopenharmony_ci	ASSERT(generic_ref->type == BTRFS_REF_DATA && action);
10448c2ecf20Sopenharmony_ci	ref = kmem_cache_alloc(btrfs_delayed_data_ref_cachep, GFP_NOFS);
10458c2ecf20Sopenharmony_ci	if (!ref)
10468c2ecf20Sopenharmony_ci		return -ENOMEM;
10478c2ecf20Sopenharmony_ci
10488c2ecf20Sopenharmony_ci	if (parent)
10498c2ecf20Sopenharmony_ci	        ref_type = BTRFS_SHARED_DATA_REF_KEY;
10508c2ecf20Sopenharmony_ci	else
10518c2ecf20Sopenharmony_ci	        ref_type = BTRFS_EXTENT_DATA_REF_KEY;
10528c2ecf20Sopenharmony_ci	init_delayed_ref_common(fs_info, &ref->node, bytenr, num_bytes,
10538c2ecf20Sopenharmony_ci				ref_root, action, ref_type);
10548c2ecf20Sopenharmony_ci	ref->root = ref_root;
10558c2ecf20Sopenharmony_ci	ref->parent = parent;
10568c2ecf20Sopenharmony_ci	ref->objectid = owner;
10578c2ecf20Sopenharmony_ci	ref->offset = offset;
10588c2ecf20Sopenharmony_ci
10598c2ecf20Sopenharmony_ci
10608c2ecf20Sopenharmony_ci	head_ref = kmem_cache_alloc(btrfs_delayed_ref_head_cachep, GFP_NOFS);
10618c2ecf20Sopenharmony_ci	if (!head_ref) {
10628c2ecf20Sopenharmony_ci		kmem_cache_free(btrfs_delayed_data_ref_cachep, ref);
10638c2ecf20Sopenharmony_ci		return -ENOMEM;
10648c2ecf20Sopenharmony_ci	}
10658c2ecf20Sopenharmony_ci
10668c2ecf20Sopenharmony_ci	if (test_bit(BTRFS_FS_QUOTA_ENABLED, &fs_info->flags) &&
10678c2ecf20Sopenharmony_ci	    is_fstree(ref_root) &&
10688c2ecf20Sopenharmony_ci	    is_fstree(generic_ref->real_root) &&
10698c2ecf20Sopenharmony_ci	    !generic_ref->skip_qgroup) {
10708c2ecf20Sopenharmony_ci		record = kzalloc(sizeof(*record), GFP_NOFS);
10718c2ecf20Sopenharmony_ci		if (!record) {
10728c2ecf20Sopenharmony_ci			kmem_cache_free(btrfs_delayed_data_ref_cachep, ref);
10738c2ecf20Sopenharmony_ci			kmem_cache_free(btrfs_delayed_ref_head_cachep,
10748c2ecf20Sopenharmony_ci					head_ref);
10758c2ecf20Sopenharmony_ci			return -ENOMEM;
10768c2ecf20Sopenharmony_ci		}
10778c2ecf20Sopenharmony_ci	}
10788c2ecf20Sopenharmony_ci
10798c2ecf20Sopenharmony_ci	init_delayed_ref_head(head_ref, record, bytenr, num_bytes, ref_root,
10808c2ecf20Sopenharmony_ci			      reserved, action, true, false);
10818c2ecf20Sopenharmony_ci	head_ref->extent_op = NULL;
10828c2ecf20Sopenharmony_ci
10838c2ecf20Sopenharmony_ci	delayed_refs = &trans->transaction->delayed_refs;
10848c2ecf20Sopenharmony_ci	spin_lock(&delayed_refs->lock);
10858c2ecf20Sopenharmony_ci
10868c2ecf20Sopenharmony_ci	/*
10878c2ecf20Sopenharmony_ci	 * insert both the head node and the new ref without dropping
10888c2ecf20Sopenharmony_ci	 * the spin lock
10898c2ecf20Sopenharmony_ci	 */
10908c2ecf20Sopenharmony_ci	head_ref = add_delayed_ref_head(trans, head_ref, record,
10918c2ecf20Sopenharmony_ci					action, &qrecord_inserted);
10928c2ecf20Sopenharmony_ci
10938c2ecf20Sopenharmony_ci	ret = insert_delayed_ref(trans, delayed_refs, head_ref, &ref->node);
10948c2ecf20Sopenharmony_ci	spin_unlock(&delayed_refs->lock);
10958c2ecf20Sopenharmony_ci
10968c2ecf20Sopenharmony_ci	/*
10978c2ecf20Sopenharmony_ci	 * Need to update the delayed_refs_rsv with any changes we may have
10988c2ecf20Sopenharmony_ci	 * made.
10998c2ecf20Sopenharmony_ci	 */
11008c2ecf20Sopenharmony_ci	btrfs_update_delayed_refs_rsv(trans);
11018c2ecf20Sopenharmony_ci
11028c2ecf20Sopenharmony_ci	trace_add_delayed_data_ref(trans->fs_info, &ref->node, ref,
11038c2ecf20Sopenharmony_ci				   action == BTRFS_ADD_DELAYED_EXTENT ?
11048c2ecf20Sopenharmony_ci				   BTRFS_ADD_DELAYED_REF : action);
11058c2ecf20Sopenharmony_ci	if (ret > 0)
11068c2ecf20Sopenharmony_ci		kmem_cache_free(btrfs_delayed_data_ref_cachep, ref);
11078c2ecf20Sopenharmony_ci
11088c2ecf20Sopenharmony_ci
11098c2ecf20Sopenharmony_ci	if (qrecord_inserted)
11108c2ecf20Sopenharmony_ci		return btrfs_qgroup_trace_extent_post(fs_info, record);
11118c2ecf20Sopenharmony_ci	return 0;
11128c2ecf20Sopenharmony_ci}
11138c2ecf20Sopenharmony_ci
11148c2ecf20Sopenharmony_ciint btrfs_add_delayed_extent_op(struct btrfs_trans_handle *trans,
11158c2ecf20Sopenharmony_ci				u64 bytenr, u64 num_bytes,
11168c2ecf20Sopenharmony_ci				struct btrfs_delayed_extent_op *extent_op)
11178c2ecf20Sopenharmony_ci{
11188c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_head *head_ref;
11198c2ecf20Sopenharmony_ci	struct btrfs_delayed_ref_root *delayed_refs;
11208c2ecf20Sopenharmony_ci
11218c2ecf20Sopenharmony_ci	head_ref = kmem_cache_alloc(btrfs_delayed_ref_head_cachep, GFP_NOFS);
11228c2ecf20Sopenharmony_ci	if (!head_ref)
11238c2ecf20Sopenharmony_ci		return -ENOMEM;
11248c2ecf20Sopenharmony_ci
11258c2ecf20Sopenharmony_ci	init_delayed_ref_head(head_ref, NULL, bytenr, num_bytes, 0, 0,
11268c2ecf20Sopenharmony_ci			      BTRFS_UPDATE_DELAYED_HEAD, extent_op->is_data,
11278c2ecf20Sopenharmony_ci			      false);
11288c2ecf20Sopenharmony_ci	head_ref->extent_op = extent_op;
11298c2ecf20Sopenharmony_ci
11308c2ecf20Sopenharmony_ci	delayed_refs = &trans->transaction->delayed_refs;
11318c2ecf20Sopenharmony_ci	spin_lock(&delayed_refs->lock);
11328c2ecf20Sopenharmony_ci
11338c2ecf20Sopenharmony_ci	add_delayed_ref_head(trans, head_ref, NULL, BTRFS_UPDATE_DELAYED_HEAD,
11348c2ecf20Sopenharmony_ci			     NULL);
11358c2ecf20Sopenharmony_ci
11368c2ecf20Sopenharmony_ci	spin_unlock(&delayed_refs->lock);
11378c2ecf20Sopenharmony_ci
11388c2ecf20Sopenharmony_ci	/*
11398c2ecf20Sopenharmony_ci	 * Need to update the delayed_refs_rsv with any changes we may have
11408c2ecf20Sopenharmony_ci	 * made.
11418c2ecf20Sopenharmony_ci	 */
11428c2ecf20Sopenharmony_ci	btrfs_update_delayed_refs_rsv(trans);
11438c2ecf20Sopenharmony_ci	return 0;
11448c2ecf20Sopenharmony_ci}
11458c2ecf20Sopenharmony_ci
11468c2ecf20Sopenharmony_ci/*
11478c2ecf20Sopenharmony_ci * This does a simple search for the head node for a given extent.  Returns the
11488c2ecf20Sopenharmony_ci * head node if found, or NULL if not.
11498c2ecf20Sopenharmony_ci */
11508c2ecf20Sopenharmony_cistruct btrfs_delayed_ref_head *
11518c2ecf20Sopenharmony_cibtrfs_find_delayed_ref_head(struct btrfs_delayed_ref_root *delayed_refs, u64 bytenr)
11528c2ecf20Sopenharmony_ci{
11538c2ecf20Sopenharmony_ci	lockdep_assert_held(&delayed_refs->lock);
11548c2ecf20Sopenharmony_ci
11558c2ecf20Sopenharmony_ci	return find_ref_head(delayed_refs, bytenr, false);
11568c2ecf20Sopenharmony_ci}
11578c2ecf20Sopenharmony_ci
11588c2ecf20Sopenharmony_civoid __cold btrfs_delayed_ref_exit(void)
11598c2ecf20Sopenharmony_ci{
11608c2ecf20Sopenharmony_ci	kmem_cache_destroy(btrfs_delayed_ref_head_cachep);
11618c2ecf20Sopenharmony_ci	kmem_cache_destroy(btrfs_delayed_tree_ref_cachep);
11628c2ecf20Sopenharmony_ci	kmem_cache_destroy(btrfs_delayed_data_ref_cachep);
11638c2ecf20Sopenharmony_ci	kmem_cache_destroy(btrfs_delayed_extent_op_cachep);
11648c2ecf20Sopenharmony_ci}
11658c2ecf20Sopenharmony_ci
11668c2ecf20Sopenharmony_ciint __init btrfs_delayed_ref_init(void)
11678c2ecf20Sopenharmony_ci{
11688c2ecf20Sopenharmony_ci	btrfs_delayed_ref_head_cachep = kmem_cache_create(
11698c2ecf20Sopenharmony_ci				"btrfs_delayed_ref_head",
11708c2ecf20Sopenharmony_ci				sizeof(struct btrfs_delayed_ref_head), 0,
11718c2ecf20Sopenharmony_ci				SLAB_MEM_SPREAD, NULL);
11728c2ecf20Sopenharmony_ci	if (!btrfs_delayed_ref_head_cachep)
11738c2ecf20Sopenharmony_ci		goto fail;
11748c2ecf20Sopenharmony_ci
11758c2ecf20Sopenharmony_ci	btrfs_delayed_tree_ref_cachep = kmem_cache_create(
11768c2ecf20Sopenharmony_ci				"btrfs_delayed_tree_ref",
11778c2ecf20Sopenharmony_ci				sizeof(struct btrfs_delayed_tree_ref), 0,
11788c2ecf20Sopenharmony_ci				SLAB_MEM_SPREAD, NULL);
11798c2ecf20Sopenharmony_ci	if (!btrfs_delayed_tree_ref_cachep)
11808c2ecf20Sopenharmony_ci		goto fail;
11818c2ecf20Sopenharmony_ci
11828c2ecf20Sopenharmony_ci	btrfs_delayed_data_ref_cachep = kmem_cache_create(
11838c2ecf20Sopenharmony_ci				"btrfs_delayed_data_ref",
11848c2ecf20Sopenharmony_ci				sizeof(struct btrfs_delayed_data_ref), 0,
11858c2ecf20Sopenharmony_ci				SLAB_MEM_SPREAD, NULL);
11868c2ecf20Sopenharmony_ci	if (!btrfs_delayed_data_ref_cachep)
11878c2ecf20Sopenharmony_ci		goto fail;
11888c2ecf20Sopenharmony_ci
11898c2ecf20Sopenharmony_ci	btrfs_delayed_extent_op_cachep = kmem_cache_create(
11908c2ecf20Sopenharmony_ci				"btrfs_delayed_extent_op",
11918c2ecf20Sopenharmony_ci				sizeof(struct btrfs_delayed_extent_op), 0,
11928c2ecf20Sopenharmony_ci				SLAB_MEM_SPREAD, NULL);
11938c2ecf20Sopenharmony_ci	if (!btrfs_delayed_extent_op_cachep)
11948c2ecf20Sopenharmony_ci		goto fail;
11958c2ecf20Sopenharmony_ci
11968c2ecf20Sopenharmony_ci	return 0;
11978c2ecf20Sopenharmony_cifail:
11988c2ecf20Sopenharmony_ci	btrfs_delayed_ref_exit();
11998c2ecf20Sopenharmony_ci	return -ENOMEM;
12008c2ecf20Sopenharmony_ci}
1201