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