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