18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
28c2ecf20Sopenharmony_ci
38c2ecf20Sopenharmony_ci#include "misc.h"
48c2ecf20Sopenharmony_ci#include "ctree.h"
58c2ecf20Sopenharmony_ci#include "block-rsv.h"
68c2ecf20Sopenharmony_ci#include "space-info.h"
78c2ecf20Sopenharmony_ci#include "transaction.h"
88c2ecf20Sopenharmony_ci#include "block-group.h"
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci/*
118c2ecf20Sopenharmony_ci * HOW DO BLOCK RESERVES WORK
128c2ecf20Sopenharmony_ci *
138c2ecf20Sopenharmony_ci *   Think of block_rsv's as buckets for logically grouped metadata
148c2ecf20Sopenharmony_ci *   reservations.  Each block_rsv has a ->size and a ->reserved.  ->size is
158c2ecf20Sopenharmony_ci *   how large we want our block rsv to be, ->reserved is how much space is
168c2ecf20Sopenharmony_ci *   currently reserved for this block reserve.
178c2ecf20Sopenharmony_ci *
188c2ecf20Sopenharmony_ci *   ->failfast exists for the truncate case, and is described below.
198c2ecf20Sopenharmony_ci *
208c2ecf20Sopenharmony_ci * NORMAL OPERATION
218c2ecf20Sopenharmony_ci *
228c2ecf20Sopenharmony_ci *   -> Reserve
238c2ecf20Sopenharmony_ci *     Entrance: btrfs_block_rsv_add, btrfs_block_rsv_refill
248c2ecf20Sopenharmony_ci *
258c2ecf20Sopenharmony_ci *     We call into btrfs_reserve_metadata_bytes() with our bytes, which is
268c2ecf20Sopenharmony_ci *     accounted for in space_info->bytes_may_use, and then add the bytes to
278c2ecf20Sopenharmony_ci *     ->reserved, and ->size in the case of btrfs_block_rsv_add.
288c2ecf20Sopenharmony_ci *
298c2ecf20Sopenharmony_ci *     ->size is an over-estimation of how much we may use for a particular
308c2ecf20Sopenharmony_ci *     operation.
318c2ecf20Sopenharmony_ci *
328c2ecf20Sopenharmony_ci *   -> Use
338c2ecf20Sopenharmony_ci *     Entrance: btrfs_use_block_rsv
348c2ecf20Sopenharmony_ci *
358c2ecf20Sopenharmony_ci *     When we do a btrfs_alloc_tree_block() we call into btrfs_use_block_rsv()
368c2ecf20Sopenharmony_ci *     to determine the appropriate block_rsv to use, and then verify that
378c2ecf20Sopenharmony_ci *     ->reserved has enough space for our tree block allocation.  Once
388c2ecf20Sopenharmony_ci *     successful we subtract fs_info->nodesize from ->reserved.
398c2ecf20Sopenharmony_ci *
408c2ecf20Sopenharmony_ci *   -> Finish
418c2ecf20Sopenharmony_ci *     Entrance: btrfs_block_rsv_release
428c2ecf20Sopenharmony_ci *
438c2ecf20Sopenharmony_ci *     We are finished with our operation, subtract our individual reservation
448c2ecf20Sopenharmony_ci *     from ->size, and then subtract ->size from ->reserved and free up the
458c2ecf20Sopenharmony_ci *     excess if there is any.
468c2ecf20Sopenharmony_ci *
478c2ecf20Sopenharmony_ci *     There is some logic here to refill the delayed refs rsv or the global rsv
488c2ecf20Sopenharmony_ci *     as needed, otherwise the excess is subtracted from
498c2ecf20Sopenharmony_ci *     space_info->bytes_may_use.
508c2ecf20Sopenharmony_ci *
518c2ecf20Sopenharmony_ci * TYPES OF BLOCK RESERVES
528c2ecf20Sopenharmony_ci *
538c2ecf20Sopenharmony_ci * BLOCK_RSV_TRANS, BLOCK_RSV_DELOPS, BLOCK_RSV_CHUNK
548c2ecf20Sopenharmony_ci *   These behave normally, as described above, just within the confines of the
558c2ecf20Sopenharmony_ci *   lifetime of their particular operation (transaction for the whole trans
568c2ecf20Sopenharmony_ci *   handle lifetime, for example).
578c2ecf20Sopenharmony_ci *
588c2ecf20Sopenharmony_ci * BLOCK_RSV_GLOBAL
598c2ecf20Sopenharmony_ci *   It is impossible to properly account for all the space that may be required
608c2ecf20Sopenharmony_ci *   to make our extent tree updates.  This block reserve acts as an overflow
618c2ecf20Sopenharmony_ci *   buffer in case our delayed refs reserve does not reserve enough space to
628c2ecf20Sopenharmony_ci *   update the extent tree.
638c2ecf20Sopenharmony_ci *
648c2ecf20Sopenharmony_ci *   We can steal from this in some cases as well, notably on evict() or
658c2ecf20Sopenharmony_ci *   truncate() in order to help users recover from ENOSPC conditions.
668c2ecf20Sopenharmony_ci *
678c2ecf20Sopenharmony_ci * BLOCK_RSV_DELALLOC
688c2ecf20Sopenharmony_ci *   The individual item sizes are determined by the per-inode size
698c2ecf20Sopenharmony_ci *   calculations, which are described with the delalloc code.  This is pretty
708c2ecf20Sopenharmony_ci *   straightforward, it's just the calculation of ->size encodes a lot of
718c2ecf20Sopenharmony_ci *   different items, and thus it gets used when updating inodes, inserting file
728c2ecf20Sopenharmony_ci *   extents, and inserting checksums.
738c2ecf20Sopenharmony_ci *
748c2ecf20Sopenharmony_ci * BLOCK_RSV_DELREFS
758c2ecf20Sopenharmony_ci *   We keep a running tally of how many delayed refs we have on the system.
768c2ecf20Sopenharmony_ci *   We assume each one of these delayed refs are going to use a full
778c2ecf20Sopenharmony_ci *   reservation.  We use the transaction items and pre-reserve space for every
788c2ecf20Sopenharmony_ci *   operation, and use this reservation to refill any gap between ->size and
798c2ecf20Sopenharmony_ci *   ->reserved that may exist.
808c2ecf20Sopenharmony_ci *
818c2ecf20Sopenharmony_ci *   From there it's straightforward, removing a delayed ref means we remove its
828c2ecf20Sopenharmony_ci *   count from ->size and free up reservations as necessary.  Since this is
838c2ecf20Sopenharmony_ci *   the most dynamic block reserve in the system, we will try to refill this
848c2ecf20Sopenharmony_ci *   block reserve first with any excess returned by any other block reserve.
858c2ecf20Sopenharmony_ci *
868c2ecf20Sopenharmony_ci * BLOCK_RSV_EMPTY
878c2ecf20Sopenharmony_ci *   This is the fallback block reserve to make us try to reserve space if we
888c2ecf20Sopenharmony_ci *   don't have a specific bucket for this allocation.  It is mostly used for
898c2ecf20Sopenharmony_ci *   updating the device tree and such, since that is a separate pool we're
908c2ecf20Sopenharmony_ci *   content to just reserve space from the space_info on demand.
918c2ecf20Sopenharmony_ci *
928c2ecf20Sopenharmony_ci * BLOCK_RSV_TEMP
938c2ecf20Sopenharmony_ci *   This is used by things like truncate and iput.  We will temporarily
948c2ecf20Sopenharmony_ci *   allocate a block reserve, set it to some size, and then truncate bytes
958c2ecf20Sopenharmony_ci *   until we have no space left.  With ->failfast set we'll simply return
968c2ecf20Sopenharmony_ci *   ENOSPC from btrfs_use_block_rsv() to signal that we need to unwind and try
978c2ecf20Sopenharmony_ci *   to make a new reservation.  This is because these operations are
988c2ecf20Sopenharmony_ci *   unbounded, so we want to do as much work as we can, and then back off and
998c2ecf20Sopenharmony_ci *   re-reserve.
1008c2ecf20Sopenharmony_ci */
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_cistatic u64 block_rsv_release_bytes(struct btrfs_fs_info *fs_info,
1038c2ecf20Sopenharmony_ci				    struct btrfs_block_rsv *block_rsv,
1048c2ecf20Sopenharmony_ci				    struct btrfs_block_rsv *dest, u64 num_bytes,
1058c2ecf20Sopenharmony_ci				    u64 *qgroup_to_release_ret)
1068c2ecf20Sopenharmony_ci{
1078c2ecf20Sopenharmony_ci	struct btrfs_space_info *space_info = block_rsv->space_info;
1088c2ecf20Sopenharmony_ci	u64 qgroup_to_release = 0;
1098c2ecf20Sopenharmony_ci	u64 ret;
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci	spin_lock(&block_rsv->lock);
1128c2ecf20Sopenharmony_ci	if (num_bytes == (u64)-1) {
1138c2ecf20Sopenharmony_ci		num_bytes = block_rsv->size;
1148c2ecf20Sopenharmony_ci		qgroup_to_release = block_rsv->qgroup_rsv_size;
1158c2ecf20Sopenharmony_ci	}
1168c2ecf20Sopenharmony_ci	block_rsv->size -= num_bytes;
1178c2ecf20Sopenharmony_ci	if (block_rsv->reserved >= block_rsv->size) {
1188c2ecf20Sopenharmony_ci		num_bytes = block_rsv->reserved - block_rsv->size;
1198c2ecf20Sopenharmony_ci		block_rsv->reserved = block_rsv->size;
1208c2ecf20Sopenharmony_ci		block_rsv->full = 1;
1218c2ecf20Sopenharmony_ci	} else {
1228c2ecf20Sopenharmony_ci		num_bytes = 0;
1238c2ecf20Sopenharmony_ci	}
1248c2ecf20Sopenharmony_ci	if (qgroup_to_release_ret &&
1258c2ecf20Sopenharmony_ci	    block_rsv->qgroup_rsv_reserved >= block_rsv->qgroup_rsv_size) {
1268c2ecf20Sopenharmony_ci		qgroup_to_release = block_rsv->qgroup_rsv_reserved -
1278c2ecf20Sopenharmony_ci				    block_rsv->qgroup_rsv_size;
1288c2ecf20Sopenharmony_ci		block_rsv->qgroup_rsv_reserved = block_rsv->qgroup_rsv_size;
1298c2ecf20Sopenharmony_ci	} else {
1308c2ecf20Sopenharmony_ci		qgroup_to_release = 0;
1318c2ecf20Sopenharmony_ci	}
1328c2ecf20Sopenharmony_ci	spin_unlock(&block_rsv->lock);
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci	ret = num_bytes;
1358c2ecf20Sopenharmony_ci	if (num_bytes > 0) {
1368c2ecf20Sopenharmony_ci		if (dest) {
1378c2ecf20Sopenharmony_ci			spin_lock(&dest->lock);
1388c2ecf20Sopenharmony_ci			if (!dest->full) {
1398c2ecf20Sopenharmony_ci				u64 bytes_to_add;
1408c2ecf20Sopenharmony_ci
1418c2ecf20Sopenharmony_ci				bytes_to_add = dest->size - dest->reserved;
1428c2ecf20Sopenharmony_ci				bytes_to_add = min(num_bytes, bytes_to_add);
1438c2ecf20Sopenharmony_ci				dest->reserved += bytes_to_add;
1448c2ecf20Sopenharmony_ci				if (dest->reserved >= dest->size)
1458c2ecf20Sopenharmony_ci					dest->full = 1;
1468c2ecf20Sopenharmony_ci				num_bytes -= bytes_to_add;
1478c2ecf20Sopenharmony_ci			}
1488c2ecf20Sopenharmony_ci			spin_unlock(&dest->lock);
1498c2ecf20Sopenharmony_ci		}
1508c2ecf20Sopenharmony_ci		if (num_bytes)
1518c2ecf20Sopenharmony_ci			btrfs_space_info_free_bytes_may_use(fs_info,
1528c2ecf20Sopenharmony_ci							    space_info,
1538c2ecf20Sopenharmony_ci							    num_bytes);
1548c2ecf20Sopenharmony_ci	}
1558c2ecf20Sopenharmony_ci	if (qgroup_to_release_ret)
1568c2ecf20Sopenharmony_ci		*qgroup_to_release_ret = qgroup_to_release;
1578c2ecf20Sopenharmony_ci	return ret;
1588c2ecf20Sopenharmony_ci}
1598c2ecf20Sopenharmony_ci
1608c2ecf20Sopenharmony_ciint btrfs_block_rsv_migrate(struct btrfs_block_rsv *src,
1618c2ecf20Sopenharmony_ci			    struct btrfs_block_rsv *dst, u64 num_bytes,
1628c2ecf20Sopenharmony_ci			    bool update_size)
1638c2ecf20Sopenharmony_ci{
1648c2ecf20Sopenharmony_ci	int ret;
1658c2ecf20Sopenharmony_ci
1668c2ecf20Sopenharmony_ci	ret = btrfs_block_rsv_use_bytes(src, num_bytes);
1678c2ecf20Sopenharmony_ci	if (ret)
1688c2ecf20Sopenharmony_ci		return ret;
1698c2ecf20Sopenharmony_ci
1708c2ecf20Sopenharmony_ci	btrfs_block_rsv_add_bytes(dst, num_bytes, update_size);
1718c2ecf20Sopenharmony_ci	return 0;
1728c2ecf20Sopenharmony_ci}
1738c2ecf20Sopenharmony_ci
1748c2ecf20Sopenharmony_civoid btrfs_init_block_rsv(struct btrfs_block_rsv *rsv, unsigned short type)
1758c2ecf20Sopenharmony_ci{
1768c2ecf20Sopenharmony_ci	memset(rsv, 0, sizeof(*rsv));
1778c2ecf20Sopenharmony_ci	spin_lock_init(&rsv->lock);
1788c2ecf20Sopenharmony_ci	rsv->type = type;
1798c2ecf20Sopenharmony_ci}
1808c2ecf20Sopenharmony_ci
1818c2ecf20Sopenharmony_civoid btrfs_init_metadata_block_rsv(struct btrfs_fs_info *fs_info,
1828c2ecf20Sopenharmony_ci				   struct btrfs_block_rsv *rsv,
1838c2ecf20Sopenharmony_ci				   unsigned short type)
1848c2ecf20Sopenharmony_ci{
1858c2ecf20Sopenharmony_ci	btrfs_init_block_rsv(rsv, type);
1868c2ecf20Sopenharmony_ci	rsv->space_info = btrfs_find_space_info(fs_info,
1878c2ecf20Sopenharmony_ci					    BTRFS_BLOCK_GROUP_METADATA);
1888c2ecf20Sopenharmony_ci}
1898c2ecf20Sopenharmony_ci
1908c2ecf20Sopenharmony_cistruct btrfs_block_rsv *btrfs_alloc_block_rsv(struct btrfs_fs_info *fs_info,
1918c2ecf20Sopenharmony_ci					      unsigned short type)
1928c2ecf20Sopenharmony_ci{
1938c2ecf20Sopenharmony_ci	struct btrfs_block_rsv *block_rsv;
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci	block_rsv = kmalloc(sizeof(*block_rsv), GFP_NOFS);
1968c2ecf20Sopenharmony_ci	if (!block_rsv)
1978c2ecf20Sopenharmony_ci		return NULL;
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_ci	btrfs_init_metadata_block_rsv(fs_info, block_rsv, type);
2008c2ecf20Sopenharmony_ci	return block_rsv;
2018c2ecf20Sopenharmony_ci}
2028c2ecf20Sopenharmony_ci
2038c2ecf20Sopenharmony_civoid btrfs_free_block_rsv(struct btrfs_fs_info *fs_info,
2048c2ecf20Sopenharmony_ci			  struct btrfs_block_rsv *rsv)
2058c2ecf20Sopenharmony_ci{
2068c2ecf20Sopenharmony_ci	if (!rsv)
2078c2ecf20Sopenharmony_ci		return;
2088c2ecf20Sopenharmony_ci	btrfs_block_rsv_release(fs_info, rsv, (u64)-1, NULL);
2098c2ecf20Sopenharmony_ci	kfree(rsv);
2108c2ecf20Sopenharmony_ci}
2118c2ecf20Sopenharmony_ci
2128c2ecf20Sopenharmony_ciint btrfs_block_rsv_add(struct btrfs_root *root,
2138c2ecf20Sopenharmony_ci			struct btrfs_block_rsv *block_rsv, u64 num_bytes,
2148c2ecf20Sopenharmony_ci			enum btrfs_reserve_flush_enum flush)
2158c2ecf20Sopenharmony_ci{
2168c2ecf20Sopenharmony_ci	int ret;
2178c2ecf20Sopenharmony_ci
2188c2ecf20Sopenharmony_ci	if (num_bytes == 0)
2198c2ecf20Sopenharmony_ci		return 0;
2208c2ecf20Sopenharmony_ci
2218c2ecf20Sopenharmony_ci	ret = btrfs_reserve_metadata_bytes(root, block_rsv, num_bytes, flush);
2228c2ecf20Sopenharmony_ci	if (!ret)
2238c2ecf20Sopenharmony_ci		btrfs_block_rsv_add_bytes(block_rsv, num_bytes, true);
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci	return ret;
2268c2ecf20Sopenharmony_ci}
2278c2ecf20Sopenharmony_ci
2288c2ecf20Sopenharmony_ciint btrfs_block_rsv_check(struct btrfs_block_rsv *block_rsv, int min_factor)
2298c2ecf20Sopenharmony_ci{
2308c2ecf20Sopenharmony_ci	u64 num_bytes = 0;
2318c2ecf20Sopenharmony_ci	int ret = -ENOSPC;
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci	if (!block_rsv)
2348c2ecf20Sopenharmony_ci		return 0;
2358c2ecf20Sopenharmony_ci
2368c2ecf20Sopenharmony_ci	spin_lock(&block_rsv->lock);
2378c2ecf20Sopenharmony_ci	num_bytes = div_factor(block_rsv->size, min_factor);
2388c2ecf20Sopenharmony_ci	if (block_rsv->reserved >= num_bytes)
2398c2ecf20Sopenharmony_ci		ret = 0;
2408c2ecf20Sopenharmony_ci	spin_unlock(&block_rsv->lock);
2418c2ecf20Sopenharmony_ci
2428c2ecf20Sopenharmony_ci	return ret;
2438c2ecf20Sopenharmony_ci}
2448c2ecf20Sopenharmony_ci
2458c2ecf20Sopenharmony_ciint btrfs_block_rsv_refill(struct btrfs_root *root,
2468c2ecf20Sopenharmony_ci			   struct btrfs_block_rsv *block_rsv, u64 min_reserved,
2478c2ecf20Sopenharmony_ci			   enum btrfs_reserve_flush_enum flush)
2488c2ecf20Sopenharmony_ci{
2498c2ecf20Sopenharmony_ci	u64 num_bytes = 0;
2508c2ecf20Sopenharmony_ci	int ret = -ENOSPC;
2518c2ecf20Sopenharmony_ci
2528c2ecf20Sopenharmony_ci	if (!block_rsv)
2538c2ecf20Sopenharmony_ci		return 0;
2548c2ecf20Sopenharmony_ci
2558c2ecf20Sopenharmony_ci	spin_lock(&block_rsv->lock);
2568c2ecf20Sopenharmony_ci	num_bytes = min_reserved;
2578c2ecf20Sopenharmony_ci	if (block_rsv->reserved >= num_bytes)
2588c2ecf20Sopenharmony_ci		ret = 0;
2598c2ecf20Sopenharmony_ci	else
2608c2ecf20Sopenharmony_ci		num_bytes -= block_rsv->reserved;
2618c2ecf20Sopenharmony_ci	spin_unlock(&block_rsv->lock);
2628c2ecf20Sopenharmony_ci
2638c2ecf20Sopenharmony_ci	if (!ret)
2648c2ecf20Sopenharmony_ci		return 0;
2658c2ecf20Sopenharmony_ci
2668c2ecf20Sopenharmony_ci	ret = btrfs_reserve_metadata_bytes(root, block_rsv, num_bytes, flush);
2678c2ecf20Sopenharmony_ci	if (!ret) {
2688c2ecf20Sopenharmony_ci		btrfs_block_rsv_add_bytes(block_rsv, num_bytes, false);
2698c2ecf20Sopenharmony_ci		return 0;
2708c2ecf20Sopenharmony_ci	}
2718c2ecf20Sopenharmony_ci
2728c2ecf20Sopenharmony_ci	return ret;
2738c2ecf20Sopenharmony_ci}
2748c2ecf20Sopenharmony_ci
2758c2ecf20Sopenharmony_ciu64 btrfs_block_rsv_release(struct btrfs_fs_info *fs_info,
2768c2ecf20Sopenharmony_ci			    struct btrfs_block_rsv *block_rsv, u64 num_bytes,
2778c2ecf20Sopenharmony_ci			    u64 *qgroup_to_release)
2788c2ecf20Sopenharmony_ci{
2798c2ecf20Sopenharmony_ci	struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv;
2808c2ecf20Sopenharmony_ci	struct btrfs_block_rsv *delayed_rsv = &fs_info->delayed_refs_rsv;
2818c2ecf20Sopenharmony_ci	struct btrfs_block_rsv *target = NULL;
2828c2ecf20Sopenharmony_ci
2838c2ecf20Sopenharmony_ci	/*
2848c2ecf20Sopenharmony_ci	 * If we are the delayed_rsv then push to the global rsv, otherwise dump
2858c2ecf20Sopenharmony_ci	 * into the delayed rsv if it is not full.
2868c2ecf20Sopenharmony_ci	 */
2878c2ecf20Sopenharmony_ci	if (block_rsv == delayed_rsv)
2888c2ecf20Sopenharmony_ci		target = global_rsv;
2898c2ecf20Sopenharmony_ci	else if (block_rsv != global_rsv && !delayed_rsv->full)
2908c2ecf20Sopenharmony_ci		target = delayed_rsv;
2918c2ecf20Sopenharmony_ci
2928c2ecf20Sopenharmony_ci	if (target && block_rsv->space_info != target->space_info)
2938c2ecf20Sopenharmony_ci		target = NULL;
2948c2ecf20Sopenharmony_ci
2958c2ecf20Sopenharmony_ci	return block_rsv_release_bytes(fs_info, block_rsv, target, num_bytes,
2968c2ecf20Sopenharmony_ci				       qgroup_to_release);
2978c2ecf20Sopenharmony_ci}
2988c2ecf20Sopenharmony_ci
2998c2ecf20Sopenharmony_ciint btrfs_block_rsv_use_bytes(struct btrfs_block_rsv *block_rsv, u64 num_bytes)
3008c2ecf20Sopenharmony_ci{
3018c2ecf20Sopenharmony_ci	int ret = -ENOSPC;
3028c2ecf20Sopenharmony_ci
3038c2ecf20Sopenharmony_ci	spin_lock(&block_rsv->lock);
3048c2ecf20Sopenharmony_ci	if (block_rsv->reserved >= num_bytes) {
3058c2ecf20Sopenharmony_ci		block_rsv->reserved -= num_bytes;
3068c2ecf20Sopenharmony_ci		if (block_rsv->reserved < block_rsv->size)
3078c2ecf20Sopenharmony_ci			block_rsv->full = 0;
3088c2ecf20Sopenharmony_ci		ret = 0;
3098c2ecf20Sopenharmony_ci	}
3108c2ecf20Sopenharmony_ci	spin_unlock(&block_rsv->lock);
3118c2ecf20Sopenharmony_ci	return ret;
3128c2ecf20Sopenharmony_ci}
3138c2ecf20Sopenharmony_ci
3148c2ecf20Sopenharmony_civoid btrfs_block_rsv_add_bytes(struct btrfs_block_rsv *block_rsv,
3158c2ecf20Sopenharmony_ci			       u64 num_bytes, bool update_size)
3168c2ecf20Sopenharmony_ci{
3178c2ecf20Sopenharmony_ci	spin_lock(&block_rsv->lock);
3188c2ecf20Sopenharmony_ci	block_rsv->reserved += num_bytes;
3198c2ecf20Sopenharmony_ci	if (update_size)
3208c2ecf20Sopenharmony_ci		block_rsv->size += num_bytes;
3218c2ecf20Sopenharmony_ci	else if (block_rsv->reserved >= block_rsv->size)
3228c2ecf20Sopenharmony_ci		block_rsv->full = 1;
3238c2ecf20Sopenharmony_ci	spin_unlock(&block_rsv->lock);
3248c2ecf20Sopenharmony_ci}
3258c2ecf20Sopenharmony_ci
3268c2ecf20Sopenharmony_ciint btrfs_cond_migrate_bytes(struct btrfs_fs_info *fs_info,
3278c2ecf20Sopenharmony_ci			     struct btrfs_block_rsv *dest, u64 num_bytes,
3288c2ecf20Sopenharmony_ci			     int min_factor)
3298c2ecf20Sopenharmony_ci{
3308c2ecf20Sopenharmony_ci	struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv;
3318c2ecf20Sopenharmony_ci	u64 min_bytes;
3328c2ecf20Sopenharmony_ci
3338c2ecf20Sopenharmony_ci	if (global_rsv->space_info != dest->space_info)
3348c2ecf20Sopenharmony_ci		return -ENOSPC;
3358c2ecf20Sopenharmony_ci
3368c2ecf20Sopenharmony_ci	spin_lock(&global_rsv->lock);
3378c2ecf20Sopenharmony_ci	min_bytes = div_factor(global_rsv->size, min_factor);
3388c2ecf20Sopenharmony_ci	if (global_rsv->reserved < min_bytes + num_bytes) {
3398c2ecf20Sopenharmony_ci		spin_unlock(&global_rsv->lock);
3408c2ecf20Sopenharmony_ci		return -ENOSPC;
3418c2ecf20Sopenharmony_ci	}
3428c2ecf20Sopenharmony_ci	global_rsv->reserved -= num_bytes;
3438c2ecf20Sopenharmony_ci	if (global_rsv->reserved < global_rsv->size)
3448c2ecf20Sopenharmony_ci		global_rsv->full = 0;
3458c2ecf20Sopenharmony_ci	spin_unlock(&global_rsv->lock);
3468c2ecf20Sopenharmony_ci
3478c2ecf20Sopenharmony_ci	btrfs_block_rsv_add_bytes(dest, num_bytes, true);
3488c2ecf20Sopenharmony_ci	return 0;
3498c2ecf20Sopenharmony_ci}
3508c2ecf20Sopenharmony_ci
3518c2ecf20Sopenharmony_civoid btrfs_update_global_block_rsv(struct btrfs_fs_info *fs_info)
3528c2ecf20Sopenharmony_ci{
3538c2ecf20Sopenharmony_ci	struct btrfs_block_rsv *block_rsv = &fs_info->global_block_rsv;
3548c2ecf20Sopenharmony_ci	struct btrfs_space_info *sinfo = block_rsv->space_info;
3558c2ecf20Sopenharmony_ci	u64 num_bytes;
3568c2ecf20Sopenharmony_ci	unsigned min_items;
3578c2ecf20Sopenharmony_ci
3588c2ecf20Sopenharmony_ci	/*
3598c2ecf20Sopenharmony_ci	 * The global block rsv is based on the size of the extent tree, the
3608c2ecf20Sopenharmony_ci	 * checksum tree and the root tree.  If the fs is empty we want to set
3618c2ecf20Sopenharmony_ci	 * it to a minimal amount for safety.
3628c2ecf20Sopenharmony_ci	 */
3638c2ecf20Sopenharmony_ci	num_bytes = btrfs_root_used(&fs_info->extent_root->root_item) +
3648c2ecf20Sopenharmony_ci		btrfs_root_used(&fs_info->csum_root->root_item) +
3658c2ecf20Sopenharmony_ci		btrfs_root_used(&fs_info->tree_root->root_item);
3668c2ecf20Sopenharmony_ci
3678c2ecf20Sopenharmony_ci	/*
3688c2ecf20Sopenharmony_ci	 * We at a minimum are going to modify the csum root, the tree root, and
3698c2ecf20Sopenharmony_ci	 * the extent root.
3708c2ecf20Sopenharmony_ci	 */
3718c2ecf20Sopenharmony_ci	min_items = 3;
3728c2ecf20Sopenharmony_ci
3738c2ecf20Sopenharmony_ci	/*
3748c2ecf20Sopenharmony_ci	 * But we also want to reserve enough space so we can do the fallback
3758c2ecf20Sopenharmony_ci	 * global reserve for an unlink, which is an additional 5 items (see the
3768c2ecf20Sopenharmony_ci	 * comment in __unlink_start_trans for what we're modifying.)
3778c2ecf20Sopenharmony_ci	 *
3788c2ecf20Sopenharmony_ci	 * But we also need space for the delayed ref updates from the unlink,
3798c2ecf20Sopenharmony_ci	 * so its 10, 5 for the actual operation, and 5 for the delayed ref
3808c2ecf20Sopenharmony_ci	 * updates.
3818c2ecf20Sopenharmony_ci	 */
3828c2ecf20Sopenharmony_ci	min_items += 10;
3838c2ecf20Sopenharmony_ci
3848c2ecf20Sopenharmony_ci	num_bytes = max_t(u64, num_bytes,
3858c2ecf20Sopenharmony_ci			  btrfs_calc_insert_metadata_size(fs_info, min_items));
3868c2ecf20Sopenharmony_ci
3878c2ecf20Sopenharmony_ci	spin_lock(&sinfo->lock);
3888c2ecf20Sopenharmony_ci	spin_lock(&block_rsv->lock);
3898c2ecf20Sopenharmony_ci
3908c2ecf20Sopenharmony_ci	block_rsv->size = min_t(u64, num_bytes, SZ_512M);
3918c2ecf20Sopenharmony_ci
3928c2ecf20Sopenharmony_ci	if (block_rsv->reserved < block_rsv->size) {
3938c2ecf20Sopenharmony_ci		num_bytes = block_rsv->size - block_rsv->reserved;
3948c2ecf20Sopenharmony_ci		btrfs_space_info_update_bytes_may_use(fs_info, sinfo,
3958c2ecf20Sopenharmony_ci						      num_bytes);
3968c2ecf20Sopenharmony_ci		block_rsv->reserved = block_rsv->size;
3978c2ecf20Sopenharmony_ci	} else if (block_rsv->reserved > block_rsv->size) {
3988c2ecf20Sopenharmony_ci		num_bytes = block_rsv->reserved - block_rsv->size;
3998c2ecf20Sopenharmony_ci		btrfs_space_info_update_bytes_may_use(fs_info, sinfo,
4008c2ecf20Sopenharmony_ci						      -num_bytes);
4018c2ecf20Sopenharmony_ci		block_rsv->reserved = block_rsv->size;
4028c2ecf20Sopenharmony_ci		btrfs_try_granting_tickets(fs_info, sinfo);
4038c2ecf20Sopenharmony_ci	}
4048c2ecf20Sopenharmony_ci
4058c2ecf20Sopenharmony_ci	if (block_rsv->reserved == block_rsv->size)
4068c2ecf20Sopenharmony_ci		block_rsv->full = 1;
4078c2ecf20Sopenharmony_ci	else
4088c2ecf20Sopenharmony_ci		block_rsv->full = 0;
4098c2ecf20Sopenharmony_ci
4108c2ecf20Sopenharmony_ci	if (block_rsv->size >= sinfo->total_bytes)
4118c2ecf20Sopenharmony_ci		sinfo->force_alloc = CHUNK_ALLOC_FORCE;
4128c2ecf20Sopenharmony_ci	spin_unlock(&block_rsv->lock);
4138c2ecf20Sopenharmony_ci	spin_unlock(&sinfo->lock);
4148c2ecf20Sopenharmony_ci}
4158c2ecf20Sopenharmony_ci
4168c2ecf20Sopenharmony_civoid btrfs_init_global_block_rsv(struct btrfs_fs_info *fs_info)
4178c2ecf20Sopenharmony_ci{
4188c2ecf20Sopenharmony_ci	struct btrfs_space_info *space_info;
4198c2ecf20Sopenharmony_ci
4208c2ecf20Sopenharmony_ci	space_info = btrfs_find_space_info(fs_info, BTRFS_BLOCK_GROUP_SYSTEM);
4218c2ecf20Sopenharmony_ci	fs_info->chunk_block_rsv.space_info = space_info;
4228c2ecf20Sopenharmony_ci
4238c2ecf20Sopenharmony_ci	space_info = btrfs_find_space_info(fs_info, BTRFS_BLOCK_GROUP_METADATA);
4248c2ecf20Sopenharmony_ci	fs_info->global_block_rsv.space_info = space_info;
4258c2ecf20Sopenharmony_ci	fs_info->trans_block_rsv.space_info = space_info;
4268c2ecf20Sopenharmony_ci	fs_info->empty_block_rsv.space_info = space_info;
4278c2ecf20Sopenharmony_ci	fs_info->delayed_block_rsv.space_info = space_info;
4288c2ecf20Sopenharmony_ci	fs_info->delayed_refs_rsv.space_info = space_info;
4298c2ecf20Sopenharmony_ci
4308c2ecf20Sopenharmony_ci	fs_info->extent_root->block_rsv = &fs_info->delayed_refs_rsv;
4318c2ecf20Sopenharmony_ci	fs_info->csum_root->block_rsv = &fs_info->delayed_refs_rsv;
4328c2ecf20Sopenharmony_ci	fs_info->dev_root->block_rsv = &fs_info->global_block_rsv;
4338c2ecf20Sopenharmony_ci	fs_info->tree_root->block_rsv = &fs_info->global_block_rsv;
4348c2ecf20Sopenharmony_ci	if (fs_info->quota_root)
4358c2ecf20Sopenharmony_ci		fs_info->quota_root->block_rsv = &fs_info->global_block_rsv;
4368c2ecf20Sopenharmony_ci	fs_info->chunk_root->block_rsv = &fs_info->chunk_block_rsv;
4378c2ecf20Sopenharmony_ci
4388c2ecf20Sopenharmony_ci	btrfs_update_global_block_rsv(fs_info);
4398c2ecf20Sopenharmony_ci}
4408c2ecf20Sopenharmony_ci
4418c2ecf20Sopenharmony_civoid btrfs_release_global_block_rsv(struct btrfs_fs_info *fs_info)
4428c2ecf20Sopenharmony_ci{
4438c2ecf20Sopenharmony_ci	btrfs_block_rsv_release(fs_info, &fs_info->global_block_rsv, (u64)-1,
4448c2ecf20Sopenharmony_ci				NULL);
4458c2ecf20Sopenharmony_ci	WARN_ON(fs_info->trans_block_rsv.size > 0);
4468c2ecf20Sopenharmony_ci	WARN_ON(fs_info->trans_block_rsv.reserved > 0);
4478c2ecf20Sopenharmony_ci	WARN_ON(fs_info->chunk_block_rsv.size > 0);
4488c2ecf20Sopenharmony_ci	WARN_ON(fs_info->chunk_block_rsv.reserved > 0);
4498c2ecf20Sopenharmony_ci	WARN_ON(fs_info->delayed_block_rsv.size > 0);
4508c2ecf20Sopenharmony_ci	WARN_ON(fs_info->delayed_block_rsv.reserved > 0);
4518c2ecf20Sopenharmony_ci	WARN_ON(fs_info->delayed_refs_rsv.reserved > 0);
4528c2ecf20Sopenharmony_ci	WARN_ON(fs_info->delayed_refs_rsv.size > 0);
4538c2ecf20Sopenharmony_ci}
4548c2ecf20Sopenharmony_ci
4558c2ecf20Sopenharmony_cistatic struct btrfs_block_rsv *get_block_rsv(
4568c2ecf20Sopenharmony_ci					const struct btrfs_trans_handle *trans,
4578c2ecf20Sopenharmony_ci					const struct btrfs_root *root)
4588c2ecf20Sopenharmony_ci{
4598c2ecf20Sopenharmony_ci	struct btrfs_fs_info *fs_info = root->fs_info;
4608c2ecf20Sopenharmony_ci	struct btrfs_block_rsv *block_rsv = NULL;
4618c2ecf20Sopenharmony_ci
4628c2ecf20Sopenharmony_ci	if (test_bit(BTRFS_ROOT_SHAREABLE, &root->state) ||
4638c2ecf20Sopenharmony_ci	    (root == fs_info->csum_root && trans->adding_csums) ||
4648c2ecf20Sopenharmony_ci	    (root == fs_info->uuid_root))
4658c2ecf20Sopenharmony_ci		block_rsv = trans->block_rsv;
4668c2ecf20Sopenharmony_ci
4678c2ecf20Sopenharmony_ci	if (!block_rsv)
4688c2ecf20Sopenharmony_ci		block_rsv = root->block_rsv;
4698c2ecf20Sopenharmony_ci
4708c2ecf20Sopenharmony_ci	if (!block_rsv)
4718c2ecf20Sopenharmony_ci		block_rsv = &fs_info->empty_block_rsv;
4728c2ecf20Sopenharmony_ci
4738c2ecf20Sopenharmony_ci	return block_rsv;
4748c2ecf20Sopenharmony_ci}
4758c2ecf20Sopenharmony_ci
4768c2ecf20Sopenharmony_cistruct btrfs_block_rsv *btrfs_use_block_rsv(struct btrfs_trans_handle *trans,
4778c2ecf20Sopenharmony_ci					    struct btrfs_root *root,
4788c2ecf20Sopenharmony_ci					    u32 blocksize)
4798c2ecf20Sopenharmony_ci{
4808c2ecf20Sopenharmony_ci	struct btrfs_fs_info *fs_info = root->fs_info;
4818c2ecf20Sopenharmony_ci	struct btrfs_block_rsv *block_rsv;
4828c2ecf20Sopenharmony_ci	struct btrfs_block_rsv *global_rsv = &fs_info->global_block_rsv;
4838c2ecf20Sopenharmony_ci	int ret;
4848c2ecf20Sopenharmony_ci	bool global_updated = false;
4858c2ecf20Sopenharmony_ci
4868c2ecf20Sopenharmony_ci	block_rsv = get_block_rsv(trans, root);
4878c2ecf20Sopenharmony_ci
4888c2ecf20Sopenharmony_ci	if (unlikely(block_rsv->size == 0))
4898c2ecf20Sopenharmony_ci		goto try_reserve;
4908c2ecf20Sopenharmony_ciagain:
4918c2ecf20Sopenharmony_ci	ret = btrfs_block_rsv_use_bytes(block_rsv, blocksize);
4928c2ecf20Sopenharmony_ci	if (!ret)
4938c2ecf20Sopenharmony_ci		return block_rsv;
4948c2ecf20Sopenharmony_ci
4958c2ecf20Sopenharmony_ci	if (block_rsv->failfast)
4968c2ecf20Sopenharmony_ci		return ERR_PTR(ret);
4978c2ecf20Sopenharmony_ci
4988c2ecf20Sopenharmony_ci	if (block_rsv->type == BTRFS_BLOCK_RSV_GLOBAL && !global_updated) {
4998c2ecf20Sopenharmony_ci		global_updated = true;
5008c2ecf20Sopenharmony_ci		btrfs_update_global_block_rsv(fs_info);
5018c2ecf20Sopenharmony_ci		goto again;
5028c2ecf20Sopenharmony_ci	}
5038c2ecf20Sopenharmony_ci
5048c2ecf20Sopenharmony_ci	/*
5058c2ecf20Sopenharmony_ci	 * The global reserve still exists to save us from ourselves, so don't
5068c2ecf20Sopenharmony_ci	 * warn_on if we are short on our delayed refs reserve.
5078c2ecf20Sopenharmony_ci	 */
5088c2ecf20Sopenharmony_ci	if (block_rsv->type != BTRFS_BLOCK_RSV_DELREFS &&
5098c2ecf20Sopenharmony_ci	    btrfs_test_opt(fs_info, ENOSPC_DEBUG)) {
5108c2ecf20Sopenharmony_ci		static DEFINE_RATELIMIT_STATE(_rs,
5118c2ecf20Sopenharmony_ci				DEFAULT_RATELIMIT_INTERVAL * 10,
5128c2ecf20Sopenharmony_ci				/*DEFAULT_RATELIMIT_BURST*/ 1);
5138c2ecf20Sopenharmony_ci		if (__ratelimit(&_rs))
5148c2ecf20Sopenharmony_ci			WARN(1, KERN_DEBUG
5158c2ecf20Sopenharmony_ci				"BTRFS: block rsv %d returned %d\n",
5168c2ecf20Sopenharmony_ci				block_rsv->type, ret);
5178c2ecf20Sopenharmony_ci	}
5188c2ecf20Sopenharmony_citry_reserve:
5198c2ecf20Sopenharmony_ci	ret = btrfs_reserve_metadata_bytes(root, block_rsv, blocksize,
5208c2ecf20Sopenharmony_ci					   BTRFS_RESERVE_NO_FLUSH);
5218c2ecf20Sopenharmony_ci	if (!ret)
5228c2ecf20Sopenharmony_ci		return block_rsv;
5238c2ecf20Sopenharmony_ci	/*
5248c2ecf20Sopenharmony_ci	 * If we couldn't reserve metadata bytes try and use some from
5258c2ecf20Sopenharmony_ci	 * the global reserve if its space type is the same as the global
5268c2ecf20Sopenharmony_ci	 * reservation.
5278c2ecf20Sopenharmony_ci	 */
5288c2ecf20Sopenharmony_ci	if (block_rsv->type != BTRFS_BLOCK_RSV_GLOBAL &&
5298c2ecf20Sopenharmony_ci	    block_rsv->space_info == global_rsv->space_info) {
5308c2ecf20Sopenharmony_ci		ret = btrfs_block_rsv_use_bytes(global_rsv, blocksize);
5318c2ecf20Sopenharmony_ci		if (!ret)
5328c2ecf20Sopenharmony_ci			return global_rsv;
5338c2ecf20Sopenharmony_ci	}
5348c2ecf20Sopenharmony_ci	return ERR_PTR(ret);
5358c2ecf20Sopenharmony_ci}
536