18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (C) 2011 Fujitsu. All rights reserved. 48c2ecf20Sopenharmony_ci * Written by Miao Xie <miaox@cn.fujitsu.com> 58c2ecf20Sopenharmony_ci */ 68c2ecf20Sopenharmony_ci 78c2ecf20Sopenharmony_ci#include <linux/slab.h> 88c2ecf20Sopenharmony_ci#include <linux/iversion.h> 98c2ecf20Sopenharmony_ci#include <linux/sched/mm.h> 108c2ecf20Sopenharmony_ci#include "misc.h" 118c2ecf20Sopenharmony_ci#include "delayed-inode.h" 128c2ecf20Sopenharmony_ci#include "disk-io.h" 138c2ecf20Sopenharmony_ci#include "transaction.h" 148c2ecf20Sopenharmony_ci#include "ctree.h" 158c2ecf20Sopenharmony_ci#include "qgroup.h" 168c2ecf20Sopenharmony_ci#include "locking.h" 178c2ecf20Sopenharmony_ci 188c2ecf20Sopenharmony_ci#define BTRFS_DELAYED_WRITEBACK 512 198c2ecf20Sopenharmony_ci#define BTRFS_DELAYED_BACKGROUND 128 208c2ecf20Sopenharmony_ci#define BTRFS_DELAYED_BATCH 16 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_cistatic struct kmem_cache *delayed_node_cache; 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_ciint __init btrfs_delayed_inode_init(void) 258c2ecf20Sopenharmony_ci{ 268c2ecf20Sopenharmony_ci delayed_node_cache = kmem_cache_create("btrfs_delayed_node", 278c2ecf20Sopenharmony_ci sizeof(struct btrfs_delayed_node), 288c2ecf20Sopenharmony_ci 0, 298c2ecf20Sopenharmony_ci SLAB_MEM_SPREAD, 308c2ecf20Sopenharmony_ci NULL); 318c2ecf20Sopenharmony_ci if (!delayed_node_cache) 328c2ecf20Sopenharmony_ci return -ENOMEM; 338c2ecf20Sopenharmony_ci return 0; 348c2ecf20Sopenharmony_ci} 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_civoid __cold btrfs_delayed_inode_exit(void) 378c2ecf20Sopenharmony_ci{ 388c2ecf20Sopenharmony_ci kmem_cache_destroy(delayed_node_cache); 398c2ecf20Sopenharmony_ci} 408c2ecf20Sopenharmony_ci 418c2ecf20Sopenharmony_cistatic inline void btrfs_init_delayed_node( 428c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_node, 438c2ecf20Sopenharmony_ci struct btrfs_root *root, u64 inode_id) 448c2ecf20Sopenharmony_ci{ 458c2ecf20Sopenharmony_ci delayed_node->root = root; 468c2ecf20Sopenharmony_ci delayed_node->inode_id = inode_id; 478c2ecf20Sopenharmony_ci refcount_set(&delayed_node->refs, 0); 488c2ecf20Sopenharmony_ci delayed_node->ins_root = RB_ROOT_CACHED; 498c2ecf20Sopenharmony_ci delayed_node->del_root = RB_ROOT_CACHED; 508c2ecf20Sopenharmony_ci mutex_init(&delayed_node->mutex); 518c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&delayed_node->n_list); 528c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&delayed_node->p_list); 538c2ecf20Sopenharmony_ci} 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_cistatic inline int btrfs_is_continuous_delayed_item( 568c2ecf20Sopenharmony_ci struct btrfs_delayed_item *item1, 578c2ecf20Sopenharmony_ci struct btrfs_delayed_item *item2) 588c2ecf20Sopenharmony_ci{ 598c2ecf20Sopenharmony_ci if (item1->key.type == BTRFS_DIR_INDEX_KEY && 608c2ecf20Sopenharmony_ci item1->key.objectid == item2->key.objectid && 618c2ecf20Sopenharmony_ci item1->key.type == item2->key.type && 628c2ecf20Sopenharmony_ci item1->key.offset + 1 == item2->key.offset) 638c2ecf20Sopenharmony_ci return 1; 648c2ecf20Sopenharmony_ci return 0; 658c2ecf20Sopenharmony_ci} 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_cistatic struct btrfs_delayed_node *btrfs_get_delayed_node( 688c2ecf20Sopenharmony_ci struct btrfs_inode *btrfs_inode) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci struct btrfs_root *root = btrfs_inode->root; 718c2ecf20Sopenharmony_ci u64 ino = btrfs_ino(btrfs_inode); 728c2ecf20Sopenharmony_ci struct btrfs_delayed_node *node; 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci node = READ_ONCE(btrfs_inode->delayed_node); 758c2ecf20Sopenharmony_ci if (node) { 768c2ecf20Sopenharmony_ci refcount_inc(&node->refs); 778c2ecf20Sopenharmony_ci return node; 788c2ecf20Sopenharmony_ci } 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci spin_lock(&root->inode_lock); 818c2ecf20Sopenharmony_ci node = radix_tree_lookup(&root->delayed_nodes_tree, ino); 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci if (node) { 848c2ecf20Sopenharmony_ci if (btrfs_inode->delayed_node) { 858c2ecf20Sopenharmony_ci refcount_inc(&node->refs); /* can be accessed */ 868c2ecf20Sopenharmony_ci BUG_ON(btrfs_inode->delayed_node != node); 878c2ecf20Sopenharmony_ci spin_unlock(&root->inode_lock); 888c2ecf20Sopenharmony_ci return node; 898c2ecf20Sopenharmony_ci } 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci /* 928c2ecf20Sopenharmony_ci * It's possible that we're racing into the middle of removing 938c2ecf20Sopenharmony_ci * this node from the radix tree. In this case, the refcount 948c2ecf20Sopenharmony_ci * was zero and it should never go back to one. Just return 958c2ecf20Sopenharmony_ci * NULL like it was never in the radix at all; our release 968c2ecf20Sopenharmony_ci * function is in the process of removing it. 978c2ecf20Sopenharmony_ci * 988c2ecf20Sopenharmony_ci * Some implementations of refcount_inc refuse to bump the 998c2ecf20Sopenharmony_ci * refcount once it has hit zero. If we don't do this dance 1008c2ecf20Sopenharmony_ci * here, refcount_inc() may decide to just WARN_ONCE() instead 1018c2ecf20Sopenharmony_ci * of actually bumping the refcount. 1028c2ecf20Sopenharmony_ci * 1038c2ecf20Sopenharmony_ci * If this node is properly in the radix, we want to bump the 1048c2ecf20Sopenharmony_ci * refcount twice, once for the inode and once for this get 1058c2ecf20Sopenharmony_ci * operation. 1068c2ecf20Sopenharmony_ci */ 1078c2ecf20Sopenharmony_ci if (refcount_inc_not_zero(&node->refs)) { 1088c2ecf20Sopenharmony_ci refcount_inc(&node->refs); 1098c2ecf20Sopenharmony_ci btrfs_inode->delayed_node = node; 1108c2ecf20Sopenharmony_ci } else { 1118c2ecf20Sopenharmony_ci node = NULL; 1128c2ecf20Sopenharmony_ci } 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci spin_unlock(&root->inode_lock); 1158c2ecf20Sopenharmony_ci return node; 1168c2ecf20Sopenharmony_ci } 1178c2ecf20Sopenharmony_ci spin_unlock(&root->inode_lock); 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci return NULL; 1208c2ecf20Sopenharmony_ci} 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_ci/* Will return either the node or PTR_ERR(-ENOMEM) */ 1238c2ecf20Sopenharmony_cistatic struct btrfs_delayed_node *btrfs_get_or_create_delayed_node( 1248c2ecf20Sopenharmony_ci struct btrfs_inode *btrfs_inode) 1258c2ecf20Sopenharmony_ci{ 1268c2ecf20Sopenharmony_ci struct btrfs_delayed_node *node; 1278c2ecf20Sopenharmony_ci struct btrfs_root *root = btrfs_inode->root; 1288c2ecf20Sopenharmony_ci u64 ino = btrfs_ino(btrfs_inode); 1298c2ecf20Sopenharmony_ci int ret; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ciagain: 1328c2ecf20Sopenharmony_ci node = btrfs_get_delayed_node(btrfs_inode); 1338c2ecf20Sopenharmony_ci if (node) 1348c2ecf20Sopenharmony_ci return node; 1358c2ecf20Sopenharmony_ci 1368c2ecf20Sopenharmony_ci node = kmem_cache_zalloc(delayed_node_cache, GFP_NOFS); 1378c2ecf20Sopenharmony_ci if (!node) 1388c2ecf20Sopenharmony_ci return ERR_PTR(-ENOMEM); 1398c2ecf20Sopenharmony_ci btrfs_init_delayed_node(node, root, ino); 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci /* cached in the btrfs inode and can be accessed */ 1428c2ecf20Sopenharmony_ci refcount_set(&node->refs, 2); 1438c2ecf20Sopenharmony_ci 1448c2ecf20Sopenharmony_ci ret = radix_tree_preload(GFP_NOFS); 1458c2ecf20Sopenharmony_ci if (ret) { 1468c2ecf20Sopenharmony_ci kmem_cache_free(delayed_node_cache, node); 1478c2ecf20Sopenharmony_ci return ERR_PTR(ret); 1488c2ecf20Sopenharmony_ci } 1498c2ecf20Sopenharmony_ci 1508c2ecf20Sopenharmony_ci spin_lock(&root->inode_lock); 1518c2ecf20Sopenharmony_ci ret = radix_tree_insert(&root->delayed_nodes_tree, ino, node); 1528c2ecf20Sopenharmony_ci if (ret == -EEXIST) { 1538c2ecf20Sopenharmony_ci spin_unlock(&root->inode_lock); 1548c2ecf20Sopenharmony_ci kmem_cache_free(delayed_node_cache, node); 1558c2ecf20Sopenharmony_ci radix_tree_preload_end(); 1568c2ecf20Sopenharmony_ci goto again; 1578c2ecf20Sopenharmony_ci } 1588c2ecf20Sopenharmony_ci btrfs_inode->delayed_node = node; 1598c2ecf20Sopenharmony_ci spin_unlock(&root->inode_lock); 1608c2ecf20Sopenharmony_ci radix_tree_preload_end(); 1618c2ecf20Sopenharmony_ci 1628c2ecf20Sopenharmony_ci return node; 1638c2ecf20Sopenharmony_ci} 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci/* 1668c2ecf20Sopenharmony_ci * Call it when holding delayed_node->mutex 1678c2ecf20Sopenharmony_ci * 1688c2ecf20Sopenharmony_ci * If mod = 1, add this node into the prepared list. 1698c2ecf20Sopenharmony_ci */ 1708c2ecf20Sopenharmony_cistatic void btrfs_queue_delayed_node(struct btrfs_delayed_root *root, 1718c2ecf20Sopenharmony_ci struct btrfs_delayed_node *node, 1728c2ecf20Sopenharmony_ci int mod) 1738c2ecf20Sopenharmony_ci{ 1748c2ecf20Sopenharmony_ci spin_lock(&root->lock); 1758c2ecf20Sopenharmony_ci if (test_bit(BTRFS_DELAYED_NODE_IN_LIST, &node->flags)) { 1768c2ecf20Sopenharmony_ci if (!list_empty(&node->p_list)) 1778c2ecf20Sopenharmony_ci list_move_tail(&node->p_list, &root->prepare_list); 1788c2ecf20Sopenharmony_ci else if (mod) 1798c2ecf20Sopenharmony_ci list_add_tail(&node->p_list, &root->prepare_list); 1808c2ecf20Sopenharmony_ci } else { 1818c2ecf20Sopenharmony_ci list_add_tail(&node->n_list, &root->node_list); 1828c2ecf20Sopenharmony_ci list_add_tail(&node->p_list, &root->prepare_list); 1838c2ecf20Sopenharmony_ci refcount_inc(&node->refs); /* inserted into list */ 1848c2ecf20Sopenharmony_ci root->nodes++; 1858c2ecf20Sopenharmony_ci set_bit(BTRFS_DELAYED_NODE_IN_LIST, &node->flags); 1868c2ecf20Sopenharmony_ci } 1878c2ecf20Sopenharmony_ci spin_unlock(&root->lock); 1888c2ecf20Sopenharmony_ci} 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci/* Call it when holding delayed_node->mutex */ 1918c2ecf20Sopenharmony_cistatic void btrfs_dequeue_delayed_node(struct btrfs_delayed_root *root, 1928c2ecf20Sopenharmony_ci struct btrfs_delayed_node *node) 1938c2ecf20Sopenharmony_ci{ 1948c2ecf20Sopenharmony_ci spin_lock(&root->lock); 1958c2ecf20Sopenharmony_ci if (test_bit(BTRFS_DELAYED_NODE_IN_LIST, &node->flags)) { 1968c2ecf20Sopenharmony_ci root->nodes--; 1978c2ecf20Sopenharmony_ci refcount_dec(&node->refs); /* not in the list */ 1988c2ecf20Sopenharmony_ci list_del_init(&node->n_list); 1998c2ecf20Sopenharmony_ci if (!list_empty(&node->p_list)) 2008c2ecf20Sopenharmony_ci list_del_init(&node->p_list); 2018c2ecf20Sopenharmony_ci clear_bit(BTRFS_DELAYED_NODE_IN_LIST, &node->flags); 2028c2ecf20Sopenharmony_ci } 2038c2ecf20Sopenharmony_ci spin_unlock(&root->lock); 2048c2ecf20Sopenharmony_ci} 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_cistatic struct btrfs_delayed_node *btrfs_first_delayed_node( 2078c2ecf20Sopenharmony_ci struct btrfs_delayed_root *delayed_root) 2088c2ecf20Sopenharmony_ci{ 2098c2ecf20Sopenharmony_ci struct list_head *p; 2108c2ecf20Sopenharmony_ci struct btrfs_delayed_node *node = NULL; 2118c2ecf20Sopenharmony_ci 2128c2ecf20Sopenharmony_ci spin_lock(&delayed_root->lock); 2138c2ecf20Sopenharmony_ci if (list_empty(&delayed_root->node_list)) 2148c2ecf20Sopenharmony_ci goto out; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci p = delayed_root->node_list.next; 2178c2ecf20Sopenharmony_ci node = list_entry(p, struct btrfs_delayed_node, n_list); 2188c2ecf20Sopenharmony_ci refcount_inc(&node->refs); 2198c2ecf20Sopenharmony_ciout: 2208c2ecf20Sopenharmony_ci spin_unlock(&delayed_root->lock); 2218c2ecf20Sopenharmony_ci 2228c2ecf20Sopenharmony_ci return node; 2238c2ecf20Sopenharmony_ci} 2248c2ecf20Sopenharmony_ci 2258c2ecf20Sopenharmony_cistatic struct btrfs_delayed_node *btrfs_next_delayed_node( 2268c2ecf20Sopenharmony_ci struct btrfs_delayed_node *node) 2278c2ecf20Sopenharmony_ci{ 2288c2ecf20Sopenharmony_ci struct btrfs_delayed_root *delayed_root; 2298c2ecf20Sopenharmony_ci struct list_head *p; 2308c2ecf20Sopenharmony_ci struct btrfs_delayed_node *next = NULL; 2318c2ecf20Sopenharmony_ci 2328c2ecf20Sopenharmony_ci delayed_root = node->root->fs_info->delayed_root; 2338c2ecf20Sopenharmony_ci spin_lock(&delayed_root->lock); 2348c2ecf20Sopenharmony_ci if (!test_bit(BTRFS_DELAYED_NODE_IN_LIST, &node->flags)) { 2358c2ecf20Sopenharmony_ci /* not in the list */ 2368c2ecf20Sopenharmony_ci if (list_empty(&delayed_root->node_list)) 2378c2ecf20Sopenharmony_ci goto out; 2388c2ecf20Sopenharmony_ci p = delayed_root->node_list.next; 2398c2ecf20Sopenharmony_ci } else if (list_is_last(&node->n_list, &delayed_root->node_list)) 2408c2ecf20Sopenharmony_ci goto out; 2418c2ecf20Sopenharmony_ci else 2428c2ecf20Sopenharmony_ci p = node->n_list.next; 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_ci next = list_entry(p, struct btrfs_delayed_node, n_list); 2458c2ecf20Sopenharmony_ci refcount_inc(&next->refs); 2468c2ecf20Sopenharmony_ciout: 2478c2ecf20Sopenharmony_ci spin_unlock(&delayed_root->lock); 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci return next; 2508c2ecf20Sopenharmony_ci} 2518c2ecf20Sopenharmony_ci 2528c2ecf20Sopenharmony_cistatic void __btrfs_release_delayed_node( 2538c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_node, 2548c2ecf20Sopenharmony_ci int mod) 2558c2ecf20Sopenharmony_ci{ 2568c2ecf20Sopenharmony_ci struct btrfs_delayed_root *delayed_root; 2578c2ecf20Sopenharmony_ci 2588c2ecf20Sopenharmony_ci if (!delayed_node) 2598c2ecf20Sopenharmony_ci return; 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci delayed_root = delayed_node->root->fs_info->delayed_root; 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_ci mutex_lock(&delayed_node->mutex); 2648c2ecf20Sopenharmony_ci if (delayed_node->count) 2658c2ecf20Sopenharmony_ci btrfs_queue_delayed_node(delayed_root, delayed_node, mod); 2668c2ecf20Sopenharmony_ci else 2678c2ecf20Sopenharmony_ci btrfs_dequeue_delayed_node(delayed_root, delayed_node); 2688c2ecf20Sopenharmony_ci mutex_unlock(&delayed_node->mutex); 2698c2ecf20Sopenharmony_ci 2708c2ecf20Sopenharmony_ci if (refcount_dec_and_test(&delayed_node->refs)) { 2718c2ecf20Sopenharmony_ci struct btrfs_root *root = delayed_node->root; 2728c2ecf20Sopenharmony_ci 2738c2ecf20Sopenharmony_ci spin_lock(&root->inode_lock); 2748c2ecf20Sopenharmony_ci /* 2758c2ecf20Sopenharmony_ci * Once our refcount goes to zero, nobody is allowed to bump it 2768c2ecf20Sopenharmony_ci * back up. We can delete it now. 2778c2ecf20Sopenharmony_ci */ 2788c2ecf20Sopenharmony_ci ASSERT(refcount_read(&delayed_node->refs) == 0); 2798c2ecf20Sopenharmony_ci radix_tree_delete(&root->delayed_nodes_tree, 2808c2ecf20Sopenharmony_ci delayed_node->inode_id); 2818c2ecf20Sopenharmony_ci spin_unlock(&root->inode_lock); 2828c2ecf20Sopenharmony_ci kmem_cache_free(delayed_node_cache, delayed_node); 2838c2ecf20Sopenharmony_ci } 2848c2ecf20Sopenharmony_ci} 2858c2ecf20Sopenharmony_ci 2868c2ecf20Sopenharmony_cistatic inline void btrfs_release_delayed_node(struct btrfs_delayed_node *node) 2878c2ecf20Sopenharmony_ci{ 2888c2ecf20Sopenharmony_ci __btrfs_release_delayed_node(node, 0); 2898c2ecf20Sopenharmony_ci} 2908c2ecf20Sopenharmony_ci 2918c2ecf20Sopenharmony_cistatic struct btrfs_delayed_node *btrfs_first_prepared_delayed_node( 2928c2ecf20Sopenharmony_ci struct btrfs_delayed_root *delayed_root) 2938c2ecf20Sopenharmony_ci{ 2948c2ecf20Sopenharmony_ci struct list_head *p; 2958c2ecf20Sopenharmony_ci struct btrfs_delayed_node *node = NULL; 2968c2ecf20Sopenharmony_ci 2978c2ecf20Sopenharmony_ci spin_lock(&delayed_root->lock); 2988c2ecf20Sopenharmony_ci if (list_empty(&delayed_root->prepare_list)) 2998c2ecf20Sopenharmony_ci goto out; 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci p = delayed_root->prepare_list.next; 3028c2ecf20Sopenharmony_ci list_del_init(p); 3038c2ecf20Sopenharmony_ci node = list_entry(p, struct btrfs_delayed_node, p_list); 3048c2ecf20Sopenharmony_ci refcount_inc(&node->refs); 3058c2ecf20Sopenharmony_ciout: 3068c2ecf20Sopenharmony_ci spin_unlock(&delayed_root->lock); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci return node; 3098c2ecf20Sopenharmony_ci} 3108c2ecf20Sopenharmony_ci 3118c2ecf20Sopenharmony_cistatic inline void btrfs_release_prepared_delayed_node( 3128c2ecf20Sopenharmony_ci struct btrfs_delayed_node *node) 3138c2ecf20Sopenharmony_ci{ 3148c2ecf20Sopenharmony_ci __btrfs_release_delayed_node(node, 1); 3158c2ecf20Sopenharmony_ci} 3168c2ecf20Sopenharmony_ci 3178c2ecf20Sopenharmony_cistatic struct btrfs_delayed_item *btrfs_alloc_delayed_item(u32 data_len) 3188c2ecf20Sopenharmony_ci{ 3198c2ecf20Sopenharmony_ci struct btrfs_delayed_item *item; 3208c2ecf20Sopenharmony_ci item = kmalloc(sizeof(*item) + data_len, GFP_NOFS); 3218c2ecf20Sopenharmony_ci if (item) { 3228c2ecf20Sopenharmony_ci item->data_len = data_len; 3238c2ecf20Sopenharmony_ci item->ins_or_del = 0; 3248c2ecf20Sopenharmony_ci item->bytes_reserved = 0; 3258c2ecf20Sopenharmony_ci item->delayed_node = NULL; 3268c2ecf20Sopenharmony_ci refcount_set(&item->refs, 1); 3278c2ecf20Sopenharmony_ci } 3288c2ecf20Sopenharmony_ci return item; 3298c2ecf20Sopenharmony_ci} 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci/* 3328c2ecf20Sopenharmony_ci * __btrfs_lookup_delayed_item - look up the delayed item by key 3338c2ecf20Sopenharmony_ci * @delayed_node: pointer to the delayed node 3348c2ecf20Sopenharmony_ci * @key: the key to look up 3358c2ecf20Sopenharmony_ci * @prev: used to store the prev item if the right item isn't found 3368c2ecf20Sopenharmony_ci * @next: used to store the next item if the right item isn't found 3378c2ecf20Sopenharmony_ci * 3388c2ecf20Sopenharmony_ci * Note: if we don't find the right item, we will return the prev item and 3398c2ecf20Sopenharmony_ci * the next item. 3408c2ecf20Sopenharmony_ci */ 3418c2ecf20Sopenharmony_cistatic struct btrfs_delayed_item *__btrfs_lookup_delayed_item( 3428c2ecf20Sopenharmony_ci struct rb_root *root, 3438c2ecf20Sopenharmony_ci struct btrfs_key *key, 3448c2ecf20Sopenharmony_ci struct btrfs_delayed_item **prev, 3458c2ecf20Sopenharmony_ci struct btrfs_delayed_item **next) 3468c2ecf20Sopenharmony_ci{ 3478c2ecf20Sopenharmony_ci struct rb_node *node, *prev_node = NULL; 3488c2ecf20Sopenharmony_ci struct btrfs_delayed_item *delayed_item = NULL; 3498c2ecf20Sopenharmony_ci int ret = 0; 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci node = root->rb_node; 3528c2ecf20Sopenharmony_ci 3538c2ecf20Sopenharmony_ci while (node) { 3548c2ecf20Sopenharmony_ci delayed_item = rb_entry(node, struct btrfs_delayed_item, 3558c2ecf20Sopenharmony_ci rb_node); 3568c2ecf20Sopenharmony_ci prev_node = node; 3578c2ecf20Sopenharmony_ci ret = btrfs_comp_cpu_keys(&delayed_item->key, key); 3588c2ecf20Sopenharmony_ci if (ret < 0) 3598c2ecf20Sopenharmony_ci node = node->rb_right; 3608c2ecf20Sopenharmony_ci else if (ret > 0) 3618c2ecf20Sopenharmony_ci node = node->rb_left; 3628c2ecf20Sopenharmony_ci else 3638c2ecf20Sopenharmony_ci return delayed_item; 3648c2ecf20Sopenharmony_ci } 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci if (prev) { 3678c2ecf20Sopenharmony_ci if (!prev_node) 3688c2ecf20Sopenharmony_ci *prev = NULL; 3698c2ecf20Sopenharmony_ci else if (ret < 0) 3708c2ecf20Sopenharmony_ci *prev = delayed_item; 3718c2ecf20Sopenharmony_ci else if ((node = rb_prev(prev_node)) != NULL) { 3728c2ecf20Sopenharmony_ci *prev = rb_entry(node, struct btrfs_delayed_item, 3738c2ecf20Sopenharmony_ci rb_node); 3748c2ecf20Sopenharmony_ci } else 3758c2ecf20Sopenharmony_ci *prev = NULL; 3768c2ecf20Sopenharmony_ci } 3778c2ecf20Sopenharmony_ci 3788c2ecf20Sopenharmony_ci if (next) { 3798c2ecf20Sopenharmony_ci if (!prev_node) 3808c2ecf20Sopenharmony_ci *next = NULL; 3818c2ecf20Sopenharmony_ci else if (ret > 0) 3828c2ecf20Sopenharmony_ci *next = delayed_item; 3838c2ecf20Sopenharmony_ci else if ((node = rb_next(prev_node)) != NULL) { 3848c2ecf20Sopenharmony_ci *next = rb_entry(node, struct btrfs_delayed_item, 3858c2ecf20Sopenharmony_ci rb_node); 3868c2ecf20Sopenharmony_ci } else 3878c2ecf20Sopenharmony_ci *next = NULL; 3888c2ecf20Sopenharmony_ci } 3898c2ecf20Sopenharmony_ci return NULL; 3908c2ecf20Sopenharmony_ci} 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_cistatic struct btrfs_delayed_item *__btrfs_lookup_delayed_insertion_item( 3938c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_node, 3948c2ecf20Sopenharmony_ci struct btrfs_key *key) 3958c2ecf20Sopenharmony_ci{ 3968c2ecf20Sopenharmony_ci return __btrfs_lookup_delayed_item(&delayed_node->ins_root.rb_root, key, 3978c2ecf20Sopenharmony_ci NULL, NULL); 3988c2ecf20Sopenharmony_ci} 3998c2ecf20Sopenharmony_ci 4008c2ecf20Sopenharmony_cistatic int __btrfs_add_delayed_item(struct btrfs_delayed_node *delayed_node, 4018c2ecf20Sopenharmony_ci struct btrfs_delayed_item *ins, 4028c2ecf20Sopenharmony_ci int action) 4038c2ecf20Sopenharmony_ci{ 4048c2ecf20Sopenharmony_ci struct rb_node **p, *node; 4058c2ecf20Sopenharmony_ci struct rb_node *parent_node = NULL; 4068c2ecf20Sopenharmony_ci struct rb_root_cached *root; 4078c2ecf20Sopenharmony_ci struct btrfs_delayed_item *item; 4088c2ecf20Sopenharmony_ci int cmp; 4098c2ecf20Sopenharmony_ci bool leftmost = true; 4108c2ecf20Sopenharmony_ci 4118c2ecf20Sopenharmony_ci if (action == BTRFS_DELAYED_INSERTION_ITEM) 4128c2ecf20Sopenharmony_ci root = &delayed_node->ins_root; 4138c2ecf20Sopenharmony_ci else if (action == BTRFS_DELAYED_DELETION_ITEM) 4148c2ecf20Sopenharmony_ci root = &delayed_node->del_root; 4158c2ecf20Sopenharmony_ci else 4168c2ecf20Sopenharmony_ci BUG(); 4178c2ecf20Sopenharmony_ci p = &root->rb_root.rb_node; 4188c2ecf20Sopenharmony_ci node = &ins->rb_node; 4198c2ecf20Sopenharmony_ci 4208c2ecf20Sopenharmony_ci while (*p) { 4218c2ecf20Sopenharmony_ci parent_node = *p; 4228c2ecf20Sopenharmony_ci item = rb_entry(parent_node, struct btrfs_delayed_item, 4238c2ecf20Sopenharmony_ci rb_node); 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci cmp = btrfs_comp_cpu_keys(&item->key, &ins->key); 4268c2ecf20Sopenharmony_ci if (cmp < 0) { 4278c2ecf20Sopenharmony_ci p = &(*p)->rb_right; 4288c2ecf20Sopenharmony_ci leftmost = false; 4298c2ecf20Sopenharmony_ci } else if (cmp > 0) { 4308c2ecf20Sopenharmony_ci p = &(*p)->rb_left; 4318c2ecf20Sopenharmony_ci } else { 4328c2ecf20Sopenharmony_ci return -EEXIST; 4338c2ecf20Sopenharmony_ci } 4348c2ecf20Sopenharmony_ci } 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci rb_link_node(node, parent_node, p); 4378c2ecf20Sopenharmony_ci rb_insert_color_cached(node, root, leftmost); 4388c2ecf20Sopenharmony_ci ins->delayed_node = delayed_node; 4398c2ecf20Sopenharmony_ci ins->ins_or_del = action; 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_ci if (ins->key.type == BTRFS_DIR_INDEX_KEY && 4428c2ecf20Sopenharmony_ci action == BTRFS_DELAYED_INSERTION_ITEM && 4438c2ecf20Sopenharmony_ci ins->key.offset >= delayed_node->index_cnt) 4448c2ecf20Sopenharmony_ci delayed_node->index_cnt = ins->key.offset + 1; 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci delayed_node->count++; 4478c2ecf20Sopenharmony_ci atomic_inc(&delayed_node->root->fs_info->delayed_root->items); 4488c2ecf20Sopenharmony_ci return 0; 4498c2ecf20Sopenharmony_ci} 4508c2ecf20Sopenharmony_ci 4518c2ecf20Sopenharmony_cistatic int __btrfs_add_delayed_insertion_item(struct btrfs_delayed_node *node, 4528c2ecf20Sopenharmony_ci struct btrfs_delayed_item *item) 4538c2ecf20Sopenharmony_ci{ 4548c2ecf20Sopenharmony_ci return __btrfs_add_delayed_item(node, item, 4558c2ecf20Sopenharmony_ci BTRFS_DELAYED_INSERTION_ITEM); 4568c2ecf20Sopenharmony_ci} 4578c2ecf20Sopenharmony_ci 4588c2ecf20Sopenharmony_cistatic int __btrfs_add_delayed_deletion_item(struct btrfs_delayed_node *node, 4598c2ecf20Sopenharmony_ci struct btrfs_delayed_item *item) 4608c2ecf20Sopenharmony_ci{ 4618c2ecf20Sopenharmony_ci return __btrfs_add_delayed_item(node, item, 4628c2ecf20Sopenharmony_ci BTRFS_DELAYED_DELETION_ITEM); 4638c2ecf20Sopenharmony_ci} 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_cistatic void finish_one_item(struct btrfs_delayed_root *delayed_root) 4668c2ecf20Sopenharmony_ci{ 4678c2ecf20Sopenharmony_ci int seq = atomic_inc_return(&delayed_root->items_seq); 4688c2ecf20Sopenharmony_ci 4698c2ecf20Sopenharmony_ci /* atomic_dec_return implies a barrier */ 4708c2ecf20Sopenharmony_ci if ((atomic_dec_return(&delayed_root->items) < 4718c2ecf20Sopenharmony_ci BTRFS_DELAYED_BACKGROUND || seq % BTRFS_DELAYED_BATCH == 0)) 4728c2ecf20Sopenharmony_ci cond_wake_up_nomb(&delayed_root->wait); 4738c2ecf20Sopenharmony_ci} 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_cistatic void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item) 4768c2ecf20Sopenharmony_ci{ 4778c2ecf20Sopenharmony_ci struct rb_root_cached *root; 4788c2ecf20Sopenharmony_ci struct btrfs_delayed_root *delayed_root; 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_ci /* Not associated with any delayed_node */ 4818c2ecf20Sopenharmony_ci if (!delayed_item->delayed_node) 4828c2ecf20Sopenharmony_ci return; 4838c2ecf20Sopenharmony_ci delayed_root = delayed_item->delayed_node->root->fs_info->delayed_root; 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_ci BUG_ON(!delayed_root); 4868c2ecf20Sopenharmony_ci BUG_ON(delayed_item->ins_or_del != BTRFS_DELAYED_DELETION_ITEM && 4878c2ecf20Sopenharmony_ci delayed_item->ins_or_del != BTRFS_DELAYED_INSERTION_ITEM); 4888c2ecf20Sopenharmony_ci 4898c2ecf20Sopenharmony_ci if (delayed_item->ins_or_del == BTRFS_DELAYED_INSERTION_ITEM) 4908c2ecf20Sopenharmony_ci root = &delayed_item->delayed_node->ins_root; 4918c2ecf20Sopenharmony_ci else 4928c2ecf20Sopenharmony_ci root = &delayed_item->delayed_node->del_root; 4938c2ecf20Sopenharmony_ci 4948c2ecf20Sopenharmony_ci rb_erase_cached(&delayed_item->rb_node, root); 4958c2ecf20Sopenharmony_ci delayed_item->delayed_node->count--; 4968c2ecf20Sopenharmony_ci 4978c2ecf20Sopenharmony_ci finish_one_item(delayed_root); 4988c2ecf20Sopenharmony_ci} 4998c2ecf20Sopenharmony_ci 5008c2ecf20Sopenharmony_cistatic void btrfs_release_delayed_item(struct btrfs_delayed_item *item) 5018c2ecf20Sopenharmony_ci{ 5028c2ecf20Sopenharmony_ci if (item) { 5038c2ecf20Sopenharmony_ci __btrfs_remove_delayed_item(item); 5048c2ecf20Sopenharmony_ci if (refcount_dec_and_test(&item->refs)) 5058c2ecf20Sopenharmony_ci kfree(item); 5068c2ecf20Sopenharmony_ci } 5078c2ecf20Sopenharmony_ci} 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_cistatic struct btrfs_delayed_item *__btrfs_first_delayed_insertion_item( 5108c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_node) 5118c2ecf20Sopenharmony_ci{ 5128c2ecf20Sopenharmony_ci struct rb_node *p; 5138c2ecf20Sopenharmony_ci struct btrfs_delayed_item *item = NULL; 5148c2ecf20Sopenharmony_ci 5158c2ecf20Sopenharmony_ci p = rb_first_cached(&delayed_node->ins_root); 5168c2ecf20Sopenharmony_ci if (p) 5178c2ecf20Sopenharmony_ci item = rb_entry(p, struct btrfs_delayed_item, rb_node); 5188c2ecf20Sopenharmony_ci 5198c2ecf20Sopenharmony_ci return item; 5208c2ecf20Sopenharmony_ci} 5218c2ecf20Sopenharmony_ci 5228c2ecf20Sopenharmony_cistatic struct btrfs_delayed_item *__btrfs_first_delayed_deletion_item( 5238c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_node) 5248c2ecf20Sopenharmony_ci{ 5258c2ecf20Sopenharmony_ci struct rb_node *p; 5268c2ecf20Sopenharmony_ci struct btrfs_delayed_item *item = NULL; 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_ci p = rb_first_cached(&delayed_node->del_root); 5298c2ecf20Sopenharmony_ci if (p) 5308c2ecf20Sopenharmony_ci item = rb_entry(p, struct btrfs_delayed_item, rb_node); 5318c2ecf20Sopenharmony_ci 5328c2ecf20Sopenharmony_ci return item; 5338c2ecf20Sopenharmony_ci} 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_cistatic struct btrfs_delayed_item *__btrfs_next_delayed_item( 5368c2ecf20Sopenharmony_ci struct btrfs_delayed_item *item) 5378c2ecf20Sopenharmony_ci{ 5388c2ecf20Sopenharmony_ci struct rb_node *p; 5398c2ecf20Sopenharmony_ci struct btrfs_delayed_item *next = NULL; 5408c2ecf20Sopenharmony_ci 5418c2ecf20Sopenharmony_ci p = rb_next(&item->rb_node); 5428c2ecf20Sopenharmony_ci if (p) 5438c2ecf20Sopenharmony_ci next = rb_entry(p, struct btrfs_delayed_item, rb_node); 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_ci return next; 5468c2ecf20Sopenharmony_ci} 5478c2ecf20Sopenharmony_ci 5488c2ecf20Sopenharmony_cistatic int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans, 5498c2ecf20Sopenharmony_ci struct btrfs_root *root, 5508c2ecf20Sopenharmony_ci struct btrfs_delayed_item *item) 5518c2ecf20Sopenharmony_ci{ 5528c2ecf20Sopenharmony_ci struct btrfs_block_rsv *src_rsv; 5538c2ecf20Sopenharmony_ci struct btrfs_block_rsv *dst_rsv; 5548c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = root->fs_info; 5558c2ecf20Sopenharmony_ci u64 num_bytes; 5568c2ecf20Sopenharmony_ci int ret; 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_ci if (!trans->bytes_reserved) 5598c2ecf20Sopenharmony_ci return 0; 5608c2ecf20Sopenharmony_ci 5618c2ecf20Sopenharmony_ci src_rsv = trans->block_rsv; 5628c2ecf20Sopenharmony_ci dst_rsv = &fs_info->delayed_block_rsv; 5638c2ecf20Sopenharmony_ci 5648c2ecf20Sopenharmony_ci num_bytes = btrfs_calc_insert_metadata_size(fs_info, 1); 5658c2ecf20Sopenharmony_ci 5668c2ecf20Sopenharmony_ci /* 5678c2ecf20Sopenharmony_ci * Here we migrate space rsv from transaction rsv, since have already 5688c2ecf20Sopenharmony_ci * reserved space when starting a transaction. So no need to reserve 5698c2ecf20Sopenharmony_ci * qgroup space here. 5708c2ecf20Sopenharmony_ci */ 5718c2ecf20Sopenharmony_ci ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, true); 5728c2ecf20Sopenharmony_ci if (!ret) { 5738c2ecf20Sopenharmony_ci trace_btrfs_space_reservation(fs_info, "delayed_item", 5748c2ecf20Sopenharmony_ci item->key.objectid, 5758c2ecf20Sopenharmony_ci num_bytes, 1); 5768c2ecf20Sopenharmony_ci item->bytes_reserved = num_bytes; 5778c2ecf20Sopenharmony_ci } 5788c2ecf20Sopenharmony_ci 5798c2ecf20Sopenharmony_ci return ret; 5808c2ecf20Sopenharmony_ci} 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_cistatic void btrfs_delayed_item_release_metadata(struct btrfs_root *root, 5838c2ecf20Sopenharmony_ci struct btrfs_delayed_item *item) 5848c2ecf20Sopenharmony_ci{ 5858c2ecf20Sopenharmony_ci struct btrfs_block_rsv *rsv; 5868c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = root->fs_info; 5878c2ecf20Sopenharmony_ci 5888c2ecf20Sopenharmony_ci if (!item->bytes_reserved) 5898c2ecf20Sopenharmony_ci return; 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_ci rsv = &fs_info->delayed_block_rsv; 5928c2ecf20Sopenharmony_ci /* 5938c2ecf20Sopenharmony_ci * Check btrfs_delayed_item_reserve_metadata() to see why we don't need 5948c2ecf20Sopenharmony_ci * to release/reserve qgroup space. 5958c2ecf20Sopenharmony_ci */ 5968c2ecf20Sopenharmony_ci trace_btrfs_space_reservation(fs_info, "delayed_item", 5978c2ecf20Sopenharmony_ci item->key.objectid, item->bytes_reserved, 5988c2ecf20Sopenharmony_ci 0); 5998c2ecf20Sopenharmony_ci btrfs_block_rsv_release(fs_info, rsv, item->bytes_reserved, NULL); 6008c2ecf20Sopenharmony_ci} 6018c2ecf20Sopenharmony_ci 6028c2ecf20Sopenharmony_cistatic int btrfs_delayed_inode_reserve_metadata( 6038c2ecf20Sopenharmony_ci struct btrfs_trans_handle *trans, 6048c2ecf20Sopenharmony_ci struct btrfs_root *root, 6058c2ecf20Sopenharmony_ci struct btrfs_inode *inode, 6068c2ecf20Sopenharmony_ci struct btrfs_delayed_node *node) 6078c2ecf20Sopenharmony_ci{ 6088c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = root->fs_info; 6098c2ecf20Sopenharmony_ci struct btrfs_block_rsv *src_rsv; 6108c2ecf20Sopenharmony_ci struct btrfs_block_rsv *dst_rsv; 6118c2ecf20Sopenharmony_ci u64 num_bytes; 6128c2ecf20Sopenharmony_ci int ret; 6138c2ecf20Sopenharmony_ci 6148c2ecf20Sopenharmony_ci src_rsv = trans->block_rsv; 6158c2ecf20Sopenharmony_ci dst_rsv = &fs_info->delayed_block_rsv; 6168c2ecf20Sopenharmony_ci 6178c2ecf20Sopenharmony_ci num_bytes = btrfs_calc_metadata_size(fs_info, 1); 6188c2ecf20Sopenharmony_ci 6198c2ecf20Sopenharmony_ci /* 6208c2ecf20Sopenharmony_ci * btrfs_dirty_inode will update the inode under btrfs_join_transaction 6218c2ecf20Sopenharmony_ci * which doesn't reserve space for speed. This is a problem since we 6228c2ecf20Sopenharmony_ci * still need to reserve space for this update, so try to reserve the 6238c2ecf20Sopenharmony_ci * space. 6248c2ecf20Sopenharmony_ci * 6258c2ecf20Sopenharmony_ci * Now if src_rsv == delalloc_block_rsv we'll let it just steal since 6268c2ecf20Sopenharmony_ci * we always reserve enough to update the inode item. 6278c2ecf20Sopenharmony_ci */ 6288c2ecf20Sopenharmony_ci if (!src_rsv || (!trans->bytes_reserved && 6298c2ecf20Sopenharmony_ci src_rsv->type != BTRFS_BLOCK_RSV_DELALLOC)) { 6308c2ecf20Sopenharmony_ci ret = btrfs_qgroup_reserve_meta(root, num_bytes, 6318c2ecf20Sopenharmony_ci BTRFS_QGROUP_RSV_META_PREALLOC, true); 6328c2ecf20Sopenharmony_ci if (ret < 0) 6338c2ecf20Sopenharmony_ci return ret; 6348c2ecf20Sopenharmony_ci ret = btrfs_block_rsv_add(root, dst_rsv, num_bytes, 6358c2ecf20Sopenharmony_ci BTRFS_RESERVE_NO_FLUSH); 6368c2ecf20Sopenharmony_ci /* 6378c2ecf20Sopenharmony_ci * Since we're under a transaction reserve_metadata_bytes could 6388c2ecf20Sopenharmony_ci * try to commit the transaction which will make it return 6398c2ecf20Sopenharmony_ci * EAGAIN to make us stop the transaction we have, so return 6408c2ecf20Sopenharmony_ci * ENOSPC instead so that btrfs_dirty_inode knows what to do. 6418c2ecf20Sopenharmony_ci */ 6428c2ecf20Sopenharmony_ci if (ret == -EAGAIN) { 6438c2ecf20Sopenharmony_ci ret = -ENOSPC; 6448c2ecf20Sopenharmony_ci btrfs_qgroup_free_meta_prealloc(root, num_bytes); 6458c2ecf20Sopenharmony_ci } 6468c2ecf20Sopenharmony_ci if (!ret) { 6478c2ecf20Sopenharmony_ci node->bytes_reserved = num_bytes; 6488c2ecf20Sopenharmony_ci trace_btrfs_space_reservation(fs_info, 6498c2ecf20Sopenharmony_ci "delayed_inode", 6508c2ecf20Sopenharmony_ci btrfs_ino(inode), 6518c2ecf20Sopenharmony_ci num_bytes, 1); 6528c2ecf20Sopenharmony_ci } else { 6538c2ecf20Sopenharmony_ci btrfs_qgroup_free_meta_prealloc(root, num_bytes); 6548c2ecf20Sopenharmony_ci } 6558c2ecf20Sopenharmony_ci return ret; 6568c2ecf20Sopenharmony_ci } 6578c2ecf20Sopenharmony_ci 6588c2ecf20Sopenharmony_ci ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, true); 6598c2ecf20Sopenharmony_ci if (!ret) { 6608c2ecf20Sopenharmony_ci trace_btrfs_space_reservation(fs_info, "delayed_inode", 6618c2ecf20Sopenharmony_ci btrfs_ino(inode), num_bytes, 1); 6628c2ecf20Sopenharmony_ci node->bytes_reserved = num_bytes; 6638c2ecf20Sopenharmony_ci } 6648c2ecf20Sopenharmony_ci 6658c2ecf20Sopenharmony_ci return ret; 6668c2ecf20Sopenharmony_ci} 6678c2ecf20Sopenharmony_ci 6688c2ecf20Sopenharmony_cistatic void btrfs_delayed_inode_release_metadata(struct btrfs_fs_info *fs_info, 6698c2ecf20Sopenharmony_ci struct btrfs_delayed_node *node, 6708c2ecf20Sopenharmony_ci bool qgroup_free) 6718c2ecf20Sopenharmony_ci{ 6728c2ecf20Sopenharmony_ci struct btrfs_block_rsv *rsv; 6738c2ecf20Sopenharmony_ci 6748c2ecf20Sopenharmony_ci if (!node->bytes_reserved) 6758c2ecf20Sopenharmony_ci return; 6768c2ecf20Sopenharmony_ci 6778c2ecf20Sopenharmony_ci rsv = &fs_info->delayed_block_rsv; 6788c2ecf20Sopenharmony_ci trace_btrfs_space_reservation(fs_info, "delayed_inode", 6798c2ecf20Sopenharmony_ci node->inode_id, node->bytes_reserved, 0); 6808c2ecf20Sopenharmony_ci btrfs_block_rsv_release(fs_info, rsv, node->bytes_reserved, NULL); 6818c2ecf20Sopenharmony_ci if (qgroup_free) 6828c2ecf20Sopenharmony_ci btrfs_qgroup_free_meta_prealloc(node->root, 6838c2ecf20Sopenharmony_ci node->bytes_reserved); 6848c2ecf20Sopenharmony_ci else 6858c2ecf20Sopenharmony_ci btrfs_qgroup_convert_reserved_meta(node->root, 6868c2ecf20Sopenharmony_ci node->bytes_reserved); 6878c2ecf20Sopenharmony_ci node->bytes_reserved = 0; 6888c2ecf20Sopenharmony_ci} 6898c2ecf20Sopenharmony_ci 6908c2ecf20Sopenharmony_ci/* 6918c2ecf20Sopenharmony_ci * This helper will insert some continuous items into the same leaf according 6928c2ecf20Sopenharmony_ci * to the free space of the leaf. 6938c2ecf20Sopenharmony_ci */ 6948c2ecf20Sopenharmony_cistatic int btrfs_batch_insert_items(struct btrfs_root *root, 6958c2ecf20Sopenharmony_ci struct btrfs_path *path, 6968c2ecf20Sopenharmony_ci struct btrfs_delayed_item *item) 6978c2ecf20Sopenharmony_ci{ 6988c2ecf20Sopenharmony_ci struct btrfs_delayed_item *curr, *next; 6998c2ecf20Sopenharmony_ci int free_space; 7008c2ecf20Sopenharmony_ci int total_data_size = 0, total_size = 0; 7018c2ecf20Sopenharmony_ci struct extent_buffer *leaf; 7028c2ecf20Sopenharmony_ci char *data_ptr; 7038c2ecf20Sopenharmony_ci struct btrfs_key *keys; 7048c2ecf20Sopenharmony_ci u32 *data_size; 7058c2ecf20Sopenharmony_ci struct list_head head; 7068c2ecf20Sopenharmony_ci int slot; 7078c2ecf20Sopenharmony_ci int nitems; 7088c2ecf20Sopenharmony_ci int i; 7098c2ecf20Sopenharmony_ci int ret = 0; 7108c2ecf20Sopenharmony_ci 7118c2ecf20Sopenharmony_ci BUG_ON(!path->nodes[0]); 7128c2ecf20Sopenharmony_ci 7138c2ecf20Sopenharmony_ci leaf = path->nodes[0]; 7148c2ecf20Sopenharmony_ci free_space = btrfs_leaf_free_space(leaf); 7158c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&head); 7168c2ecf20Sopenharmony_ci 7178c2ecf20Sopenharmony_ci next = item; 7188c2ecf20Sopenharmony_ci nitems = 0; 7198c2ecf20Sopenharmony_ci 7208c2ecf20Sopenharmony_ci /* 7218c2ecf20Sopenharmony_ci * count the number of the continuous items that we can insert in batch 7228c2ecf20Sopenharmony_ci */ 7238c2ecf20Sopenharmony_ci while (total_size + next->data_len + sizeof(struct btrfs_item) <= 7248c2ecf20Sopenharmony_ci free_space) { 7258c2ecf20Sopenharmony_ci total_data_size += next->data_len; 7268c2ecf20Sopenharmony_ci total_size += next->data_len + sizeof(struct btrfs_item); 7278c2ecf20Sopenharmony_ci list_add_tail(&next->tree_list, &head); 7288c2ecf20Sopenharmony_ci nitems++; 7298c2ecf20Sopenharmony_ci 7308c2ecf20Sopenharmony_ci curr = next; 7318c2ecf20Sopenharmony_ci next = __btrfs_next_delayed_item(curr); 7328c2ecf20Sopenharmony_ci if (!next) 7338c2ecf20Sopenharmony_ci break; 7348c2ecf20Sopenharmony_ci 7358c2ecf20Sopenharmony_ci if (!btrfs_is_continuous_delayed_item(curr, next)) 7368c2ecf20Sopenharmony_ci break; 7378c2ecf20Sopenharmony_ci } 7388c2ecf20Sopenharmony_ci 7398c2ecf20Sopenharmony_ci if (!nitems) { 7408c2ecf20Sopenharmony_ci ret = 0; 7418c2ecf20Sopenharmony_ci goto out; 7428c2ecf20Sopenharmony_ci } 7438c2ecf20Sopenharmony_ci 7448c2ecf20Sopenharmony_ci /* 7458c2ecf20Sopenharmony_ci * we need allocate some memory space, but it might cause the task 7468c2ecf20Sopenharmony_ci * to sleep, so we set all locked nodes in the path to blocking locks 7478c2ecf20Sopenharmony_ci * first. 7488c2ecf20Sopenharmony_ci */ 7498c2ecf20Sopenharmony_ci btrfs_set_path_blocking(path); 7508c2ecf20Sopenharmony_ci 7518c2ecf20Sopenharmony_ci keys = kmalloc_array(nitems, sizeof(struct btrfs_key), GFP_NOFS); 7528c2ecf20Sopenharmony_ci if (!keys) { 7538c2ecf20Sopenharmony_ci ret = -ENOMEM; 7548c2ecf20Sopenharmony_ci goto out; 7558c2ecf20Sopenharmony_ci } 7568c2ecf20Sopenharmony_ci 7578c2ecf20Sopenharmony_ci data_size = kmalloc_array(nitems, sizeof(u32), GFP_NOFS); 7588c2ecf20Sopenharmony_ci if (!data_size) { 7598c2ecf20Sopenharmony_ci ret = -ENOMEM; 7608c2ecf20Sopenharmony_ci goto error; 7618c2ecf20Sopenharmony_ci } 7628c2ecf20Sopenharmony_ci 7638c2ecf20Sopenharmony_ci /* get keys of all the delayed items */ 7648c2ecf20Sopenharmony_ci i = 0; 7658c2ecf20Sopenharmony_ci list_for_each_entry(next, &head, tree_list) { 7668c2ecf20Sopenharmony_ci keys[i] = next->key; 7678c2ecf20Sopenharmony_ci data_size[i] = next->data_len; 7688c2ecf20Sopenharmony_ci i++; 7698c2ecf20Sopenharmony_ci } 7708c2ecf20Sopenharmony_ci 7718c2ecf20Sopenharmony_ci /* insert the keys of the items */ 7728c2ecf20Sopenharmony_ci setup_items_for_insert(root, path, keys, data_size, nitems); 7738c2ecf20Sopenharmony_ci 7748c2ecf20Sopenharmony_ci /* insert the dir index items */ 7758c2ecf20Sopenharmony_ci slot = path->slots[0]; 7768c2ecf20Sopenharmony_ci list_for_each_entry_safe(curr, next, &head, tree_list) { 7778c2ecf20Sopenharmony_ci data_ptr = btrfs_item_ptr(leaf, slot, char); 7788c2ecf20Sopenharmony_ci write_extent_buffer(leaf, &curr->data, 7798c2ecf20Sopenharmony_ci (unsigned long)data_ptr, 7808c2ecf20Sopenharmony_ci curr->data_len); 7818c2ecf20Sopenharmony_ci slot++; 7828c2ecf20Sopenharmony_ci 7838c2ecf20Sopenharmony_ci btrfs_delayed_item_release_metadata(root, curr); 7848c2ecf20Sopenharmony_ci 7858c2ecf20Sopenharmony_ci list_del(&curr->tree_list); 7868c2ecf20Sopenharmony_ci btrfs_release_delayed_item(curr); 7878c2ecf20Sopenharmony_ci } 7888c2ecf20Sopenharmony_ci 7898c2ecf20Sopenharmony_cierror: 7908c2ecf20Sopenharmony_ci kfree(data_size); 7918c2ecf20Sopenharmony_ci kfree(keys); 7928c2ecf20Sopenharmony_ciout: 7938c2ecf20Sopenharmony_ci return ret; 7948c2ecf20Sopenharmony_ci} 7958c2ecf20Sopenharmony_ci 7968c2ecf20Sopenharmony_ci/* 7978c2ecf20Sopenharmony_ci * This helper can just do simple insertion that needn't extend item for new 7988c2ecf20Sopenharmony_ci * data, such as directory name index insertion, inode insertion. 7998c2ecf20Sopenharmony_ci */ 8008c2ecf20Sopenharmony_cistatic int btrfs_insert_delayed_item(struct btrfs_trans_handle *trans, 8018c2ecf20Sopenharmony_ci struct btrfs_root *root, 8028c2ecf20Sopenharmony_ci struct btrfs_path *path, 8038c2ecf20Sopenharmony_ci struct btrfs_delayed_item *delayed_item) 8048c2ecf20Sopenharmony_ci{ 8058c2ecf20Sopenharmony_ci struct extent_buffer *leaf; 8068c2ecf20Sopenharmony_ci unsigned int nofs_flag; 8078c2ecf20Sopenharmony_ci char *ptr; 8088c2ecf20Sopenharmony_ci int ret; 8098c2ecf20Sopenharmony_ci 8108c2ecf20Sopenharmony_ci nofs_flag = memalloc_nofs_save(); 8118c2ecf20Sopenharmony_ci ret = btrfs_insert_empty_item(trans, root, path, &delayed_item->key, 8128c2ecf20Sopenharmony_ci delayed_item->data_len); 8138c2ecf20Sopenharmony_ci memalloc_nofs_restore(nofs_flag); 8148c2ecf20Sopenharmony_ci if (ret < 0 && ret != -EEXIST) 8158c2ecf20Sopenharmony_ci return ret; 8168c2ecf20Sopenharmony_ci 8178c2ecf20Sopenharmony_ci leaf = path->nodes[0]; 8188c2ecf20Sopenharmony_ci 8198c2ecf20Sopenharmony_ci ptr = btrfs_item_ptr(leaf, path->slots[0], char); 8208c2ecf20Sopenharmony_ci 8218c2ecf20Sopenharmony_ci write_extent_buffer(leaf, delayed_item->data, (unsigned long)ptr, 8228c2ecf20Sopenharmony_ci delayed_item->data_len); 8238c2ecf20Sopenharmony_ci btrfs_mark_buffer_dirty(leaf); 8248c2ecf20Sopenharmony_ci 8258c2ecf20Sopenharmony_ci btrfs_delayed_item_release_metadata(root, delayed_item); 8268c2ecf20Sopenharmony_ci return 0; 8278c2ecf20Sopenharmony_ci} 8288c2ecf20Sopenharmony_ci 8298c2ecf20Sopenharmony_ci/* 8308c2ecf20Sopenharmony_ci * we insert an item first, then if there are some continuous items, we try 8318c2ecf20Sopenharmony_ci * to insert those items into the same leaf. 8328c2ecf20Sopenharmony_ci */ 8338c2ecf20Sopenharmony_cistatic int btrfs_insert_delayed_items(struct btrfs_trans_handle *trans, 8348c2ecf20Sopenharmony_ci struct btrfs_path *path, 8358c2ecf20Sopenharmony_ci struct btrfs_root *root, 8368c2ecf20Sopenharmony_ci struct btrfs_delayed_node *node) 8378c2ecf20Sopenharmony_ci{ 8388c2ecf20Sopenharmony_ci struct btrfs_delayed_item *curr, *prev; 8398c2ecf20Sopenharmony_ci int ret = 0; 8408c2ecf20Sopenharmony_ci 8418c2ecf20Sopenharmony_cido_again: 8428c2ecf20Sopenharmony_ci mutex_lock(&node->mutex); 8438c2ecf20Sopenharmony_ci curr = __btrfs_first_delayed_insertion_item(node); 8448c2ecf20Sopenharmony_ci if (!curr) 8458c2ecf20Sopenharmony_ci goto insert_end; 8468c2ecf20Sopenharmony_ci 8478c2ecf20Sopenharmony_ci ret = btrfs_insert_delayed_item(trans, root, path, curr); 8488c2ecf20Sopenharmony_ci if (ret < 0) { 8498c2ecf20Sopenharmony_ci btrfs_release_path(path); 8508c2ecf20Sopenharmony_ci goto insert_end; 8518c2ecf20Sopenharmony_ci } 8528c2ecf20Sopenharmony_ci 8538c2ecf20Sopenharmony_ci prev = curr; 8548c2ecf20Sopenharmony_ci curr = __btrfs_next_delayed_item(prev); 8558c2ecf20Sopenharmony_ci if (curr && btrfs_is_continuous_delayed_item(prev, curr)) { 8568c2ecf20Sopenharmony_ci /* insert the continuous items into the same leaf */ 8578c2ecf20Sopenharmony_ci path->slots[0]++; 8588c2ecf20Sopenharmony_ci btrfs_batch_insert_items(root, path, curr); 8598c2ecf20Sopenharmony_ci } 8608c2ecf20Sopenharmony_ci btrfs_release_delayed_item(prev); 8618c2ecf20Sopenharmony_ci btrfs_mark_buffer_dirty(path->nodes[0]); 8628c2ecf20Sopenharmony_ci 8638c2ecf20Sopenharmony_ci btrfs_release_path(path); 8648c2ecf20Sopenharmony_ci mutex_unlock(&node->mutex); 8658c2ecf20Sopenharmony_ci goto do_again; 8668c2ecf20Sopenharmony_ci 8678c2ecf20Sopenharmony_ciinsert_end: 8688c2ecf20Sopenharmony_ci mutex_unlock(&node->mutex); 8698c2ecf20Sopenharmony_ci return ret; 8708c2ecf20Sopenharmony_ci} 8718c2ecf20Sopenharmony_ci 8728c2ecf20Sopenharmony_cistatic int btrfs_batch_delete_items(struct btrfs_trans_handle *trans, 8738c2ecf20Sopenharmony_ci struct btrfs_root *root, 8748c2ecf20Sopenharmony_ci struct btrfs_path *path, 8758c2ecf20Sopenharmony_ci struct btrfs_delayed_item *item) 8768c2ecf20Sopenharmony_ci{ 8778c2ecf20Sopenharmony_ci struct btrfs_delayed_item *curr, *next; 8788c2ecf20Sopenharmony_ci struct extent_buffer *leaf; 8798c2ecf20Sopenharmony_ci struct btrfs_key key; 8808c2ecf20Sopenharmony_ci struct list_head head; 8818c2ecf20Sopenharmony_ci int nitems, i, last_item; 8828c2ecf20Sopenharmony_ci int ret = 0; 8838c2ecf20Sopenharmony_ci 8848c2ecf20Sopenharmony_ci BUG_ON(!path->nodes[0]); 8858c2ecf20Sopenharmony_ci 8868c2ecf20Sopenharmony_ci leaf = path->nodes[0]; 8878c2ecf20Sopenharmony_ci 8888c2ecf20Sopenharmony_ci i = path->slots[0]; 8898c2ecf20Sopenharmony_ci last_item = btrfs_header_nritems(leaf) - 1; 8908c2ecf20Sopenharmony_ci if (i > last_item) 8918c2ecf20Sopenharmony_ci return -ENOENT; /* FIXME: Is errno suitable? */ 8928c2ecf20Sopenharmony_ci 8938c2ecf20Sopenharmony_ci next = item; 8948c2ecf20Sopenharmony_ci INIT_LIST_HEAD(&head); 8958c2ecf20Sopenharmony_ci btrfs_item_key_to_cpu(leaf, &key, i); 8968c2ecf20Sopenharmony_ci nitems = 0; 8978c2ecf20Sopenharmony_ci /* 8988c2ecf20Sopenharmony_ci * count the number of the dir index items that we can delete in batch 8998c2ecf20Sopenharmony_ci */ 9008c2ecf20Sopenharmony_ci while (btrfs_comp_cpu_keys(&next->key, &key) == 0) { 9018c2ecf20Sopenharmony_ci list_add_tail(&next->tree_list, &head); 9028c2ecf20Sopenharmony_ci nitems++; 9038c2ecf20Sopenharmony_ci 9048c2ecf20Sopenharmony_ci curr = next; 9058c2ecf20Sopenharmony_ci next = __btrfs_next_delayed_item(curr); 9068c2ecf20Sopenharmony_ci if (!next) 9078c2ecf20Sopenharmony_ci break; 9088c2ecf20Sopenharmony_ci 9098c2ecf20Sopenharmony_ci if (!btrfs_is_continuous_delayed_item(curr, next)) 9108c2ecf20Sopenharmony_ci break; 9118c2ecf20Sopenharmony_ci 9128c2ecf20Sopenharmony_ci i++; 9138c2ecf20Sopenharmony_ci if (i > last_item) 9148c2ecf20Sopenharmony_ci break; 9158c2ecf20Sopenharmony_ci btrfs_item_key_to_cpu(leaf, &key, i); 9168c2ecf20Sopenharmony_ci } 9178c2ecf20Sopenharmony_ci 9188c2ecf20Sopenharmony_ci if (!nitems) 9198c2ecf20Sopenharmony_ci return 0; 9208c2ecf20Sopenharmony_ci 9218c2ecf20Sopenharmony_ci ret = btrfs_del_items(trans, root, path, path->slots[0], nitems); 9228c2ecf20Sopenharmony_ci if (ret) 9238c2ecf20Sopenharmony_ci goto out; 9248c2ecf20Sopenharmony_ci 9258c2ecf20Sopenharmony_ci list_for_each_entry_safe(curr, next, &head, tree_list) { 9268c2ecf20Sopenharmony_ci btrfs_delayed_item_release_metadata(root, curr); 9278c2ecf20Sopenharmony_ci list_del(&curr->tree_list); 9288c2ecf20Sopenharmony_ci btrfs_release_delayed_item(curr); 9298c2ecf20Sopenharmony_ci } 9308c2ecf20Sopenharmony_ci 9318c2ecf20Sopenharmony_ciout: 9328c2ecf20Sopenharmony_ci return ret; 9338c2ecf20Sopenharmony_ci} 9348c2ecf20Sopenharmony_ci 9358c2ecf20Sopenharmony_cistatic int btrfs_delete_delayed_items(struct btrfs_trans_handle *trans, 9368c2ecf20Sopenharmony_ci struct btrfs_path *path, 9378c2ecf20Sopenharmony_ci struct btrfs_root *root, 9388c2ecf20Sopenharmony_ci struct btrfs_delayed_node *node) 9398c2ecf20Sopenharmony_ci{ 9408c2ecf20Sopenharmony_ci struct btrfs_delayed_item *curr, *prev; 9418c2ecf20Sopenharmony_ci unsigned int nofs_flag; 9428c2ecf20Sopenharmony_ci int ret = 0; 9438c2ecf20Sopenharmony_ci 9448c2ecf20Sopenharmony_cido_again: 9458c2ecf20Sopenharmony_ci mutex_lock(&node->mutex); 9468c2ecf20Sopenharmony_ci curr = __btrfs_first_delayed_deletion_item(node); 9478c2ecf20Sopenharmony_ci if (!curr) 9488c2ecf20Sopenharmony_ci goto delete_fail; 9498c2ecf20Sopenharmony_ci 9508c2ecf20Sopenharmony_ci nofs_flag = memalloc_nofs_save(); 9518c2ecf20Sopenharmony_ci ret = btrfs_search_slot(trans, root, &curr->key, path, -1, 1); 9528c2ecf20Sopenharmony_ci memalloc_nofs_restore(nofs_flag); 9538c2ecf20Sopenharmony_ci if (ret < 0) 9548c2ecf20Sopenharmony_ci goto delete_fail; 9558c2ecf20Sopenharmony_ci else if (ret > 0) { 9568c2ecf20Sopenharmony_ci /* 9578c2ecf20Sopenharmony_ci * can't find the item which the node points to, so this node 9588c2ecf20Sopenharmony_ci * is invalid, just drop it. 9598c2ecf20Sopenharmony_ci */ 9608c2ecf20Sopenharmony_ci prev = curr; 9618c2ecf20Sopenharmony_ci curr = __btrfs_next_delayed_item(prev); 9628c2ecf20Sopenharmony_ci btrfs_release_delayed_item(prev); 9638c2ecf20Sopenharmony_ci ret = 0; 9648c2ecf20Sopenharmony_ci btrfs_release_path(path); 9658c2ecf20Sopenharmony_ci if (curr) { 9668c2ecf20Sopenharmony_ci mutex_unlock(&node->mutex); 9678c2ecf20Sopenharmony_ci goto do_again; 9688c2ecf20Sopenharmony_ci } else 9698c2ecf20Sopenharmony_ci goto delete_fail; 9708c2ecf20Sopenharmony_ci } 9718c2ecf20Sopenharmony_ci 9728c2ecf20Sopenharmony_ci btrfs_batch_delete_items(trans, root, path, curr); 9738c2ecf20Sopenharmony_ci btrfs_release_path(path); 9748c2ecf20Sopenharmony_ci mutex_unlock(&node->mutex); 9758c2ecf20Sopenharmony_ci goto do_again; 9768c2ecf20Sopenharmony_ci 9778c2ecf20Sopenharmony_cidelete_fail: 9788c2ecf20Sopenharmony_ci btrfs_release_path(path); 9798c2ecf20Sopenharmony_ci mutex_unlock(&node->mutex); 9808c2ecf20Sopenharmony_ci return ret; 9818c2ecf20Sopenharmony_ci} 9828c2ecf20Sopenharmony_ci 9838c2ecf20Sopenharmony_cistatic void btrfs_release_delayed_inode(struct btrfs_delayed_node *delayed_node) 9848c2ecf20Sopenharmony_ci{ 9858c2ecf20Sopenharmony_ci struct btrfs_delayed_root *delayed_root; 9868c2ecf20Sopenharmony_ci 9878c2ecf20Sopenharmony_ci if (delayed_node && 9888c2ecf20Sopenharmony_ci test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags)) { 9898c2ecf20Sopenharmony_ci BUG_ON(!delayed_node->root); 9908c2ecf20Sopenharmony_ci clear_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags); 9918c2ecf20Sopenharmony_ci delayed_node->count--; 9928c2ecf20Sopenharmony_ci 9938c2ecf20Sopenharmony_ci delayed_root = delayed_node->root->fs_info->delayed_root; 9948c2ecf20Sopenharmony_ci finish_one_item(delayed_root); 9958c2ecf20Sopenharmony_ci } 9968c2ecf20Sopenharmony_ci} 9978c2ecf20Sopenharmony_ci 9988c2ecf20Sopenharmony_cistatic void btrfs_release_delayed_iref(struct btrfs_delayed_node *delayed_node) 9998c2ecf20Sopenharmony_ci{ 10008c2ecf20Sopenharmony_ci struct btrfs_delayed_root *delayed_root; 10018c2ecf20Sopenharmony_ci 10028c2ecf20Sopenharmony_ci ASSERT(delayed_node->root); 10038c2ecf20Sopenharmony_ci clear_bit(BTRFS_DELAYED_NODE_DEL_IREF, &delayed_node->flags); 10048c2ecf20Sopenharmony_ci delayed_node->count--; 10058c2ecf20Sopenharmony_ci 10068c2ecf20Sopenharmony_ci delayed_root = delayed_node->root->fs_info->delayed_root; 10078c2ecf20Sopenharmony_ci finish_one_item(delayed_root); 10088c2ecf20Sopenharmony_ci} 10098c2ecf20Sopenharmony_ci 10108c2ecf20Sopenharmony_cistatic int __btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, 10118c2ecf20Sopenharmony_ci struct btrfs_root *root, 10128c2ecf20Sopenharmony_ci struct btrfs_path *path, 10138c2ecf20Sopenharmony_ci struct btrfs_delayed_node *node) 10148c2ecf20Sopenharmony_ci{ 10158c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = root->fs_info; 10168c2ecf20Sopenharmony_ci struct btrfs_key key; 10178c2ecf20Sopenharmony_ci struct btrfs_inode_item *inode_item; 10188c2ecf20Sopenharmony_ci struct extent_buffer *leaf; 10198c2ecf20Sopenharmony_ci unsigned int nofs_flag; 10208c2ecf20Sopenharmony_ci int mod; 10218c2ecf20Sopenharmony_ci int ret; 10228c2ecf20Sopenharmony_ci 10238c2ecf20Sopenharmony_ci key.objectid = node->inode_id; 10248c2ecf20Sopenharmony_ci key.type = BTRFS_INODE_ITEM_KEY; 10258c2ecf20Sopenharmony_ci key.offset = 0; 10268c2ecf20Sopenharmony_ci 10278c2ecf20Sopenharmony_ci if (test_bit(BTRFS_DELAYED_NODE_DEL_IREF, &node->flags)) 10288c2ecf20Sopenharmony_ci mod = -1; 10298c2ecf20Sopenharmony_ci else 10308c2ecf20Sopenharmony_ci mod = 1; 10318c2ecf20Sopenharmony_ci 10328c2ecf20Sopenharmony_ci nofs_flag = memalloc_nofs_save(); 10338c2ecf20Sopenharmony_ci ret = btrfs_lookup_inode(trans, root, path, &key, mod); 10348c2ecf20Sopenharmony_ci memalloc_nofs_restore(nofs_flag); 10358c2ecf20Sopenharmony_ci if (ret > 0) 10368c2ecf20Sopenharmony_ci ret = -ENOENT; 10378c2ecf20Sopenharmony_ci if (ret < 0) 10388c2ecf20Sopenharmony_ci goto out; 10398c2ecf20Sopenharmony_ci 10408c2ecf20Sopenharmony_ci leaf = path->nodes[0]; 10418c2ecf20Sopenharmony_ci inode_item = btrfs_item_ptr(leaf, path->slots[0], 10428c2ecf20Sopenharmony_ci struct btrfs_inode_item); 10438c2ecf20Sopenharmony_ci write_extent_buffer(leaf, &node->inode_item, (unsigned long)inode_item, 10448c2ecf20Sopenharmony_ci sizeof(struct btrfs_inode_item)); 10458c2ecf20Sopenharmony_ci btrfs_mark_buffer_dirty(leaf); 10468c2ecf20Sopenharmony_ci 10478c2ecf20Sopenharmony_ci if (!test_bit(BTRFS_DELAYED_NODE_DEL_IREF, &node->flags)) 10488c2ecf20Sopenharmony_ci goto no_iref; 10498c2ecf20Sopenharmony_ci 10508c2ecf20Sopenharmony_ci path->slots[0]++; 10518c2ecf20Sopenharmony_ci if (path->slots[0] >= btrfs_header_nritems(leaf)) 10528c2ecf20Sopenharmony_ci goto search; 10538c2ecf20Sopenharmony_ciagain: 10548c2ecf20Sopenharmony_ci btrfs_item_key_to_cpu(leaf, &key, path->slots[0]); 10558c2ecf20Sopenharmony_ci if (key.objectid != node->inode_id) 10568c2ecf20Sopenharmony_ci goto out; 10578c2ecf20Sopenharmony_ci 10588c2ecf20Sopenharmony_ci if (key.type != BTRFS_INODE_REF_KEY && 10598c2ecf20Sopenharmony_ci key.type != BTRFS_INODE_EXTREF_KEY) 10608c2ecf20Sopenharmony_ci goto out; 10618c2ecf20Sopenharmony_ci 10628c2ecf20Sopenharmony_ci /* 10638c2ecf20Sopenharmony_ci * Delayed iref deletion is for the inode who has only one link, 10648c2ecf20Sopenharmony_ci * so there is only one iref. The case that several irefs are 10658c2ecf20Sopenharmony_ci * in the same item doesn't exist. 10668c2ecf20Sopenharmony_ci */ 10678c2ecf20Sopenharmony_ci btrfs_del_item(trans, root, path); 10688c2ecf20Sopenharmony_ciout: 10698c2ecf20Sopenharmony_ci btrfs_release_delayed_iref(node); 10708c2ecf20Sopenharmony_cino_iref: 10718c2ecf20Sopenharmony_ci btrfs_release_path(path); 10728c2ecf20Sopenharmony_cierr_out: 10738c2ecf20Sopenharmony_ci btrfs_delayed_inode_release_metadata(fs_info, node, (ret < 0)); 10748c2ecf20Sopenharmony_ci btrfs_release_delayed_inode(node); 10758c2ecf20Sopenharmony_ci 10768c2ecf20Sopenharmony_ci /* 10778c2ecf20Sopenharmony_ci * If we fail to update the delayed inode we need to abort the 10788c2ecf20Sopenharmony_ci * transaction, because we could leave the inode with the improper 10798c2ecf20Sopenharmony_ci * counts behind. 10808c2ecf20Sopenharmony_ci */ 10818c2ecf20Sopenharmony_ci if (ret && ret != -ENOENT) 10828c2ecf20Sopenharmony_ci btrfs_abort_transaction(trans, ret); 10838c2ecf20Sopenharmony_ci 10848c2ecf20Sopenharmony_ci return ret; 10858c2ecf20Sopenharmony_ci 10868c2ecf20Sopenharmony_cisearch: 10878c2ecf20Sopenharmony_ci btrfs_release_path(path); 10888c2ecf20Sopenharmony_ci 10898c2ecf20Sopenharmony_ci key.type = BTRFS_INODE_EXTREF_KEY; 10908c2ecf20Sopenharmony_ci key.offset = -1; 10918c2ecf20Sopenharmony_ci 10928c2ecf20Sopenharmony_ci nofs_flag = memalloc_nofs_save(); 10938c2ecf20Sopenharmony_ci ret = btrfs_search_slot(trans, root, &key, path, -1, 1); 10948c2ecf20Sopenharmony_ci memalloc_nofs_restore(nofs_flag); 10958c2ecf20Sopenharmony_ci if (ret < 0) 10968c2ecf20Sopenharmony_ci goto err_out; 10978c2ecf20Sopenharmony_ci ASSERT(ret); 10988c2ecf20Sopenharmony_ci 10998c2ecf20Sopenharmony_ci ret = 0; 11008c2ecf20Sopenharmony_ci leaf = path->nodes[0]; 11018c2ecf20Sopenharmony_ci path->slots[0]--; 11028c2ecf20Sopenharmony_ci goto again; 11038c2ecf20Sopenharmony_ci} 11048c2ecf20Sopenharmony_ci 11058c2ecf20Sopenharmony_cistatic inline int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans, 11068c2ecf20Sopenharmony_ci struct btrfs_root *root, 11078c2ecf20Sopenharmony_ci struct btrfs_path *path, 11088c2ecf20Sopenharmony_ci struct btrfs_delayed_node *node) 11098c2ecf20Sopenharmony_ci{ 11108c2ecf20Sopenharmony_ci int ret; 11118c2ecf20Sopenharmony_ci 11128c2ecf20Sopenharmony_ci mutex_lock(&node->mutex); 11138c2ecf20Sopenharmony_ci if (!test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &node->flags)) { 11148c2ecf20Sopenharmony_ci mutex_unlock(&node->mutex); 11158c2ecf20Sopenharmony_ci return 0; 11168c2ecf20Sopenharmony_ci } 11178c2ecf20Sopenharmony_ci 11188c2ecf20Sopenharmony_ci ret = __btrfs_update_delayed_inode(trans, root, path, node); 11198c2ecf20Sopenharmony_ci mutex_unlock(&node->mutex); 11208c2ecf20Sopenharmony_ci return ret; 11218c2ecf20Sopenharmony_ci} 11228c2ecf20Sopenharmony_ci 11238c2ecf20Sopenharmony_cistatic inline int 11248c2ecf20Sopenharmony_ci__btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, 11258c2ecf20Sopenharmony_ci struct btrfs_path *path, 11268c2ecf20Sopenharmony_ci struct btrfs_delayed_node *node) 11278c2ecf20Sopenharmony_ci{ 11288c2ecf20Sopenharmony_ci int ret; 11298c2ecf20Sopenharmony_ci 11308c2ecf20Sopenharmony_ci ret = btrfs_insert_delayed_items(trans, path, node->root, node); 11318c2ecf20Sopenharmony_ci if (ret) 11328c2ecf20Sopenharmony_ci return ret; 11338c2ecf20Sopenharmony_ci 11348c2ecf20Sopenharmony_ci ret = btrfs_delete_delayed_items(trans, path, node->root, node); 11358c2ecf20Sopenharmony_ci if (ret) 11368c2ecf20Sopenharmony_ci return ret; 11378c2ecf20Sopenharmony_ci 11388c2ecf20Sopenharmony_ci ret = btrfs_update_delayed_inode(trans, node->root, path, node); 11398c2ecf20Sopenharmony_ci return ret; 11408c2ecf20Sopenharmony_ci} 11418c2ecf20Sopenharmony_ci 11428c2ecf20Sopenharmony_ci/* 11438c2ecf20Sopenharmony_ci * Called when committing the transaction. 11448c2ecf20Sopenharmony_ci * Returns 0 on success. 11458c2ecf20Sopenharmony_ci * Returns < 0 on error and returns with an aborted transaction with any 11468c2ecf20Sopenharmony_ci * outstanding delayed items cleaned up. 11478c2ecf20Sopenharmony_ci */ 11488c2ecf20Sopenharmony_cistatic int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans, int nr) 11498c2ecf20Sopenharmony_ci{ 11508c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = trans->fs_info; 11518c2ecf20Sopenharmony_ci struct btrfs_delayed_root *delayed_root; 11528c2ecf20Sopenharmony_ci struct btrfs_delayed_node *curr_node, *prev_node; 11538c2ecf20Sopenharmony_ci struct btrfs_path *path; 11548c2ecf20Sopenharmony_ci struct btrfs_block_rsv *block_rsv; 11558c2ecf20Sopenharmony_ci int ret = 0; 11568c2ecf20Sopenharmony_ci bool count = (nr > 0); 11578c2ecf20Sopenharmony_ci 11588c2ecf20Sopenharmony_ci if (TRANS_ABORTED(trans)) 11598c2ecf20Sopenharmony_ci return -EIO; 11608c2ecf20Sopenharmony_ci 11618c2ecf20Sopenharmony_ci path = btrfs_alloc_path(); 11628c2ecf20Sopenharmony_ci if (!path) 11638c2ecf20Sopenharmony_ci return -ENOMEM; 11648c2ecf20Sopenharmony_ci path->leave_spinning = 1; 11658c2ecf20Sopenharmony_ci 11668c2ecf20Sopenharmony_ci block_rsv = trans->block_rsv; 11678c2ecf20Sopenharmony_ci trans->block_rsv = &fs_info->delayed_block_rsv; 11688c2ecf20Sopenharmony_ci 11698c2ecf20Sopenharmony_ci delayed_root = fs_info->delayed_root; 11708c2ecf20Sopenharmony_ci 11718c2ecf20Sopenharmony_ci curr_node = btrfs_first_delayed_node(delayed_root); 11728c2ecf20Sopenharmony_ci while (curr_node && (!count || (count && nr--))) { 11738c2ecf20Sopenharmony_ci ret = __btrfs_commit_inode_delayed_items(trans, path, 11748c2ecf20Sopenharmony_ci curr_node); 11758c2ecf20Sopenharmony_ci if (ret) { 11768c2ecf20Sopenharmony_ci btrfs_abort_transaction(trans, ret); 11778c2ecf20Sopenharmony_ci break; 11788c2ecf20Sopenharmony_ci } 11798c2ecf20Sopenharmony_ci 11808c2ecf20Sopenharmony_ci prev_node = curr_node; 11818c2ecf20Sopenharmony_ci curr_node = btrfs_next_delayed_node(curr_node); 11828c2ecf20Sopenharmony_ci /* 11838c2ecf20Sopenharmony_ci * See the comment below about releasing path before releasing 11848c2ecf20Sopenharmony_ci * node. If the commit of delayed items was successful the path 11858c2ecf20Sopenharmony_ci * should always be released, but in case of an error, it may 11868c2ecf20Sopenharmony_ci * point to locked extent buffers (a leaf at the very least). 11878c2ecf20Sopenharmony_ci */ 11888c2ecf20Sopenharmony_ci ASSERT(path->nodes[0] == NULL); 11898c2ecf20Sopenharmony_ci btrfs_release_delayed_node(prev_node); 11908c2ecf20Sopenharmony_ci } 11918c2ecf20Sopenharmony_ci 11928c2ecf20Sopenharmony_ci /* 11938c2ecf20Sopenharmony_ci * Release the path to avoid a potential deadlock and lockdep splat when 11948c2ecf20Sopenharmony_ci * releasing the delayed node, as that requires taking the delayed node's 11958c2ecf20Sopenharmony_ci * mutex. If another task starts running delayed items before we take 11968c2ecf20Sopenharmony_ci * the mutex, it will first lock the mutex and then it may try to lock 11978c2ecf20Sopenharmony_ci * the same btree path (leaf). 11988c2ecf20Sopenharmony_ci */ 11998c2ecf20Sopenharmony_ci btrfs_free_path(path); 12008c2ecf20Sopenharmony_ci 12018c2ecf20Sopenharmony_ci if (curr_node) 12028c2ecf20Sopenharmony_ci btrfs_release_delayed_node(curr_node); 12038c2ecf20Sopenharmony_ci trans->block_rsv = block_rsv; 12048c2ecf20Sopenharmony_ci 12058c2ecf20Sopenharmony_ci return ret; 12068c2ecf20Sopenharmony_ci} 12078c2ecf20Sopenharmony_ci 12088c2ecf20Sopenharmony_ciint btrfs_run_delayed_items(struct btrfs_trans_handle *trans) 12098c2ecf20Sopenharmony_ci{ 12108c2ecf20Sopenharmony_ci return __btrfs_run_delayed_items(trans, -1); 12118c2ecf20Sopenharmony_ci} 12128c2ecf20Sopenharmony_ci 12138c2ecf20Sopenharmony_ciint btrfs_run_delayed_items_nr(struct btrfs_trans_handle *trans, int nr) 12148c2ecf20Sopenharmony_ci{ 12158c2ecf20Sopenharmony_ci return __btrfs_run_delayed_items(trans, nr); 12168c2ecf20Sopenharmony_ci} 12178c2ecf20Sopenharmony_ci 12188c2ecf20Sopenharmony_ciint btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans, 12198c2ecf20Sopenharmony_ci struct btrfs_inode *inode) 12208c2ecf20Sopenharmony_ci{ 12218c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode); 12228c2ecf20Sopenharmony_ci struct btrfs_path *path; 12238c2ecf20Sopenharmony_ci struct btrfs_block_rsv *block_rsv; 12248c2ecf20Sopenharmony_ci int ret; 12258c2ecf20Sopenharmony_ci 12268c2ecf20Sopenharmony_ci if (!delayed_node) 12278c2ecf20Sopenharmony_ci return 0; 12288c2ecf20Sopenharmony_ci 12298c2ecf20Sopenharmony_ci mutex_lock(&delayed_node->mutex); 12308c2ecf20Sopenharmony_ci if (!delayed_node->count) { 12318c2ecf20Sopenharmony_ci mutex_unlock(&delayed_node->mutex); 12328c2ecf20Sopenharmony_ci btrfs_release_delayed_node(delayed_node); 12338c2ecf20Sopenharmony_ci return 0; 12348c2ecf20Sopenharmony_ci } 12358c2ecf20Sopenharmony_ci mutex_unlock(&delayed_node->mutex); 12368c2ecf20Sopenharmony_ci 12378c2ecf20Sopenharmony_ci path = btrfs_alloc_path(); 12388c2ecf20Sopenharmony_ci if (!path) { 12398c2ecf20Sopenharmony_ci btrfs_release_delayed_node(delayed_node); 12408c2ecf20Sopenharmony_ci return -ENOMEM; 12418c2ecf20Sopenharmony_ci } 12428c2ecf20Sopenharmony_ci path->leave_spinning = 1; 12438c2ecf20Sopenharmony_ci 12448c2ecf20Sopenharmony_ci block_rsv = trans->block_rsv; 12458c2ecf20Sopenharmony_ci trans->block_rsv = &delayed_node->root->fs_info->delayed_block_rsv; 12468c2ecf20Sopenharmony_ci 12478c2ecf20Sopenharmony_ci ret = __btrfs_commit_inode_delayed_items(trans, path, delayed_node); 12488c2ecf20Sopenharmony_ci 12498c2ecf20Sopenharmony_ci btrfs_release_delayed_node(delayed_node); 12508c2ecf20Sopenharmony_ci btrfs_free_path(path); 12518c2ecf20Sopenharmony_ci trans->block_rsv = block_rsv; 12528c2ecf20Sopenharmony_ci 12538c2ecf20Sopenharmony_ci return ret; 12548c2ecf20Sopenharmony_ci} 12558c2ecf20Sopenharmony_ci 12568c2ecf20Sopenharmony_ciint btrfs_commit_inode_delayed_inode(struct btrfs_inode *inode) 12578c2ecf20Sopenharmony_ci{ 12588c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = inode->root->fs_info; 12598c2ecf20Sopenharmony_ci struct btrfs_trans_handle *trans; 12608c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode); 12618c2ecf20Sopenharmony_ci struct btrfs_path *path; 12628c2ecf20Sopenharmony_ci struct btrfs_block_rsv *block_rsv; 12638c2ecf20Sopenharmony_ci int ret; 12648c2ecf20Sopenharmony_ci 12658c2ecf20Sopenharmony_ci if (!delayed_node) 12668c2ecf20Sopenharmony_ci return 0; 12678c2ecf20Sopenharmony_ci 12688c2ecf20Sopenharmony_ci mutex_lock(&delayed_node->mutex); 12698c2ecf20Sopenharmony_ci if (!test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags)) { 12708c2ecf20Sopenharmony_ci mutex_unlock(&delayed_node->mutex); 12718c2ecf20Sopenharmony_ci btrfs_release_delayed_node(delayed_node); 12728c2ecf20Sopenharmony_ci return 0; 12738c2ecf20Sopenharmony_ci } 12748c2ecf20Sopenharmony_ci mutex_unlock(&delayed_node->mutex); 12758c2ecf20Sopenharmony_ci 12768c2ecf20Sopenharmony_ci trans = btrfs_join_transaction(delayed_node->root); 12778c2ecf20Sopenharmony_ci if (IS_ERR(trans)) { 12788c2ecf20Sopenharmony_ci ret = PTR_ERR(trans); 12798c2ecf20Sopenharmony_ci goto out; 12808c2ecf20Sopenharmony_ci } 12818c2ecf20Sopenharmony_ci 12828c2ecf20Sopenharmony_ci path = btrfs_alloc_path(); 12838c2ecf20Sopenharmony_ci if (!path) { 12848c2ecf20Sopenharmony_ci ret = -ENOMEM; 12858c2ecf20Sopenharmony_ci goto trans_out; 12868c2ecf20Sopenharmony_ci } 12878c2ecf20Sopenharmony_ci path->leave_spinning = 1; 12888c2ecf20Sopenharmony_ci 12898c2ecf20Sopenharmony_ci block_rsv = trans->block_rsv; 12908c2ecf20Sopenharmony_ci trans->block_rsv = &fs_info->delayed_block_rsv; 12918c2ecf20Sopenharmony_ci 12928c2ecf20Sopenharmony_ci mutex_lock(&delayed_node->mutex); 12938c2ecf20Sopenharmony_ci if (test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags)) 12948c2ecf20Sopenharmony_ci ret = __btrfs_update_delayed_inode(trans, delayed_node->root, 12958c2ecf20Sopenharmony_ci path, delayed_node); 12968c2ecf20Sopenharmony_ci else 12978c2ecf20Sopenharmony_ci ret = 0; 12988c2ecf20Sopenharmony_ci mutex_unlock(&delayed_node->mutex); 12998c2ecf20Sopenharmony_ci 13008c2ecf20Sopenharmony_ci btrfs_free_path(path); 13018c2ecf20Sopenharmony_ci trans->block_rsv = block_rsv; 13028c2ecf20Sopenharmony_citrans_out: 13038c2ecf20Sopenharmony_ci btrfs_end_transaction(trans); 13048c2ecf20Sopenharmony_ci btrfs_btree_balance_dirty(fs_info); 13058c2ecf20Sopenharmony_ciout: 13068c2ecf20Sopenharmony_ci btrfs_release_delayed_node(delayed_node); 13078c2ecf20Sopenharmony_ci 13088c2ecf20Sopenharmony_ci return ret; 13098c2ecf20Sopenharmony_ci} 13108c2ecf20Sopenharmony_ci 13118c2ecf20Sopenharmony_civoid btrfs_remove_delayed_node(struct btrfs_inode *inode) 13128c2ecf20Sopenharmony_ci{ 13138c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_node; 13148c2ecf20Sopenharmony_ci 13158c2ecf20Sopenharmony_ci delayed_node = READ_ONCE(inode->delayed_node); 13168c2ecf20Sopenharmony_ci if (!delayed_node) 13178c2ecf20Sopenharmony_ci return; 13188c2ecf20Sopenharmony_ci 13198c2ecf20Sopenharmony_ci inode->delayed_node = NULL; 13208c2ecf20Sopenharmony_ci btrfs_release_delayed_node(delayed_node); 13218c2ecf20Sopenharmony_ci} 13228c2ecf20Sopenharmony_ci 13238c2ecf20Sopenharmony_cistruct btrfs_async_delayed_work { 13248c2ecf20Sopenharmony_ci struct btrfs_delayed_root *delayed_root; 13258c2ecf20Sopenharmony_ci int nr; 13268c2ecf20Sopenharmony_ci struct btrfs_work work; 13278c2ecf20Sopenharmony_ci}; 13288c2ecf20Sopenharmony_ci 13298c2ecf20Sopenharmony_cistatic void btrfs_async_run_delayed_root(struct btrfs_work *work) 13308c2ecf20Sopenharmony_ci{ 13318c2ecf20Sopenharmony_ci struct btrfs_async_delayed_work *async_work; 13328c2ecf20Sopenharmony_ci struct btrfs_delayed_root *delayed_root; 13338c2ecf20Sopenharmony_ci struct btrfs_trans_handle *trans; 13348c2ecf20Sopenharmony_ci struct btrfs_path *path; 13358c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_node = NULL; 13368c2ecf20Sopenharmony_ci struct btrfs_root *root; 13378c2ecf20Sopenharmony_ci struct btrfs_block_rsv *block_rsv; 13388c2ecf20Sopenharmony_ci int total_done = 0; 13398c2ecf20Sopenharmony_ci 13408c2ecf20Sopenharmony_ci async_work = container_of(work, struct btrfs_async_delayed_work, work); 13418c2ecf20Sopenharmony_ci delayed_root = async_work->delayed_root; 13428c2ecf20Sopenharmony_ci 13438c2ecf20Sopenharmony_ci path = btrfs_alloc_path(); 13448c2ecf20Sopenharmony_ci if (!path) 13458c2ecf20Sopenharmony_ci goto out; 13468c2ecf20Sopenharmony_ci 13478c2ecf20Sopenharmony_ci do { 13488c2ecf20Sopenharmony_ci if (atomic_read(&delayed_root->items) < 13498c2ecf20Sopenharmony_ci BTRFS_DELAYED_BACKGROUND / 2) 13508c2ecf20Sopenharmony_ci break; 13518c2ecf20Sopenharmony_ci 13528c2ecf20Sopenharmony_ci delayed_node = btrfs_first_prepared_delayed_node(delayed_root); 13538c2ecf20Sopenharmony_ci if (!delayed_node) 13548c2ecf20Sopenharmony_ci break; 13558c2ecf20Sopenharmony_ci 13568c2ecf20Sopenharmony_ci path->leave_spinning = 1; 13578c2ecf20Sopenharmony_ci root = delayed_node->root; 13588c2ecf20Sopenharmony_ci 13598c2ecf20Sopenharmony_ci trans = btrfs_join_transaction(root); 13608c2ecf20Sopenharmony_ci if (IS_ERR(trans)) { 13618c2ecf20Sopenharmony_ci btrfs_release_path(path); 13628c2ecf20Sopenharmony_ci btrfs_release_prepared_delayed_node(delayed_node); 13638c2ecf20Sopenharmony_ci total_done++; 13648c2ecf20Sopenharmony_ci continue; 13658c2ecf20Sopenharmony_ci } 13668c2ecf20Sopenharmony_ci 13678c2ecf20Sopenharmony_ci block_rsv = trans->block_rsv; 13688c2ecf20Sopenharmony_ci trans->block_rsv = &root->fs_info->delayed_block_rsv; 13698c2ecf20Sopenharmony_ci 13708c2ecf20Sopenharmony_ci __btrfs_commit_inode_delayed_items(trans, path, delayed_node); 13718c2ecf20Sopenharmony_ci 13728c2ecf20Sopenharmony_ci trans->block_rsv = block_rsv; 13738c2ecf20Sopenharmony_ci btrfs_end_transaction(trans); 13748c2ecf20Sopenharmony_ci btrfs_btree_balance_dirty_nodelay(root->fs_info); 13758c2ecf20Sopenharmony_ci 13768c2ecf20Sopenharmony_ci btrfs_release_path(path); 13778c2ecf20Sopenharmony_ci btrfs_release_prepared_delayed_node(delayed_node); 13788c2ecf20Sopenharmony_ci total_done++; 13798c2ecf20Sopenharmony_ci 13808c2ecf20Sopenharmony_ci } while ((async_work->nr == 0 && total_done < BTRFS_DELAYED_WRITEBACK) 13818c2ecf20Sopenharmony_ci || total_done < async_work->nr); 13828c2ecf20Sopenharmony_ci 13838c2ecf20Sopenharmony_ci btrfs_free_path(path); 13848c2ecf20Sopenharmony_ciout: 13858c2ecf20Sopenharmony_ci wake_up(&delayed_root->wait); 13868c2ecf20Sopenharmony_ci kfree(async_work); 13878c2ecf20Sopenharmony_ci} 13888c2ecf20Sopenharmony_ci 13898c2ecf20Sopenharmony_ci 13908c2ecf20Sopenharmony_cistatic int btrfs_wq_run_delayed_node(struct btrfs_delayed_root *delayed_root, 13918c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info, int nr) 13928c2ecf20Sopenharmony_ci{ 13938c2ecf20Sopenharmony_ci struct btrfs_async_delayed_work *async_work; 13948c2ecf20Sopenharmony_ci 13958c2ecf20Sopenharmony_ci async_work = kmalloc(sizeof(*async_work), GFP_NOFS); 13968c2ecf20Sopenharmony_ci if (!async_work) 13978c2ecf20Sopenharmony_ci return -ENOMEM; 13988c2ecf20Sopenharmony_ci 13998c2ecf20Sopenharmony_ci async_work->delayed_root = delayed_root; 14008c2ecf20Sopenharmony_ci btrfs_init_work(&async_work->work, btrfs_async_run_delayed_root, NULL, 14018c2ecf20Sopenharmony_ci NULL); 14028c2ecf20Sopenharmony_ci async_work->nr = nr; 14038c2ecf20Sopenharmony_ci 14048c2ecf20Sopenharmony_ci btrfs_queue_work(fs_info->delayed_workers, &async_work->work); 14058c2ecf20Sopenharmony_ci return 0; 14068c2ecf20Sopenharmony_ci} 14078c2ecf20Sopenharmony_ci 14088c2ecf20Sopenharmony_civoid btrfs_assert_delayed_root_empty(struct btrfs_fs_info *fs_info) 14098c2ecf20Sopenharmony_ci{ 14108c2ecf20Sopenharmony_ci WARN_ON(btrfs_first_delayed_node(fs_info->delayed_root)); 14118c2ecf20Sopenharmony_ci} 14128c2ecf20Sopenharmony_ci 14138c2ecf20Sopenharmony_cistatic int could_end_wait(struct btrfs_delayed_root *delayed_root, int seq) 14148c2ecf20Sopenharmony_ci{ 14158c2ecf20Sopenharmony_ci int val = atomic_read(&delayed_root->items_seq); 14168c2ecf20Sopenharmony_ci 14178c2ecf20Sopenharmony_ci if (val < seq || val >= seq + BTRFS_DELAYED_BATCH) 14188c2ecf20Sopenharmony_ci return 1; 14198c2ecf20Sopenharmony_ci 14208c2ecf20Sopenharmony_ci if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND) 14218c2ecf20Sopenharmony_ci return 1; 14228c2ecf20Sopenharmony_ci 14238c2ecf20Sopenharmony_ci return 0; 14248c2ecf20Sopenharmony_ci} 14258c2ecf20Sopenharmony_ci 14268c2ecf20Sopenharmony_civoid btrfs_balance_delayed_items(struct btrfs_fs_info *fs_info) 14278c2ecf20Sopenharmony_ci{ 14288c2ecf20Sopenharmony_ci struct btrfs_delayed_root *delayed_root = fs_info->delayed_root; 14298c2ecf20Sopenharmony_ci 14308c2ecf20Sopenharmony_ci if ((atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND) || 14318c2ecf20Sopenharmony_ci btrfs_workqueue_normal_congested(fs_info->delayed_workers)) 14328c2ecf20Sopenharmony_ci return; 14338c2ecf20Sopenharmony_ci 14348c2ecf20Sopenharmony_ci if (atomic_read(&delayed_root->items) >= BTRFS_DELAYED_WRITEBACK) { 14358c2ecf20Sopenharmony_ci int seq; 14368c2ecf20Sopenharmony_ci int ret; 14378c2ecf20Sopenharmony_ci 14388c2ecf20Sopenharmony_ci seq = atomic_read(&delayed_root->items_seq); 14398c2ecf20Sopenharmony_ci 14408c2ecf20Sopenharmony_ci ret = btrfs_wq_run_delayed_node(delayed_root, fs_info, 0); 14418c2ecf20Sopenharmony_ci if (ret) 14428c2ecf20Sopenharmony_ci return; 14438c2ecf20Sopenharmony_ci 14448c2ecf20Sopenharmony_ci wait_event_interruptible(delayed_root->wait, 14458c2ecf20Sopenharmony_ci could_end_wait(delayed_root, seq)); 14468c2ecf20Sopenharmony_ci return; 14478c2ecf20Sopenharmony_ci } 14488c2ecf20Sopenharmony_ci 14498c2ecf20Sopenharmony_ci btrfs_wq_run_delayed_node(delayed_root, fs_info, BTRFS_DELAYED_BATCH); 14508c2ecf20Sopenharmony_ci} 14518c2ecf20Sopenharmony_ci 14528c2ecf20Sopenharmony_ci/* Will return 0 or -ENOMEM */ 14538c2ecf20Sopenharmony_ciint btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans, 14548c2ecf20Sopenharmony_ci const char *name, int name_len, 14558c2ecf20Sopenharmony_ci struct btrfs_inode *dir, 14568c2ecf20Sopenharmony_ci struct btrfs_disk_key *disk_key, u8 type, 14578c2ecf20Sopenharmony_ci u64 index) 14588c2ecf20Sopenharmony_ci{ 14598c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_node; 14608c2ecf20Sopenharmony_ci struct btrfs_delayed_item *delayed_item; 14618c2ecf20Sopenharmony_ci struct btrfs_dir_item *dir_item; 14628c2ecf20Sopenharmony_ci int ret; 14638c2ecf20Sopenharmony_ci 14648c2ecf20Sopenharmony_ci delayed_node = btrfs_get_or_create_delayed_node(dir); 14658c2ecf20Sopenharmony_ci if (IS_ERR(delayed_node)) 14668c2ecf20Sopenharmony_ci return PTR_ERR(delayed_node); 14678c2ecf20Sopenharmony_ci 14688c2ecf20Sopenharmony_ci delayed_item = btrfs_alloc_delayed_item(sizeof(*dir_item) + name_len); 14698c2ecf20Sopenharmony_ci if (!delayed_item) { 14708c2ecf20Sopenharmony_ci ret = -ENOMEM; 14718c2ecf20Sopenharmony_ci goto release_node; 14728c2ecf20Sopenharmony_ci } 14738c2ecf20Sopenharmony_ci 14748c2ecf20Sopenharmony_ci delayed_item->key.objectid = btrfs_ino(dir); 14758c2ecf20Sopenharmony_ci delayed_item->key.type = BTRFS_DIR_INDEX_KEY; 14768c2ecf20Sopenharmony_ci delayed_item->key.offset = index; 14778c2ecf20Sopenharmony_ci 14788c2ecf20Sopenharmony_ci dir_item = (struct btrfs_dir_item *)delayed_item->data; 14798c2ecf20Sopenharmony_ci dir_item->location = *disk_key; 14808c2ecf20Sopenharmony_ci btrfs_set_stack_dir_transid(dir_item, trans->transid); 14818c2ecf20Sopenharmony_ci btrfs_set_stack_dir_data_len(dir_item, 0); 14828c2ecf20Sopenharmony_ci btrfs_set_stack_dir_name_len(dir_item, name_len); 14838c2ecf20Sopenharmony_ci btrfs_set_stack_dir_type(dir_item, type); 14848c2ecf20Sopenharmony_ci memcpy((char *)(dir_item + 1), name, name_len); 14858c2ecf20Sopenharmony_ci 14868c2ecf20Sopenharmony_ci ret = btrfs_delayed_item_reserve_metadata(trans, dir->root, delayed_item); 14878c2ecf20Sopenharmony_ci /* 14888c2ecf20Sopenharmony_ci * we have reserved enough space when we start a new transaction, 14898c2ecf20Sopenharmony_ci * so reserving metadata failure is impossible 14908c2ecf20Sopenharmony_ci */ 14918c2ecf20Sopenharmony_ci BUG_ON(ret); 14928c2ecf20Sopenharmony_ci 14938c2ecf20Sopenharmony_ci mutex_lock(&delayed_node->mutex); 14948c2ecf20Sopenharmony_ci ret = __btrfs_add_delayed_insertion_item(delayed_node, delayed_item); 14958c2ecf20Sopenharmony_ci if (unlikely(ret)) { 14968c2ecf20Sopenharmony_ci btrfs_err(trans->fs_info, 14978c2ecf20Sopenharmony_ci "err add delayed dir index item(name: %.*s) into the insertion tree of the delayed node(root id: %llu, inode id: %llu, errno: %d)", 14988c2ecf20Sopenharmony_ci name_len, name, delayed_node->root->root_key.objectid, 14998c2ecf20Sopenharmony_ci delayed_node->inode_id, ret); 15008c2ecf20Sopenharmony_ci BUG(); 15018c2ecf20Sopenharmony_ci } 15028c2ecf20Sopenharmony_ci mutex_unlock(&delayed_node->mutex); 15038c2ecf20Sopenharmony_ci 15048c2ecf20Sopenharmony_cirelease_node: 15058c2ecf20Sopenharmony_ci btrfs_release_delayed_node(delayed_node); 15068c2ecf20Sopenharmony_ci return ret; 15078c2ecf20Sopenharmony_ci} 15088c2ecf20Sopenharmony_ci 15098c2ecf20Sopenharmony_cistatic int btrfs_delete_delayed_insertion_item(struct btrfs_fs_info *fs_info, 15108c2ecf20Sopenharmony_ci struct btrfs_delayed_node *node, 15118c2ecf20Sopenharmony_ci struct btrfs_key *key) 15128c2ecf20Sopenharmony_ci{ 15138c2ecf20Sopenharmony_ci struct btrfs_delayed_item *item; 15148c2ecf20Sopenharmony_ci 15158c2ecf20Sopenharmony_ci mutex_lock(&node->mutex); 15168c2ecf20Sopenharmony_ci item = __btrfs_lookup_delayed_insertion_item(node, key); 15178c2ecf20Sopenharmony_ci if (!item) { 15188c2ecf20Sopenharmony_ci mutex_unlock(&node->mutex); 15198c2ecf20Sopenharmony_ci return 1; 15208c2ecf20Sopenharmony_ci } 15218c2ecf20Sopenharmony_ci 15228c2ecf20Sopenharmony_ci btrfs_delayed_item_release_metadata(node->root, item); 15238c2ecf20Sopenharmony_ci btrfs_release_delayed_item(item); 15248c2ecf20Sopenharmony_ci mutex_unlock(&node->mutex); 15258c2ecf20Sopenharmony_ci return 0; 15268c2ecf20Sopenharmony_ci} 15278c2ecf20Sopenharmony_ci 15288c2ecf20Sopenharmony_ciint btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans, 15298c2ecf20Sopenharmony_ci struct btrfs_inode *dir, u64 index) 15308c2ecf20Sopenharmony_ci{ 15318c2ecf20Sopenharmony_ci struct btrfs_delayed_node *node; 15328c2ecf20Sopenharmony_ci struct btrfs_delayed_item *item; 15338c2ecf20Sopenharmony_ci struct btrfs_key item_key; 15348c2ecf20Sopenharmony_ci int ret; 15358c2ecf20Sopenharmony_ci 15368c2ecf20Sopenharmony_ci node = btrfs_get_or_create_delayed_node(dir); 15378c2ecf20Sopenharmony_ci if (IS_ERR(node)) 15388c2ecf20Sopenharmony_ci return PTR_ERR(node); 15398c2ecf20Sopenharmony_ci 15408c2ecf20Sopenharmony_ci item_key.objectid = btrfs_ino(dir); 15418c2ecf20Sopenharmony_ci item_key.type = BTRFS_DIR_INDEX_KEY; 15428c2ecf20Sopenharmony_ci item_key.offset = index; 15438c2ecf20Sopenharmony_ci 15448c2ecf20Sopenharmony_ci ret = btrfs_delete_delayed_insertion_item(trans->fs_info, node, 15458c2ecf20Sopenharmony_ci &item_key); 15468c2ecf20Sopenharmony_ci if (!ret) 15478c2ecf20Sopenharmony_ci goto end; 15488c2ecf20Sopenharmony_ci 15498c2ecf20Sopenharmony_ci item = btrfs_alloc_delayed_item(0); 15508c2ecf20Sopenharmony_ci if (!item) { 15518c2ecf20Sopenharmony_ci ret = -ENOMEM; 15528c2ecf20Sopenharmony_ci goto end; 15538c2ecf20Sopenharmony_ci } 15548c2ecf20Sopenharmony_ci 15558c2ecf20Sopenharmony_ci item->key = item_key; 15568c2ecf20Sopenharmony_ci 15578c2ecf20Sopenharmony_ci ret = btrfs_delayed_item_reserve_metadata(trans, dir->root, item); 15588c2ecf20Sopenharmony_ci /* 15598c2ecf20Sopenharmony_ci * we have reserved enough space when we start a new transaction, 15608c2ecf20Sopenharmony_ci * so reserving metadata failure is impossible. 15618c2ecf20Sopenharmony_ci */ 15628c2ecf20Sopenharmony_ci if (ret < 0) { 15638c2ecf20Sopenharmony_ci btrfs_err(trans->fs_info, 15648c2ecf20Sopenharmony_ci"metadata reservation failed for delayed dir item deltiona, should have been reserved"); 15658c2ecf20Sopenharmony_ci btrfs_release_delayed_item(item); 15668c2ecf20Sopenharmony_ci goto end; 15678c2ecf20Sopenharmony_ci } 15688c2ecf20Sopenharmony_ci 15698c2ecf20Sopenharmony_ci mutex_lock(&node->mutex); 15708c2ecf20Sopenharmony_ci ret = __btrfs_add_delayed_deletion_item(node, item); 15718c2ecf20Sopenharmony_ci if (unlikely(ret)) { 15728c2ecf20Sopenharmony_ci btrfs_err(trans->fs_info, 15738c2ecf20Sopenharmony_ci "err add delayed dir index item(index: %llu) into the deletion tree of the delayed node(root id: %llu, inode id: %llu, errno: %d)", 15748c2ecf20Sopenharmony_ci index, node->root->root_key.objectid, 15758c2ecf20Sopenharmony_ci node->inode_id, ret); 15768c2ecf20Sopenharmony_ci btrfs_delayed_item_release_metadata(dir->root, item); 15778c2ecf20Sopenharmony_ci btrfs_release_delayed_item(item); 15788c2ecf20Sopenharmony_ci } 15798c2ecf20Sopenharmony_ci mutex_unlock(&node->mutex); 15808c2ecf20Sopenharmony_ciend: 15818c2ecf20Sopenharmony_ci btrfs_release_delayed_node(node); 15828c2ecf20Sopenharmony_ci return ret; 15838c2ecf20Sopenharmony_ci} 15848c2ecf20Sopenharmony_ci 15858c2ecf20Sopenharmony_ciint btrfs_inode_delayed_dir_index_count(struct btrfs_inode *inode) 15868c2ecf20Sopenharmony_ci{ 15878c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode); 15888c2ecf20Sopenharmony_ci 15898c2ecf20Sopenharmony_ci if (!delayed_node) 15908c2ecf20Sopenharmony_ci return -ENOENT; 15918c2ecf20Sopenharmony_ci 15928c2ecf20Sopenharmony_ci /* 15938c2ecf20Sopenharmony_ci * Since we have held i_mutex of this directory, it is impossible that 15948c2ecf20Sopenharmony_ci * a new directory index is added into the delayed node and index_cnt 15958c2ecf20Sopenharmony_ci * is updated now. So we needn't lock the delayed node. 15968c2ecf20Sopenharmony_ci */ 15978c2ecf20Sopenharmony_ci if (!delayed_node->index_cnt) { 15988c2ecf20Sopenharmony_ci btrfs_release_delayed_node(delayed_node); 15998c2ecf20Sopenharmony_ci return -EINVAL; 16008c2ecf20Sopenharmony_ci } 16018c2ecf20Sopenharmony_ci 16028c2ecf20Sopenharmony_ci inode->index_cnt = delayed_node->index_cnt; 16038c2ecf20Sopenharmony_ci btrfs_release_delayed_node(delayed_node); 16048c2ecf20Sopenharmony_ci return 0; 16058c2ecf20Sopenharmony_ci} 16068c2ecf20Sopenharmony_ci 16078c2ecf20Sopenharmony_cibool btrfs_readdir_get_delayed_items(struct inode *inode, 16088c2ecf20Sopenharmony_ci struct list_head *ins_list, 16098c2ecf20Sopenharmony_ci struct list_head *del_list) 16108c2ecf20Sopenharmony_ci{ 16118c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_node; 16128c2ecf20Sopenharmony_ci struct btrfs_delayed_item *item; 16138c2ecf20Sopenharmony_ci 16148c2ecf20Sopenharmony_ci delayed_node = btrfs_get_delayed_node(BTRFS_I(inode)); 16158c2ecf20Sopenharmony_ci if (!delayed_node) 16168c2ecf20Sopenharmony_ci return false; 16178c2ecf20Sopenharmony_ci 16188c2ecf20Sopenharmony_ci /* 16198c2ecf20Sopenharmony_ci * We can only do one readdir with delayed items at a time because of 16208c2ecf20Sopenharmony_ci * item->readdir_list. 16218c2ecf20Sopenharmony_ci */ 16228c2ecf20Sopenharmony_ci inode_unlock_shared(inode); 16238c2ecf20Sopenharmony_ci inode_lock(inode); 16248c2ecf20Sopenharmony_ci 16258c2ecf20Sopenharmony_ci mutex_lock(&delayed_node->mutex); 16268c2ecf20Sopenharmony_ci item = __btrfs_first_delayed_insertion_item(delayed_node); 16278c2ecf20Sopenharmony_ci while (item) { 16288c2ecf20Sopenharmony_ci refcount_inc(&item->refs); 16298c2ecf20Sopenharmony_ci list_add_tail(&item->readdir_list, ins_list); 16308c2ecf20Sopenharmony_ci item = __btrfs_next_delayed_item(item); 16318c2ecf20Sopenharmony_ci } 16328c2ecf20Sopenharmony_ci 16338c2ecf20Sopenharmony_ci item = __btrfs_first_delayed_deletion_item(delayed_node); 16348c2ecf20Sopenharmony_ci while (item) { 16358c2ecf20Sopenharmony_ci refcount_inc(&item->refs); 16368c2ecf20Sopenharmony_ci list_add_tail(&item->readdir_list, del_list); 16378c2ecf20Sopenharmony_ci item = __btrfs_next_delayed_item(item); 16388c2ecf20Sopenharmony_ci } 16398c2ecf20Sopenharmony_ci mutex_unlock(&delayed_node->mutex); 16408c2ecf20Sopenharmony_ci /* 16418c2ecf20Sopenharmony_ci * This delayed node is still cached in the btrfs inode, so refs 16428c2ecf20Sopenharmony_ci * must be > 1 now, and we needn't check it is going to be freed 16438c2ecf20Sopenharmony_ci * or not. 16448c2ecf20Sopenharmony_ci * 16458c2ecf20Sopenharmony_ci * Besides that, this function is used to read dir, we do not 16468c2ecf20Sopenharmony_ci * insert/delete delayed items in this period. So we also needn't 16478c2ecf20Sopenharmony_ci * requeue or dequeue this delayed node. 16488c2ecf20Sopenharmony_ci */ 16498c2ecf20Sopenharmony_ci refcount_dec(&delayed_node->refs); 16508c2ecf20Sopenharmony_ci 16518c2ecf20Sopenharmony_ci return true; 16528c2ecf20Sopenharmony_ci} 16538c2ecf20Sopenharmony_ci 16548c2ecf20Sopenharmony_civoid btrfs_readdir_put_delayed_items(struct inode *inode, 16558c2ecf20Sopenharmony_ci struct list_head *ins_list, 16568c2ecf20Sopenharmony_ci struct list_head *del_list) 16578c2ecf20Sopenharmony_ci{ 16588c2ecf20Sopenharmony_ci struct btrfs_delayed_item *curr, *next; 16598c2ecf20Sopenharmony_ci 16608c2ecf20Sopenharmony_ci list_for_each_entry_safe(curr, next, ins_list, readdir_list) { 16618c2ecf20Sopenharmony_ci list_del(&curr->readdir_list); 16628c2ecf20Sopenharmony_ci if (refcount_dec_and_test(&curr->refs)) 16638c2ecf20Sopenharmony_ci kfree(curr); 16648c2ecf20Sopenharmony_ci } 16658c2ecf20Sopenharmony_ci 16668c2ecf20Sopenharmony_ci list_for_each_entry_safe(curr, next, del_list, readdir_list) { 16678c2ecf20Sopenharmony_ci list_del(&curr->readdir_list); 16688c2ecf20Sopenharmony_ci if (refcount_dec_and_test(&curr->refs)) 16698c2ecf20Sopenharmony_ci kfree(curr); 16708c2ecf20Sopenharmony_ci } 16718c2ecf20Sopenharmony_ci 16728c2ecf20Sopenharmony_ci /* 16738c2ecf20Sopenharmony_ci * The VFS is going to do up_read(), so we need to downgrade back to a 16748c2ecf20Sopenharmony_ci * read lock. 16758c2ecf20Sopenharmony_ci */ 16768c2ecf20Sopenharmony_ci downgrade_write(&inode->i_rwsem); 16778c2ecf20Sopenharmony_ci} 16788c2ecf20Sopenharmony_ci 16798c2ecf20Sopenharmony_ciint btrfs_should_delete_dir_index(struct list_head *del_list, 16808c2ecf20Sopenharmony_ci u64 index) 16818c2ecf20Sopenharmony_ci{ 16828c2ecf20Sopenharmony_ci struct btrfs_delayed_item *curr; 16838c2ecf20Sopenharmony_ci int ret = 0; 16848c2ecf20Sopenharmony_ci 16858c2ecf20Sopenharmony_ci list_for_each_entry(curr, del_list, readdir_list) { 16868c2ecf20Sopenharmony_ci if (curr->key.offset > index) 16878c2ecf20Sopenharmony_ci break; 16888c2ecf20Sopenharmony_ci if (curr->key.offset == index) { 16898c2ecf20Sopenharmony_ci ret = 1; 16908c2ecf20Sopenharmony_ci break; 16918c2ecf20Sopenharmony_ci } 16928c2ecf20Sopenharmony_ci } 16938c2ecf20Sopenharmony_ci return ret; 16948c2ecf20Sopenharmony_ci} 16958c2ecf20Sopenharmony_ci 16968c2ecf20Sopenharmony_ci/* 16978c2ecf20Sopenharmony_ci * btrfs_readdir_delayed_dir_index - read dir info stored in the delayed tree 16988c2ecf20Sopenharmony_ci * 16998c2ecf20Sopenharmony_ci */ 17008c2ecf20Sopenharmony_ciint btrfs_readdir_delayed_dir_index(struct dir_context *ctx, 17018c2ecf20Sopenharmony_ci struct list_head *ins_list) 17028c2ecf20Sopenharmony_ci{ 17038c2ecf20Sopenharmony_ci struct btrfs_dir_item *di; 17048c2ecf20Sopenharmony_ci struct btrfs_delayed_item *curr, *next; 17058c2ecf20Sopenharmony_ci struct btrfs_key location; 17068c2ecf20Sopenharmony_ci char *name; 17078c2ecf20Sopenharmony_ci int name_len; 17088c2ecf20Sopenharmony_ci int over = 0; 17098c2ecf20Sopenharmony_ci unsigned char d_type; 17108c2ecf20Sopenharmony_ci 17118c2ecf20Sopenharmony_ci if (list_empty(ins_list)) 17128c2ecf20Sopenharmony_ci return 0; 17138c2ecf20Sopenharmony_ci 17148c2ecf20Sopenharmony_ci /* 17158c2ecf20Sopenharmony_ci * Changing the data of the delayed item is impossible. So 17168c2ecf20Sopenharmony_ci * we needn't lock them. And we have held i_mutex of the 17178c2ecf20Sopenharmony_ci * directory, nobody can delete any directory indexes now. 17188c2ecf20Sopenharmony_ci */ 17198c2ecf20Sopenharmony_ci list_for_each_entry_safe(curr, next, ins_list, readdir_list) { 17208c2ecf20Sopenharmony_ci list_del(&curr->readdir_list); 17218c2ecf20Sopenharmony_ci 17228c2ecf20Sopenharmony_ci if (curr->key.offset < ctx->pos) { 17238c2ecf20Sopenharmony_ci if (refcount_dec_and_test(&curr->refs)) 17248c2ecf20Sopenharmony_ci kfree(curr); 17258c2ecf20Sopenharmony_ci continue; 17268c2ecf20Sopenharmony_ci } 17278c2ecf20Sopenharmony_ci 17288c2ecf20Sopenharmony_ci ctx->pos = curr->key.offset; 17298c2ecf20Sopenharmony_ci 17308c2ecf20Sopenharmony_ci di = (struct btrfs_dir_item *)curr->data; 17318c2ecf20Sopenharmony_ci name = (char *)(di + 1); 17328c2ecf20Sopenharmony_ci name_len = btrfs_stack_dir_name_len(di); 17338c2ecf20Sopenharmony_ci 17348c2ecf20Sopenharmony_ci d_type = fs_ftype_to_dtype(di->type); 17358c2ecf20Sopenharmony_ci btrfs_disk_key_to_cpu(&location, &di->location); 17368c2ecf20Sopenharmony_ci 17378c2ecf20Sopenharmony_ci over = !dir_emit(ctx, name, name_len, 17388c2ecf20Sopenharmony_ci location.objectid, d_type); 17398c2ecf20Sopenharmony_ci 17408c2ecf20Sopenharmony_ci if (refcount_dec_and_test(&curr->refs)) 17418c2ecf20Sopenharmony_ci kfree(curr); 17428c2ecf20Sopenharmony_ci 17438c2ecf20Sopenharmony_ci if (over) 17448c2ecf20Sopenharmony_ci return 1; 17458c2ecf20Sopenharmony_ci ctx->pos++; 17468c2ecf20Sopenharmony_ci } 17478c2ecf20Sopenharmony_ci return 0; 17488c2ecf20Sopenharmony_ci} 17498c2ecf20Sopenharmony_ci 17508c2ecf20Sopenharmony_cistatic void fill_stack_inode_item(struct btrfs_trans_handle *trans, 17518c2ecf20Sopenharmony_ci struct btrfs_inode_item *inode_item, 17528c2ecf20Sopenharmony_ci struct inode *inode) 17538c2ecf20Sopenharmony_ci{ 17548c2ecf20Sopenharmony_ci btrfs_set_stack_inode_uid(inode_item, i_uid_read(inode)); 17558c2ecf20Sopenharmony_ci btrfs_set_stack_inode_gid(inode_item, i_gid_read(inode)); 17568c2ecf20Sopenharmony_ci btrfs_set_stack_inode_size(inode_item, BTRFS_I(inode)->disk_i_size); 17578c2ecf20Sopenharmony_ci btrfs_set_stack_inode_mode(inode_item, inode->i_mode); 17588c2ecf20Sopenharmony_ci btrfs_set_stack_inode_nlink(inode_item, inode->i_nlink); 17598c2ecf20Sopenharmony_ci btrfs_set_stack_inode_nbytes(inode_item, inode_get_bytes(inode)); 17608c2ecf20Sopenharmony_ci btrfs_set_stack_inode_generation(inode_item, 17618c2ecf20Sopenharmony_ci BTRFS_I(inode)->generation); 17628c2ecf20Sopenharmony_ci btrfs_set_stack_inode_sequence(inode_item, 17638c2ecf20Sopenharmony_ci inode_peek_iversion(inode)); 17648c2ecf20Sopenharmony_ci btrfs_set_stack_inode_transid(inode_item, trans->transid); 17658c2ecf20Sopenharmony_ci btrfs_set_stack_inode_rdev(inode_item, inode->i_rdev); 17668c2ecf20Sopenharmony_ci btrfs_set_stack_inode_flags(inode_item, BTRFS_I(inode)->flags); 17678c2ecf20Sopenharmony_ci btrfs_set_stack_inode_block_group(inode_item, 0); 17688c2ecf20Sopenharmony_ci 17698c2ecf20Sopenharmony_ci btrfs_set_stack_timespec_sec(&inode_item->atime, 17708c2ecf20Sopenharmony_ci inode->i_atime.tv_sec); 17718c2ecf20Sopenharmony_ci btrfs_set_stack_timespec_nsec(&inode_item->atime, 17728c2ecf20Sopenharmony_ci inode->i_atime.tv_nsec); 17738c2ecf20Sopenharmony_ci 17748c2ecf20Sopenharmony_ci btrfs_set_stack_timespec_sec(&inode_item->mtime, 17758c2ecf20Sopenharmony_ci inode->i_mtime.tv_sec); 17768c2ecf20Sopenharmony_ci btrfs_set_stack_timespec_nsec(&inode_item->mtime, 17778c2ecf20Sopenharmony_ci inode->i_mtime.tv_nsec); 17788c2ecf20Sopenharmony_ci 17798c2ecf20Sopenharmony_ci btrfs_set_stack_timespec_sec(&inode_item->ctime, 17808c2ecf20Sopenharmony_ci inode->i_ctime.tv_sec); 17818c2ecf20Sopenharmony_ci btrfs_set_stack_timespec_nsec(&inode_item->ctime, 17828c2ecf20Sopenharmony_ci inode->i_ctime.tv_nsec); 17838c2ecf20Sopenharmony_ci 17848c2ecf20Sopenharmony_ci btrfs_set_stack_timespec_sec(&inode_item->otime, 17858c2ecf20Sopenharmony_ci BTRFS_I(inode)->i_otime.tv_sec); 17868c2ecf20Sopenharmony_ci btrfs_set_stack_timespec_nsec(&inode_item->otime, 17878c2ecf20Sopenharmony_ci BTRFS_I(inode)->i_otime.tv_nsec); 17888c2ecf20Sopenharmony_ci} 17898c2ecf20Sopenharmony_ci 17908c2ecf20Sopenharmony_ciint btrfs_fill_inode(struct inode *inode, u32 *rdev) 17918c2ecf20Sopenharmony_ci{ 17928c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info; 17938c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_node; 17948c2ecf20Sopenharmony_ci struct btrfs_inode_item *inode_item; 17958c2ecf20Sopenharmony_ci 17968c2ecf20Sopenharmony_ci delayed_node = btrfs_get_delayed_node(BTRFS_I(inode)); 17978c2ecf20Sopenharmony_ci if (!delayed_node) 17988c2ecf20Sopenharmony_ci return -ENOENT; 17998c2ecf20Sopenharmony_ci 18008c2ecf20Sopenharmony_ci mutex_lock(&delayed_node->mutex); 18018c2ecf20Sopenharmony_ci if (!test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags)) { 18028c2ecf20Sopenharmony_ci mutex_unlock(&delayed_node->mutex); 18038c2ecf20Sopenharmony_ci btrfs_release_delayed_node(delayed_node); 18048c2ecf20Sopenharmony_ci return -ENOENT; 18058c2ecf20Sopenharmony_ci } 18068c2ecf20Sopenharmony_ci 18078c2ecf20Sopenharmony_ci inode_item = &delayed_node->inode_item; 18088c2ecf20Sopenharmony_ci 18098c2ecf20Sopenharmony_ci i_uid_write(inode, btrfs_stack_inode_uid(inode_item)); 18108c2ecf20Sopenharmony_ci i_gid_write(inode, btrfs_stack_inode_gid(inode_item)); 18118c2ecf20Sopenharmony_ci btrfs_i_size_write(BTRFS_I(inode), btrfs_stack_inode_size(inode_item)); 18128c2ecf20Sopenharmony_ci btrfs_inode_set_file_extent_range(BTRFS_I(inode), 0, 18138c2ecf20Sopenharmony_ci round_up(i_size_read(inode), fs_info->sectorsize)); 18148c2ecf20Sopenharmony_ci inode->i_mode = btrfs_stack_inode_mode(inode_item); 18158c2ecf20Sopenharmony_ci set_nlink(inode, btrfs_stack_inode_nlink(inode_item)); 18168c2ecf20Sopenharmony_ci inode_set_bytes(inode, btrfs_stack_inode_nbytes(inode_item)); 18178c2ecf20Sopenharmony_ci BTRFS_I(inode)->generation = btrfs_stack_inode_generation(inode_item); 18188c2ecf20Sopenharmony_ci BTRFS_I(inode)->last_trans = btrfs_stack_inode_transid(inode_item); 18198c2ecf20Sopenharmony_ci 18208c2ecf20Sopenharmony_ci inode_set_iversion_queried(inode, 18218c2ecf20Sopenharmony_ci btrfs_stack_inode_sequence(inode_item)); 18228c2ecf20Sopenharmony_ci inode->i_rdev = 0; 18238c2ecf20Sopenharmony_ci *rdev = btrfs_stack_inode_rdev(inode_item); 18248c2ecf20Sopenharmony_ci BTRFS_I(inode)->flags = btrfs_stack_inode_flags(inode_item); 18258c2ecf20Sopenharmony_ci 18268c2ecf20Sopenharmony_ci inode->i_atime.tv_sec = btrfs_stack_timespec_sec(&inode_item->atime); 18278c2ecf20Sopenharmony_ci inode->i_atime.tv_nsec = btrfs_stack_timespec_nsec(&inode_item->atime); 18288c2ecf20Sopenharmony_ci 18298c2ecf20Sopenharmony_ci inode->i_mtime.tv_sec = btrfs_stack_timespec_sec(&inode_item->mtime); 18308c2ecf20Sopenharmony_ci inode->i_mtime.tv_nsec = btrfs_stack_timespec_nsec(&inode_item->mtime); 18318c2ecf20Sopenharmony_ci 18328c2ecf20Sopenharmony_ci inode->i_ctime.tv_sec = btrfs_stack_timespec_sec(&inode_item->ctime); 18338c2ecf20Sopenharmony_ci inode->i_ctime.tv_nsec = btrfs_stack_timespec_nsec(&inode_item->ctime); 18348c2ecf20Sopenharmony_ci 18358c2ecf20Sopenharmony_ci BTRFS_I(inode)->i_otime.tv_sec = 18368c2ecf20Sopenharmony_ci btrfs_stack_timespec_sec(&inode_item->otime); 18378c2ecf20Sopenharmony_ci BTRFS_I(inode)->i_otime.tv_nsec = 18388c2ecf20Sopenharmony_ci btrfs_stack_timespec_nsec(&inode_item->otime); 18398c2ecf20Sopenharmony_ci 18408c2ecf20Sopenharmony_ci inode->i_generation = BTRFS_I(inode)->generation; 18418c2ecf20Sopenharmony_ci BTRFS_I(inode)->index_cnt = (u64)-1; 18428c2ecf20Sopenharmony_ci 18438c2ecf20Sopenharmony_ci mutex_unlock(&delayed_node->mutex); 18448c2ecf20Sopenharmony_ci btrfs_release_delayed_node(delayed_node); 18458c2ecf20Sopenharmony_ci return 0; 18468c2ecf20Sopenharmony_ci} 18478c2ecf20Sopenharmony_ci 18488c2ecf20Sopenharmony_ciint btrfs_delayed_update_inode(struct btrfs_trans_handle *trans, 18498c2ecf20Sopenharmony_ci struct btrfs_root *root, struct inode *inode) 18508c2ecf20Sopenharmony_ci{ 18518c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_node; 18528c2ecf20Sopenharmony_ci int ret = 0; 18538c2ecf20Sopenharmony_ci 18548c2ecf20Sopenharmony_ci delayed_node = btrfs_get_or_create_delayed_node(BTRFS_I(inode)); 18558c2ecf20Sopenharmony_ci if (IS_ERR(delayed_node)) 18568c2ecf20Sopenharmony_ci return PTR_ERR(delayed_node); 18578c2ecf20Sopenharmony_ci 18588c2ecf20Sopenharmony_ci mutex_lock(&delayed_node->mutex); 18598c2ecf20Sopenharmony_ci if (test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags)) { 18608c2ecf20Sopenharmony_ci fill_stack_inode_item(trans, &delayed_node->inode_item, inode); 18618c2ecf20Sopenharmony_ci goto release_node; 18628c2ecf20Sopenharmony_ci } 18638c2ecf20Sopenharmony_ci 18648c2ecf20Sopenharmony_ci ret = btrfs_delayed_inode_reserve_metadata(trans, root, BTRFS_I(inode), 18658c2ecf20Sopenharmony_ci delayed_node); 18668c2ecf20Sopenharmony_ci if (ret) 18678c2ecf20Sopenharmony_ci goto release_node; 18688c2ecf20Sopenharmony_ci 18698c2ecf20Sopenharmony_ci fill_stack_inode_item(trans, &delayed_node->inode_item, inode); 18708c2ecf20Sopenharmony_ci set_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags); 18718c2ecf20Sopenharmony_ci delayed_node->count++; 18728c2ecf20Sopenharmony_ci atomic_inc(&root->fs_info->delayed_root->items); 18738c2ecf20Sopenharmony_cirelease_node: 18748c2ecf20Sopenharmony_ci mutex_unlock(&delayed_node->mutex); 18758c2ecf20Sopenharmony_ci btrfs_release_delayed_node(delayed_node); 18768c2ecf20Sopenharmony_ci return ret; 18778c2ecf20Sopenharmony_ci} 18788c2ecf20Sopenharmony_ci 18798c2ecf20Sopenharmony_ciint btrfs_delayed_delete_inode_ref(struct btrfs_inode *inode) 18808c2ecf20Sopenharmony_ci{ 18818c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = inode->root->fs_info; 18828c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_node; 18838c2ecf20Sopenharmony_ci 18848c2ecf20Sopenharmony_ci /* 18858c2ecf20Sopenharmony_ci * we don't do delayed inode updates during log recovery because it 18868c2ecf20Sopenharmony_ci * leads to enospc problems. This means we also can't do 18878c2ecf20Sopenharmony_ci * delayed inode refs 18888c2ecf20Sopenharmony_ci */ 18898c2ecf20Sopenharmony_ci if (test_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags)) 18908c2ecf20Sopenharmony_ci return -EAGAIN; 18918c2ecf20Sopenharmony_ci 18928c2ecf20Sopenharmony_ci delayed_node = btrfs_get_or_create_delayed_node(inode); 18938c2ecf20Sopenharmony_ci if (IS_ERR(delayed_node)) 18948c2ecf20Sopenharmony_ci return PTR_ERR(delayed_node); 18958c2ecf20Sopenharmony_ci 18968c2ecf20Sopenharmony_ci /* 18978c2ecf20Sopenharmony_ci * We don't reserve space for inode ref deletion is because: 18988c2ecf20Sopenharmony_ci * - We ONLY do async inode ref deletion for the inode who has only 18998c2ecf20Sopenharmony_ci * one link(i_nlink == 1), it means there is only one inode ref. 19008c2ecf20Sopenharmony_ci * And in most case, the inode ref and the inode item are in the 19018c2ecf20Sopenharmony_ci * same leaf, and we will deal with them at the same time. 19028c2ecf20Sopenharmony_ci * Since we are sure we will reserve the space for the inode item, 19038c2ecf20Sopenharmony_ci * it is unnecessary to reserve space for inode ref deletion. 19048c2ecf20Sopenharmony_ci * - If the inode ref and the inode item are not in the same leaf, 19058c2ecf20Sopenharmony_ci * We also needn't worry about enospc problem, because we reserve 19068c2ecf20Sopenharmony_ci * much more space for the inode update than it needs. 19078c2ecf20Sopenharmony_ci * - At the worst, we can steal some space from the global reservation. 19088c2ecf20Sopenharmony_ci * It is very rare. 19098c2ecf20Sopenharmony_ci */ 19108c2ecf20Sopenharmony_ci mutex_lock(&delayed_node->mutex); 19118c2ecf20Sopenharmony_ci if (test_bit(BTRFS_DELAYED_NODE_DEL_IREF, &delayed_node->flags)) 19128c2ecf20Sopenharmony_ci goto release_node; 19138c2ecf20Sopenharmony_ci 19148c2ecf20Sopenharmony_ci set_bit(BTRFS_DELAYED_NODE_DEL_IREF, &delayed_node->flags); 19158c2ecf20Sopenharmony_ci delayed_node->count++; 19168c2ecf20Sopenharmony_ci atomic_inc(&fs_info->delayed_root->items); 19178c2ecf20Sopenharmony_cirelease_node: 19188c2ecf20Sopenharmony_ci mutex_unlock(&delayed_node->mutex); 19198c2ecf20Sopenharmony_ci btrfs_release_delayed_node(delayed_node); 19208c2ecf20Sopenharmony_ci return 0; 19218c2ecf20Sopenharmony_ci} 19228c2ecf20Sopenharmony_ci 19238c2ecf20Sopenharmony_cistatic void __btrfs_kill_delayed_node(struct btrfs_delayed_node *delayed_node) 19248c2ecf20Sopenharmony_ci{ 19258c2ecf20Sopenharmony_ci struct btrfs_root *root = delayed_node->root; 19268c2ecf20Sopenharmony_ci struct btrfs_fs_info *fs_info = root->fs_info; 19278c2ecf20Sopenharmony_ci struct btrfs_delayed_item *curr_item, *prev_item; 19288c2ecf20Sopenharmony_ci 19298c2ecf20Sopenharmony_ci mutex_lock(&delayed_node->mutex); 19308c2ecf20Sopenharmony_ci curr_item = __btrfs_first_delayed_insertion_item(delayed_node); 19318c2ecf20Sopenharmony_ci while (curr_item) { 19328c2ecf20Sopenharmony_ci btrfs_delayed_item_release_metadata(root, curr_item); 19338c2ecf20Sopenharmony_ci prev_item = curr_item; 19348c2ecf20Sopenharmony_ci curr_item = __btrfs_next_delayed_item(prev_item); 19358c2ecf20Sopenharmony_ci btrfs_release_delayed_item(prev_item); 19368c2ecf20Sopenharmony_ci } 19378c2ecf20Sopenharmony_ci 19388c2ecf20Sopenharmony_ci curr_item = __btrfs_first_delayed_deletion_item(delayed_node); 19398c2ecf20Sopenharmony_ci while (curr_item) { 19408c2ecf20Sopenharmony_ci btrfs_delayed_item_release_metadata(root, curr_item); 19418c2ecf20Sopenharmony_ci prev_item = curr_item; 19428c2ecf20Sopenharmony_ci curr_item = __btrfs_next_delayed_item(prev_item); 19438c2ecf20Sopenharmony_ci btrfs_release_delayed_item(prev_item); 19448c2ecf20Sopenharmony_ci } 19458c2ecf20Sopenharmony_ci 19468c2ecf20Sopenharmony_ci if (test_bit(BTRFS_DELAYED_NODE_DEL_IREF, &delayed_node->flags)) 19478c2ecf20Sopenharmony_ci btrfs_release_delayed_iref(delayed_node); 19488c2ecf20Sopenharmony_ci 19498c2ecf20Sopenharmony_ci if (test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags)) { 19508c2ecf20Sopenharmony_ci btrfs_delayed_inode_release_metadata(fs_info, delayed_node, false); 19518c2ecf20Sopenharmony_ci btrfs_release_delayed_inode(delayed_node); 19528c2ecf20Sopenharmony_ci } 19538c2ecf20Sopenharmony_ci mutex_unlock(&delayed_node->mutex); 19548c2ecf20Sopenharmony_ci} 19558c2ecf20Sopenharmony_ci 19568c2ecf20Sopenharmony_civoid btrfs_kill_delayed_inode_items(struct btrfs_inode *inode) 19578c2ecf20Sopenharmony_ci{ 19588c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_node; 19598c2ecf20Sopenharmony_ci 19608c2ecf20Sopenharmony_ci delayed_node = btrfs_get_delayed_node(inode); 19618c2ecf20Sopenharmony_ci if (!delayed_node) 19628c2ecf20Sopenharmony_ci return; 19638c2ecf20Sopenharmony_ci 19648c2ecf20Sopenharmony_ci __btrfs_kill_delayed_node(delayed_node); 19658c2ecf20Sopenharmony_ci btrfs_release_delayed_node(delayed_node); 19668c2ecf20Sopenharmony_ci} 19678c2ecf20Sopenharmony_ci 19688c2ecf20Sopenharmony_civoid btrfs_kill_all_delayed_nodes(struct btrfs_root *root) 19698c2ecf20Sopenharmony_ci{ 19708c2ecf20Sopenharmony_ci u64 inode_id = 0; 19718c2ecf20Sopenharmony_ci struct btrfs_delayed_node *delayed_nodes[8]; 19728c2ecf20Sopenharmony_ci int i, n; 19738c2ecf20Sopenharmony_ci 19748c2ecf20Sopenharmony_ci while (1) { 19758c2ecf20Sopenharmony_ci spin_lock(&root->inode_lock); 19768c2ecf20Sopenharmony_ci n = radix_tree_gang_lookup(&root->delayed_nodes_tree, 19778c2ecf20Sopenharmony_ci (void **)delayed_nodes, inode_id, 19788c2ecf20Sopenharmony_ci ARRAY_SIZE(delayed_nodes)); 19798c2ecf20Sopenharmony_ci if (!n) { 19808c2ecf20Sopenharmony_ci spin_unlock(&root->inode_lock); 19818c2ecf20Sopenharmony_ci break; 19828c2ecf20Sopenharmony_ci } 19838c2ecf20Sopenharmony_ci 19848c2ecf20Sopenharmony_ci inode_id = delayed_nodes[n - 1]->inode_id + 1; 19858c2ecf20Sopenharmony_ci for (i = 0; i < n; i++) { 19868c2ecf20Sopenharmony_ci /* 19878c2ecf20Sopenharmony_ci * Don't increase refs in case the node is dead and 19888c2ecf20Sopenharmony_ci * about to be removed from the tree in the loop below 19898c2ecf20Sopenharmony_ci */ 19908c2ecf20Sopenharmony_ci if (!refcount_inc_not_zero(&delayed_nodes[i]->refs)) 19918c2ecf20Sopenharmony_ci delayed_nodes[i] = NULL; 19928c2ecf20Sopenharmony_ci } 19938c2ecf20Sopenharmony_ci spin_unlock(&root->inode_lock); 19948c2ecf20Sopenharmony_ci 19958c2ecf20Sopenharmony_ci for (i = 0; i < n; i++) { 19968c2ecf20Sopenharmony_ci if (!delayed_nodes[i]) 19978c2ecf20Sopenharmony_ci continue; 19988c2ecf20Sopenharmony_ci __btrfs_kill_delayed_node(delayed_nodes[i]); 19998c2ecf20Sopenharmony_ci btrfs_release_delayed_node(delayed_nodes[i]); 20008c2ecf20Sopenharmony_ci } 20018c2ecf20Sopenharmony_ci } 20028c2ecf20Sopenharmony_ci} 20038c2ecf20Sopenharmony_ci 20048c2ecf20Sopenharmony_civoid btrfs_destroy_delayed_inodes(struct btrfs_fs_info *fs_info) 20058c2ecf20Sopenharmony_ci{ 20068c2ecf20Sopenharmony_ci struct btrfs_delayed_node *curr_node, *prev_node; 20078c2ecf20Sopenharmony_ci 20088c2ecf20Sopenharmony_ci curr_node = btrfs_first_delayed_node(fs_info->delayed_root); 20098c2ecf20Sopenharmony_ci while (curr_node) { 20108c2ecf20Sopenharmony_ci __btrfs_kill_delayed_node(curr_node); 20118c2ecf20Sopenharmony_ci 20128c2ecf20Sopenharmony_ci prev_node = curr_node; 20138c2ecf20Sopenharmony_ci curr_node = btrfs_next_delayed_node(curr_node); 20148c2ecf20Sopenharmony_ci btrfs_release_delayed_node(prev_node); 20158c2ecf20Sopenharmony_ci } 20168c2ecf20Sopenharmony_ci} 20178c2ecf20Sopenharmony_ci 2018