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