Blame view

fs/btrfs/delayed-inode.c 51.9 KB
c1d7c514f   David Sterba   btrfs: replace GP...
1
  // SPDX-License-Identifier: GPL-2.0
16cdcec73   Miao Xie   btrfs: implement ...
2
3
4
  /*
   * Copyright (C) 2011 Fujitsu.  All rights reserved.
   * Written by Miao Xie <miaox@cn.fujitsu.com>
16cdcec73   Miao Xie   btrfs: implement ...
5
6
7
   */
  
  #include <linux/slab.h>
c7f88c4e7   Jeff Layton   btrfs: convert to...
8
  #include <linux/iversion.h>
351cbf6e4   Josef Bacik   btrfs: use nofs a...
9
  #include <linux/sched/mm.h>
602cbe91f   David Sterba   btrfs: move cond_...
10
  #include "misc.h"
16cdcec73   Miao Xie   btrfs: implement ...
11
12
13
  #include "delayed-inode.h"
  #include "disk-io.h"
  #include "transaction.h"
3cae210fa   Qu Wenruo   btrfs: Cleanup fo...
14
  #include "ctree.h"
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
15
  #include "qgroup.h"
1f95ec012   David Sterba   btrfs: move btrfs...
16
  #include "locking.h"
16cdcec73   Miao Xie   btrfs: implement ...
17

de3cb945d   Chris Mason   Btrfs: improve th...
18
19
20
  #define BTRFS_DELAYED_WRITEBACK		512
  #define BTRFS_DELAYED_BACKGROUND	128
  #define BTRFS_DELAYED_BATCH		16
16cdcec73   Miao Xie   btrfs: implement ...
21
22
23
24
25
  
  static struct kmem_cache *delayed_node_cache;
  
  int __init btrfs_delayed_inode_init(void)
  {
837e19728   David Sterba   btrfs: polish nam...
26
  	delayed_node_cache = kmem_cache_create("btrfs_delayed_node",
16cdcec73   Miao Xie   btrfs: implement ...
27
28
  					sizeof(struct btrfs_delayed_node),
  					0,
fba4b6977   Nikolay Borisov   btrfs: Fix slab a...
29
  					SLAB_MEM_SPREAD,
16cdcec73   Miao Xie   btrfs: implement ...
30
31
32
33
34
  					NULL);
  	if (!delayed_node_cache)
  		return -ENOMEM;
  	return 0;
  }
e67c718b5   David Sterba   btrfs: add more _...
35
  void __cold btrfs_delayed_inode_exit(void)
16cdcec73   Miao Xie   btrfs: implement ...
36
  {
5598e9005   Kinglong Mee   btrfs: drop null ...
37
  	kmem_cache_destroy(delayed_node_cache);
16cdcec73   Miao Xie   btrfs: implement ...
38
39
40
41
42
43
44
45
  }
  
  static inline void btrfs_init_delayed_node(
  				struct btrfs_delayed_node *delayed_node,
  				struct btrfs_root *root, u64 inode_id)
  {
  	delayed_node->root = root;
  	delayed_node->inode_id = inode_id;
6de5f18e7   Elena Reshetova   btrfs: convert bt...
46
  	refcount_set(&delayed_node->refs, 0);
03a1d4c89   Liu Bo   Btrfs: delayed-in...
47
48
  	delayed_node->ins_root = RB_ROOT_CACHED;
  	delayed_node->del_root = RB_ROOT_CACHED;
16cdcec73   Miao Xie   btrfs: implement ...
49
  	mutex_init(&delayed_node->mutex);
16cdcec73   Miao Xie   btrfs: implement ...
50
51
  	INIT_LIST_HEAD(&delayed_node->n_list);
  	INIT_LIST_HEAD(&delayed_node->p_list);
16cdcec73   Miao Xie   btrfs: implement ...
52
53
54
55
56
57
58
59
60
61
62
63
64
  }
  
  static inline int btrfs_is_continuous_delayed_item(
  					struct btrfs_delayed_item *item1,
  					struct btrfs_delayed_item *item2)
  {
  	if (item1->key.type == BTRFS_DIR_INDEX_KEY &&
  	    item1->key.objectid == item2->key.objectid &&
  	    item1->key.type == item2->key.type &&
  	    item1->key.offset + 1 == item2->key.offset)
  		return 1;
  	return 0;
  }
f85b7379c   David Sterba   btrfs: fix over-8...
65
66
  static struct btrfs_delayed_node *btrfs_get_delayed_node(
  		struct btrfs_inode *btrfs_inode)
16cdcec73   Miao Xie   btrfs: implement ...
67
  {
16cdcec73   Miao Xie   btrfs: implement ...
68
  	struct btrfs_root *root = btrfs_inode->root;
4a0cc7ca6   Nikolay Borisov   btrfs: Make btrfs...
69
  	u64 ino = btrfs_ino(btrfs_inode);
2f7e33d43   Miao Xie   btrfs: fix incons...
70
  	struct btrfs_delayed_node *node;
16cdcec73   Miao Xie   btrfs: implement ...
71

20c7bcec6   Seraphime Kirkovski   Btrfs: ACCESS_ONC...
72
  	node = READ_ONCE(btrfs_inode->delayed_node);
16cdcec73   Miao Xie   btrfs: implement ...
73
  	if (node) {
6de5f18e7   Elena Reshetova   btrfs: convert bt...
74
  		refcount_inc(&node->refs);
16cdcec73   Miao Xie   btrfs: implement ...
75
76
77
78
  		return node;
  	}
  
  	spin_lock(&root->inode_lock);
0d0ca30f1   Chris Mason   Btrfs: update the...
79
  	node = radix_tree_lookup(&root->delayed_nodes_tree, ino);
ec35e48b2   Chris Mason   btrfs: fix refcou...
80

16cdcec73   Miao Xie   btrfs: implement ...
81
82
  	if (node) {
  		if (btrfs_inode->delayed_node) {
6de5f18e7   Elena Reshetova   btrfs: convert bt...
83
  			refcount_inc(&node->refs);	/* can be accessed */
2f7e33d43   Miao Xie   btrfs: fix incons...
84
  			BUG_ON(btrfs_inode->delayed_node != node);
16cdcec73   Miao Xie   btrfs: implement ...
85
  			spin_unlock(&root->inode_lock);
2f7e33d43   Miao Xie   btrfs: fix incons...
86
  			return node;
16cdcec73   Miao Xie   btrfs: implement ...
87
  		}
ec35e48b2   Chris Mason   btrfs: fix refcou...
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
  
  		/*
  		 * It's possible that we're racing into the middle of removing
  		 * this node from the radix tree.  In this case, the refcount
  		 * was zero and it should never go back to one.  Just return
  		 * NULL like it was never in the radix at all; our release
  		 * function is in the process of removing it.
  		 *
  		 * Some implementations of refcount_inc refuse to bump the
  		 * refcount once it has hit zero.  If we don't do this dance
  		 * here, refcount_inc() may decide to just WARN_ONCE() instead
  		 * of actually bumping the refcount.
  		 *
  		 * If this node is properly in the radix, we want to bump the
  		 * refcount twice, once for the inode and once for this get
  		 * operation.
  		 */
  		if (refcount_inc_not_zero(&node->refs)) {
  			refcount_inc(&node->refs);
  			btrfs_inode->delayed_node = node;
  		} else {
  			node = NULL;
  		}
16cdcec73   Miao Xie   btrfs: implement ...
111
112
113
114
  		spin_unlock(&root->inode_lock);
  		return node;
  	}
  	spin_unlock(&root->inode_lock);
2f7e33d43   Miao Xie   btrfs: fix incons...
115
116
  	return NULL;
  }
79787eaab   Jeff Mahoney   btrfs: replace ma...
117
  /* Will return either the node or PTR_ERR(-ENOMEM) */
2f7e33d43   Miao Xie   btrfs: fix incons...
118
  static struct btrfs_delayed_node *btrfs_get_or_create_delayed_node(
f85b7379c   David Sterba   btrfs: fix over-8...
119
  		struct btrfs_inode *btrfs_inode)
2f7e33d43   Miao Xie   btrfs: fix incons...
120
121
  {
  	struct btrfs_delayed_node *node;
2f7e33d43   Miao Xie   btrfs: fix incons...
122
  	struct btrfs_root *root = btrfs_inode->root;
4a0cc7ca6   Nikolay Borisov   btrfs: Make btrfs...
123
  	u64 ino = btrfs_ino(btrfs_inode);
2f7e33d43   Miao Xie   btrfs: fix incons...
124
125
126
  	int ret;
  
  again:
340c6ca9f   Nikolay Borisov   btrfs: Make btrfs...
127
  	node = btrfs_get_delayed_node(btrfs_inode);
2f7e33d43   Miao Xie   btrfs: fix incons...
128
129
  	if (node)
  		return node;
352dd9c8d   Alexandru Moise   btrfs: zero out d...
130
  	node = kmem_cache_zalloc(delayed_node_cache, GFP_NOFS);
16cdcec73   Miao Xie   btrfs: implement ...
131
132
  	if (!node)
  		return ERR_PTR(-ENOMEM);
0d0ca30f1   Chris Mason   Btrfs: update the...
133
  	btrfs_init_delayed_node(node, root, ino);
16cdcec73   Miao Xie   btrfs: implement ...
134

95e94d14b   Rashika   btrfs: Replace mu...
135
  	/* cached in the btrfs inode and can be accessed */
6de5f18e7   Elena Reshetova   btrfs: convert bt...
136
  	refcount_set(&node->refs, 2);
16cdcec73   Miao Xie   btrfs: implement ...
137

e1860a772   David Sterba   btrfs: GFP_NOFS d...
138
  	ret = radix_tree_preload(GFP_NOFS);
16cdcec73   Miao Xie   btrfs: implement ...
139
140
141
142
143
144
  	if (ret) {
  		kmem_cache_free(delayed_node_cache, node);
  		return ERR_PTR(ret);
  	}
  
  	spin_lock(&root->inode_lock);
0d0ca30f1   Chris Mason   Btrfs: update the...
145
  	ret = radix_tree_insert(&root->delayed_nodes_tree, ino, node);
16cdcec73   Miao Xie   btrfs: implement ...
146
  	if (ret == -EEXIST) {
16cdcec73   Miao Xie   btrfs: implement ...
147
  		spin_unlock(&root->inode_lock);
964930312   Jeff Mahoney   btrfs: free delay...
148
  		kmem_cache_free(delayed_node_cache, node);
16cdcec73   Miao Xie   btrfs: implement ...
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
  		radix_tree_preload_end();
  		goto again;
  	}
  	btrfs_inode->delayed_node = node;
  	spin_unlock(&root->inode_lock);
  	radix_tree_preload_end();
  
  	return node;
  }
  
  /*
   * Call it when holding delayed_node->mutex
   *
   * If mod = 1, add this node into the prepared list.
   */
  static void btrfs_queue_delayed_node(struct btrfs_delayed_root *root,
  				     struct btrfs_delayed_node *node,
  				     int mod)
  {
  	spin_lock(&root->lock);
7cf35d91b   Miao Xie   Btrfs: use flags ...
169
  	if (test_bit(BTRFS_DELAYED_NODE_IN_LIST, &node->flags)) {
16cdcec73   Miao Xie   btrfs: implement ...
170
171
172
173
174
175
176
  		if (!list_empty(&node->p_list))
  			list_move_tail(&node->p_list, &root->prepare_list);
  		else if (mod)
  			list_add_tail(&node->p_list, &root->prepare_list);
  	} else {
  		list_add_tail(&node->n_list, &root->node_list);
  		list_add_tail(&node->p_list, &root->prepare_list);
6de5f18e7   Elena Reshetova   btrfs: convert bt...
177
  		refcount_inc(&node->refs);	/* inserted into list */
16cdcec73   Miao Xie   btrfs: implement ...
178
  		root->nodes++;
7cf35d91b   Miao Xie   Btrfs: use flags ...
179
  		set_bit(BTRFS_DELAYED_NODE_IN_LIST, &node->flags);
16cdcec73   Miao Xie   btrfs: implement ...
180
181
182
183
184
185
186
187
188
  	}
  	spin_unlock(&root->lock);
  }
  
  /* Call it when holding delayed_node->mutex */
  static void btrfs_dequeue_delayed_node(struct btrfs_delayed_root *root,
  				       struct btrfs_delayed_node *node)
  {
  	spin_lock(&root->lock);
7cf35d91b   Miao Xie   Btrfs: use flags ...
189
  	if (test_bit(BTRFS_DELAYED_NODE_IN_LIST, &node->flags)) {
16cdcec73   Miao Xie   btrfs: implement ...
190
  		root->nodes--;
6de5f18e7   Elena Reshetova   btrfs: convert bt...
191
  		refcount_dec(&node->refs);	/* not in the list */
16cdcec73   Miao Xie   btrfs: implement ...
192
193
194
  		list_del_init(&node->n_list);
  		if (!list_empty(&node->p_list))
  			list_del_init(&node->p_list);
7cf35d91b   Miao Xie   Btrfs: use flags ...
195
  		clear_bit(BTRFS_DELAYED_NODE_IN_LIST, &node->flags);
16cdcec73   Miao Xie   btrfs: implement ...
196
197
198
  	}
  	spin_unlock(&root->lock);
  }
48a3b6366   Eric Sandeen   btrfs: make stati...
199
  static struct btrfs_delayed_node *btrfs_first_delayed_node(
16cdcec73   Miao Xie   btrfs: implement ...
200
201
202
203
204
205
206
207
208
209
210
  			struct btrfs_delayed_root *delayed_root)
  {
  	struct list_head *p;
  	struct btrfs_delayed_node *node = NULL;
  
  	spin_lock(&delayed_root->lock);
  	if (list_empty(&delayed_root->node_list))
  		goto out;
  
  	p = delayed_root->node_list.next;
  	node = list_entry(p, struct btrfs_delayed_node, n_list);
6de5f18e7   Elena Reshetova   btrfs: convert bt...
211
  	refcount_inc(&node->refs);
16cdcec73   Miao Xie   btrfs: implement ...
212
213
214
215
216
  out:
  	spin_unlock(&delayed_root->lock);
  
  	return node;
  }
48a3b6366   Eric Sandeen   btrfs: make stati...
217
  static struct btrfs_delayed_node *btrfs_next_delayed_node(
16cdcec73   Miao Xie   btrfs: implement ...
218
219
220
221
222
223
224
225
  						struct btrfs_delayed_node *node)
  {
  	struct btrfs_delayed_root *delayed_root;
  	struct list_head *p;
  	struct btrfs_delayed_node *next = NULL;
  
  	delayed_root = node->root->fs_info->delayed_root;
  	spin_lock(&delayed_root->lock);
7cf35d91b   Miao Xie   Btrfs: use flags ...
226
227
  	if (!test_bit(BTRFS_DELAYED_NODE_IN_LIST, &node->flags)) {
  		/* not in the list */
16cdcec73   Miao Xie   btrfs: implement ...
228
229
230
231
232
233
234
235
236
  		if (list_empty(&delayed_root->node_list))
  			goto out;
  		p = delayed_root->node_list.next;
  	} else if (list_is_last(&node->n_list, &delayed_root->node_list))
  		goto out;
  	else
  		p = node->n_list.next;
  
  	next = list_entry(p, struct btrfs_delayed_node, n_list);
6de5f18e7   Elena Reshetova   btrfs: convert bt...
237
  	refcount_inc(&next->refs);
16cdcec73   Miao Xie   btrfs: implement ...
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
  out:
  	spin_unlock(&delayed_root->lock);
  
  	return next;
  }
  
  static void __btrfs_release_delayed_node(
  				struct btrfs_delayed_node *delayed_node,
  				int mod)
  {
  	struct btrfs_delayed_root *delayed_root;
  
  	if (!delayed_node)
  		return;
  
  	delayed_root = delayed_node->root->fs_info->delayed_root;
  
  	mutex_lock(&delayed_node->mutex);
  	if (delayed_node->count)
  		btrfs_queue_delayed_node(delayed_root, delayed_node, mod);
  	else
  		btrfs_dequeue_delayed_node(delayed_root, delayed_node);
  	mutex_unlock(&delayed_node->mutex);
6de5f18e7   Elena Reshetova   btrfs: convert bt...
261
  	if (refcount_dec_and_test(&delayed_node->refs)) {
16cdcec73   Miao Xie   btrfs: implement ...
262
  		struct btrfs_root *root = delayed_node->root;
ec35e48b2   Chris Mason   btrfs: fix refcou...
263

16cdcec73   Miao Xie   btrfs: implement ...
264
  		spin_lock(&root->inode_lock);
ec35e48b2   Chris Mason   btrfs: fix refcou...
265
266
267
268
269
270
271
  		/*
  		 * Once our refcount goes to zero, nobody is allowed to bump it
  		 * back up.  We can delete it now.
  		 */
  		ASSERT(refcount_read(&delayed_node->refs) == 0);
  		radix_tree_delete(&root->delayed_nodes_tree,
  				  delayed_node->inode_id);
16cdcec73   Miao Xie   btrfs: implement ...
272
  		spin_unlock(&root->inode_lock);
ec35e48b2   Chris Mason   btrfs: fix refcou...
273
  		kmem_cache_free(delayed_node_cache, delayed_node);
16cdcec73   Miao Xie   btrfs: implement ...
274
275
276
277
278
279
280
  	}
  }
  
  static inline void btrfs_release_delayed_node(struct btrfs_delayed_node *node)
  {
  	__btrfs_release_delayed_node(node, 0);
  }
48a3b6366   Eric Sandeen   btrfs: make stati...
281
  static struct btrfs_delayed_node *btrfs_first_prepared_delayed_node(
16cdcec73   Miao Xie   btrfs: implement ...
282
283
284
285
286
287
288
289
290
291
292
293
  					struct btrfs_delayed_root *delayed_root)
  {
  	struct list_head *p;
  	struct btrfs_delayed_node *node = NULL;
  
  	spin_lock(&delayed_root->lock);
  	if (list_empty(&delayed_root->prepare_list))
  		goto out;
  
  	p = delayed_root->prepare_list.next;
  	list_del_init(p);
  	node = list_entry(p, struct btrfs_delayed_node, p_list);
6de5f18e7   Elena Reshetova   btrfs: convert bt...
294
  	refcount_inc(&node->refs);
16cdcec73   Miao Xie   btrfs: implement ...
295
296
297
298
299
300
301
302
303
304
305
  out:
  	spin_unlock(&delayed_root->lock);
  
  	return node;
  }
  
  static inline void btrfs_release_prepared_delayed_node(
  					struct btrfs_delayed_node *node)
  {
  	__btrfs_release_delayed_node(node, 1);
  }
48a3b6366   Eric Sandeen   btrfs: make stati...
306
  static struct btrfs_delayed_item *btrfs_alloc_delayed_item(u32 data_len)
16cdcec73   Miao Xie   btrfs: implement ...
307
308
309
310
311
312
313
  {
  	struct btrfs_delayed_item *item;
  	item = kmalloc(sizeof(*item) + data_len, GFP_NOFS);
  	if (item) {
  		item->data_len = data_len;
  		item->ins_or_del = 0;
  		item->bytes_reserved = 0;
16cdcec73   Miao Xie   btrfs: implement ...
314
  		item->delayed_node = NULL;
089e77e10   Elena Reshetova   btrfs: convert bt...
315
  		refcount_set(&item->refs, 1);
16cdcec73   Miao Xie   btrfs: implement ...
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
  	}
  	return item;
  }
  
  /*
   * __btrfs_lookup_delayed_item - look up the delayed item by key
   * @delayed_node: pointer to the delayed node
   * @key:	  the key to look up
   * @prev:	  used to store the prev item if the right item isn't found
   * @next:	  used to store the next item if the right item isn't found
   *
   * Note: if we don't find the right item, we will return the prev item and
   * the next item.
   */
  static struct btrfs_delayed_item *__btrfs_lookup_delayed_item(
  				struct rb_root *root,
  				struct btrfs_key *key,
  				struct btrfs_delayed_item **prev,
  				struct btrfs_delayed_item **next)
  {
  	struct rb_node *node, *prev_node = NULL;
  	struct btrfs_delayed_item *delayed_item = NULL;
  	int ret = 0;
  
  	node = root->rb_node;
  
  	while (node) {
  		delayed_item = rb_entry(node, struct btrfs_delayed_item,
  					rb_node);
  		prev_node = node;
  		ret = btrfs_comp_cpu_keys(&delayed_item->key, key);
  		if (ret < 0)
  			node = node->rb_right;
  		else if (ret > 0)
  			node = node->rb_left;
  		else
  			return delayed_item;
  	}
  
  	if (prev) {
  		if (!prev_node)
  			*prev = NULL;
  		else if (ret < 0)
  			*prev = delayed_item;
  		else if ((node = rb_prev(prev_node)) != NULL) {
  			*prev = rb_entry(node, struct btrfs_delayed_item,
  					 rb_node);
  		} else
  			*prev = NULL;
  	}
  
  	if (next) {
  		if (!prev_node)
  			*next = NULL;
  		else if (ret > 0)
  			*next = delayed_item;
  		else if ((node = rb_next(prev_node)) != NULL) {
  			*next = rb_entry(node, struct btrfs_delayed_item,
  					 rb_node);
  		} else
  			*next = NULL;
  	}
  	return NULL;
  }
48a3b6366   Eric Sandeen   btrfs: make stati...
380
  static struct btrfs_delayed_item *__btrfs_lookup_delayed_insertion_item(
16cdcec73   Miao Xie   btrfs: implement ...
381
382
383
  					struct btrfs_delayed_node *delayed_node,
  					struct btrfs_key *key)
  {
03a1d4c89   Liu Bo   Btrfs: delayed-in...
384
  	return __btrfs_lookup_delayed_item(&delayed_node->ins_root.rb_root, key,
16cdcec73   Miao Xie   btrfs: implement ...
385
  					   NULL, NULL);
16cdcec73   Miao Xie   btrfs: implement ...
386
  }
16cdcec73   Miao Xie   btrfs: implement ...
387
388
389
390
391
392
  static int __btrfs_add_delayed_item(struct btrfs_delayed_node *delayed_node,
  				    struct btrfs_delayed_item *ins,
  				    int action)
  {
  	struct rb_node **p, *node;
  	struct rb_node *parent_node = NULL;
03a1d4c89   Liu Bo   Btrfs: delayed-in...
393
  	struct rb_root_cached *root;
16cdcec73   Miao Xie   btrfs: implement ...
394
395
  	struct btrfs_delayed_item *item;
  	int cmp;
03a1d4c89   Liu Bo   Btrfs: delayed-in...
396
  	bool leftmost = true;
16cdcec73   Miao Xie   btrfs: implement ...
397
398
399
400
401
402
403
  
  	if (action == BTRFS_DELAYED_INSERTION_ITEM)
  		root = &delayed_node->ins_root;
  	else if (action == BTRFS_DELAYED_DELETION_ITEM)
  		root = &delayed_node->del_root;
  	else
  		BUG();
03a1d4c89   Liu Bo   Btrfs: delayed-in...
404
  	p = &root->rb_root.rb_node;
16cdcec73   Miao Xie   btrfs: implement ...
405
406
407
408
409
410
411
412
  	node = &ins->rb_node;
  
  	while (*p) {
  		parent_node = *p;
  		item = rb_entry(parent_node, struct btrfs_delayed_item,
  				 rb_node);
  
  		cmp = btrfs_comp_cpu_keys(&item->key, &ins->key);
03a1d4c89   Liu Bo   Btrfs: delayed-in...
413
  		if (cmp < 0) {
16cdcec73   Miao Xie   btrfs: implement ...
414
  			p = &(*p)->rb_right;
03a1d4c89   Liu Bo   Btrfs: delayed-in...
415
416
  			leftmost = false;
  		} else if (cmp > 0) {
16cdcec73   Miao Xie   btrfs: implement ...
417
  			p = &(*p)->rb_left;
03a1d4c89   Liu Bo   Btrfs: delayed-in...
418
  		} else {
16cdcec73   Miao Xie   btrfs: implement ...
419
  			return -EEXIST;
03a1d4c89   Liu Bo   Btrfs: delayed-in...
420
  		}
16cdcec73   Miao Xie   btrfs: implement ...
421
422
423
  	}
  
  	rb_link_node(node, parent_node, p);
03a1d4c89   Liu Bo   Btrfs: delayed-in...
424
  	rb_insert_color_cached(node, root, leftmost);
16cdcec73   Miao Xie   btrfs: implement ...
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
  	ins->delayed_node = delayed_node;
  	ins->ins_or_del = action;
  
  	if (ins->key.type == BTRFS_DIR_INDEX_KEY &&
  	    action == BTRFS_DELAYED_INSERTION_ITEM &&
  	    ins->key.offset >= delayed_node->index_cnt)
  			delayed_node->index_cnt = ins->key.offset + 1;
  
  	delayed_node->count++;
  	atomic_inc(&delayed_node->root->fs_info->delayed_root->items);
  	return 0;
  }
  
  static int __btrfs_add_delayed_insertion_item(struct btrfs_delayed_node *node,
  					      struct btrfs_delayed_item *item)
  {
  	return __btrfs_add_delayed_item(node, item,
  					BTRFS_DELAYED_INSERTION_ITEM);
  }
  
  static int __btrfs_add_delayed_deletion_item(struct btrfs_delayed_node *node,
  					     struct btrfs_delayed_item *item)
  {
  	return __btrfs_add_delayed_item(node, item,
  					BTRFS_DELAYED_DELETION_ITEM);
  }
de3cb945d   Chris Mason   Btrfs: improve th...
451
452
453
  static void finish_one_item(struct btrfs_delayed_root *delayed_root)
  {
  	int seq = atomic_inc_return(&delayed_root->items_seq);
ee8639545   David Sterba   btrfs: comment th...
454

093258e6e   David Sterba   btrfs: replace wa...
455
  	/* atomic_dec_return implies a barrier */
de3cb945d   Chris Mason   Btrfs: improve th...
456
  	if ((atomic_dec_return(&delayed_root->items) <
093258e6e   David Sterba   btrfs: replace wa...
457
458
  	    BTRFS_DELAYED_BACKGROUND || seq % BTRFS_DELAYED_BATCH == 0))
  		cond_wake_up_nomb(&delayed_root->wait);
de3cb945d   Chris Mason   Btrfs: improve th...
459
  }
16cdcec73   Miao Xie   btrfs: implement ...
460
461
  static void __btrfs_remove_delayed_item(struct btrfs_delayed_item *delayed_item)
  {
03a1d4c89   Liu Bo   Btrfs: delayed-in...
462
  	struct rb_root_cached *root;
16cdcec73   Miao Xie   btrfs: implement ...
463
  	struct btrfs_delayed_root *delayed_root;
933c22a75   Qu Wenruo   btrfs: delayed-in...
464
465
466
  	/* Not associated with any delayed_node */
  	if (!delayed_item->delayed_node)
  		return;
16cdcec73   Miao Xie   btrfs: implement ...
467
468
469
470
471
472
473
474
475
476
  	delayed_root = delayed_item->delayed_node->root->fs_info->delayed_root;
  
  	BUG_ON(!delayed_root);
  	BUG_ON(delayed_item->ins_or_del != BTRFS_DELAYED_DELETION_ITEM &&
  	       delayed_item->ins_or_del != BTRFS_DELAYED_INSERTION_ITEM);
  
  	if (delayed_item->ins_or_del == BTRFS_DELAYED_INSERTION_ITEM)
  		root = &delayed_item->delayed_node->ins_root;
  	else
  		root = &delayed_item->delayed_node->del_root;
03a1d4c89   Liu Bo   Btrfs: delayed-in...
477
  	rb_erase_cached(&delayed_item->rb_node, root);
16cdcec73   Miao Xie   btrfs: implement ...
478
  	delayed_item->delayed_node->count--;
de3cb945d   Chris Mason   Btrfs: improve th...
479
480
  
  	finish_one_item(delayed_root);
16cdcec73   Miao Xie   btrfs: implement ...
481
482
483
484
485
486
  }
  
  static void btrfs_release_delayed_item(struct btrfs_delayed_item *item)
  {
  	if (item) {
  		__btrfs_remove_delayed_item(item);
089e77e10   Elena Reshetova   btrfs: convert bt...
487
  		if (refcount_dec_and_test(&item->refs))
16cdcec73   Miao Xie   btrfs: implement ...
488
489
490
  			kfree(item);
  	}
  }
48a3b6366   Eric Sandeen   btrfs: make stati...
491
  static struct btrfs_delayed_item *__btrfs_first_delayed_insertion_item(
16cdcec73   Miao Xie   btrfs: implement ...
492
493
494
495
  					struct btrfs_delayed_node *delayed_node)
  {
  	struct rb_node *p;
  	struct btrfs_delayed_item *item = NULL;
03a1d4c89   Liu Bo   Btrfs: delayed-in...
496
  	p = rb_first_cached(&delayed_node->ins_root);
16cdcec73   Miao Xie   btrfs: implement ...
497
498
499
500
501
  	if (p)
  		item = rb_entry(p, struct btrfs_delayed_item, rb_node);
  
  	return item;
  }
48a3b6366   Eric Sandeen   btrfs: make stati...
502
  static struct btrfs_delayed_item *__btrfs_first_delayed_deletion_item(
16cdcec73   Miao Xie   btrfs: implement ...
503
504
505
506
  					struct btrfs_delayed_node *delayed_node)
  {
  	struct rb_node *p;
  	struct btrfs_delayed_item *item = NULL;
03a1d4c89   Liu Bo   Btrfs: delayed-in...
507
  	p = rb_first_cached(&delayed_node->del_root);
16cdcec73   Miao Xie   btrfs: implement ...
508
509
510
511
512
  	if (p)
  		item = rb_entry(p, struct btrfs_delayed_item, rb_node);
  
  	return item;
  }
48a3b6366   Eric Sandeen   btrfs: make stati...
513
  static struct btrfs_delayed_item *__btrfs_next_delayed_item(
16cdcec73   Miao Xie   btrfs: implement ...
514
515
516
517
518
519
520
521
522
523
524
  						struct btrfs_delayed_item *item)
  {
  	struct rb_node *p;
  	struct btrfs_delayed_item *next = NULL;
  
  	p = rb_next(&item->rb_node);
  	if (p)
  		next = rb_entry(p, struct btrfs_delayed_item, rb_node);
  
  	return next;
  }
16cdcec73   Miao Xie   btrfs: implement ...
525
  static int btrfs_delayed_item_reserve_metadata(struct btrfs_trans_handle *trans,
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
526
  					       struct btrfs_root *root,
16cdcec73   Miao Xie   btrfs: implement ...
527
528
529
530
  					       struct btrfs_delayed_item *item)
  {
  	struct btrfs_block_rsv *src_rsv;
  	struct btrfs_block_rsv *dst_rsv;
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
531
  	struct btrfs_fs_info *fs_info = root->fs_info;
16cdcec73   Miao Xie   btrfs: implement ...
532
533
534
535
536
537
538
  	u64 num_bytes;
  	int ret;
  
  	if (!trans->bytes_reserved)
  		return 0;
  
  	src_rsv = trans->block_rsv;
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
539
  	dst_rsv = &fs_info->delayed_block_rsv;
16cdcec73   Miao Xie   btrfs: implement ...
540

2bd36e7b4   Josef Bacik   btrfs: rename the...
541
  	num_bytes = btrfs_calc_insert_metadata_size(fs_info, 1);
f218ea6c4   Qu Wenruo   btrfs: delayed-in...
542
543
544
545
546
547
  
  	/*
  	 * Here we migrate space rsv from transaction rsv, since have already
  	 * reserved space when starting a transaction.  So no need to reserve
  	 * qgroup space here.
  	 */
3a5841748   Lu Fengqi   btrfs: switch upd...
548
  	ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, true);
8c2a3ca20   Josef Bacik   Btrfs: space leak...
549
  	if (!ret) {
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
550
  		trace_btrfs_space_reservation(fs_info, "delayed_item",
8c2a3ca20   Josef Bacik   Btrfs: space leak...
551
552
  					      item->key.objectid,
  					      num_bytes, 1);
16cdcec73   Miao Xie   btrfs: implement ...
553
  		item->bytes_reserved = num_bytes;
8c2a3ca20   Josef Bacik   Btrfs: space leak...
554
  	}
16cdcec73   Miao Xie   btrfs: implement ...
555
556
557
  
  	return ret;
  }
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
558
  static void btrfs_delayed_item_release_metadata(struct btrfs_root *root,
16cdcec73   Miao Xie   btrfs: implement ...
559
560
  						struct btrfs_delayed_item *item)
  {
19fd29495   Miao Xie   btrfs: fix wrong ...
561
  	struct btrfs_block_rsv *rsv;
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
562
  	struct btrfs_fs_info *fs_info = root->fs_info;
19fd29495   Miao Xie   btrfs: fix wrong ...
563

16cdcec73   Miao Xie   btrfs: implement ...
564
565
  	if (!item->bytes_reserved)
  		return;
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
566
  	rsv = &fs_info->delayed_block_rsv;
f218ea6c4   Qu Wenruo   btrfs: delayed-in...
567
568
569
570
  	/*
  	 * Check btrfs_delayed_item_reserve_metadata() to see why we don't need
  	 * to release/reserve qgroup space.
  	 */
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
571
  	trace_btrfs_space_reservation(fs_info, "delayed_item",
8c2a3ca20   Josef Bacik   Btrfs: space leak...
572
573
  				      item->key.objectid, item->bytes_reserved,
  				      0);
63f018be5   Nikolay Borisov   btrfs: Remove __ ...
574
  	btrfs_block_rsv_release(fs_info, rsv, item->bytes_reserved, NULL);
16cdcec73   Miao Xie   btrfs: implement ...
575
576
577
578
579
  }
  
  static int btrfs_delayed_inode_reserve_metadata(
  					struct btrfs_trans_handle *trans,
  					struct btrfs_root *root,
fcabdd1ca   Nikolay Borisov   btrfs: Make btrfs...
580
  					struct btrfs_inode *inode,
16cdcec73   Miao Xie   btrfs: implement ...
581
582
  					struct btrfs_delayed_node *node)
  {
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
583
  	struct btrfs_fs_info *fs_info = root->fs_info;
16cdcec73   Miao Xie   btrfs: implement ...
584
585
586
587
  	struct btrfs_block_rsv *src_rsv;
  	struct btrfs_block_rsv *dst_rsv;
  	u64 num_bytes;
  	int ret;
16cdcec73   Miao Xie   btrfs: implement ...
588
  	src_rsv = trans->block_rsv;
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
589
  	dst_rsv = &fs_info->delayed_block_rsv;
16cdcec73   Miao Xie   btrfs: implement ...
590

bcacf5f3f   Josef Bacik   btrfs: only reser...
591
  	num_bytes = btrfs_calc_metadata_size(fs_info, 1);
c06a0e120   Josef Bacik   Btrfs: fix delaye...
592
593
594
595
596
597
598
599
  
  	/*
  	 * btrfs_dirty_inode will update the inode under btrfs_join_transaction
  	 * which doesn't reserve space for speed.  This is a problem since we
  	 * still need to reserve space for this update, so try to reserve the
  	 * space.
  	 *
  	 * Now if src_rsv == delalloc_block_rsv we'll let it just steal since
69fe2d75d   Josef Bacik   btrfs: make the d...
600
  	 * we always reserve enough to update the inode item.
c06a0e120   Josef Bacik   Btrfs: fix delaye...
601
  	 */
e755d9ab3   Chris Mason   Btrfs: deal with ...
602
  	if (!src_rsv || (!trans->bytes_reserved &&
66d8f3dd1   Miao Xie   Btrfs: add a new ...
603
  			 src_rsv->type != BTRFS_BLOCK_RSV_DELALLOC)) {
f218ea6c4   Qu Wenruo   btrfs: delayed-in...
604
605
606
607
  		ret = btrfs_qgroup_reserve_meta_prealloc(root,
  				fs_info->nodesize, true);
  		if (ret < 0)
  			return ret;
08e007d2e   Miao Xie   Btrfs: improve th...
608
609
  		ret = btrfs_block_rsv_add(root, dst_rsv, num_bytes,
  					  BTRFS_RESERVE_NO_FLUSH);
c06a0e120   Josef Bacik   Btrfs: fix delaye...
610
611
612
613
614
615
  		/*
  		 * Since we're under a transaction reserve_metadata_bytes could
  		 * try to commit the transaction which will make it return
  		 * EAGAIN to make us stop the transaction we have, so return
  		 * ENOSPC instead so that btrfs_dirty_inode knows what to do.
  		 */
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
616
  		if (ret == -EAGAIN) {
c06a0e120   Josef Bacik   Btrfs: fix delaye...
617
  			ret = -ENOSPC;
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
618
619
  			btrfs_qgroup_free_meta_prealloc(root, num_bytes);
  		}
8c2a3ca20   Josef Bacik   Btrfs: space leak...
620
  		if (!ret) {
c06a0e120   Josef Bacik   Btrfs: fix delaye...
621
  			node->bytes_reserved = num_bytes;
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
622
  			trace_btrfs_space_reservation(fs_info,
8c2a3ca20   Josef Bacik   Btrfs: space leak...
623
  						      "delayed_inode",
fcabdd1ca   Nikolay Borisov   btrfs: Make btrfs...
624
  						      btrfs_ino(inode),
8c2a3ca20   Josef Bacik   Btrfs: space leak...
625
  						      num_bytes, 1);
f218ea6c4   Qu Wenruo   btrfs: delayed-in...
626
627
  		} else {
  			btrfs_qgroup_free_meta_prealloc(root, fs_info->nodesize);
8c2a3ca20   Josef Bacik   Btrfs: space leak...
628
  		}
c06a0e120   Josef Bacik   Btrfs: fix delaye...
629
630
  		return ret;
  	}
3a5841748   Lu Fengqi   btrfs: switch upd...
631
  	ret = btrfs_block_rsv_migrate(src_rsv, dst_rsv, num_bytes, true);
8c2a3ca20   Josef Bacik   Btrfs: space leak...
632
  	if (!ret) {
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
633
  		trace_btrfs_space_reservation(fs_info, "delayed_inode",
fcabdd1ca   Nikolay Borisov   btrfs: Make btrfs...
634
  					      btrfs_ino(inode), num_bytes, 1);
16cdcec73   Miao Xie   btrfs: implement ...
635
  		node->bytes_reserved = num_bytes;
8c2a3ca20   Josef Bacik   Btrfs: space leak...
636
  	}
16cdcec73   Miao Xie   btrfs: implement ...
637
638
639
  
  	return ret;
  }
2ff7e61e0   Jeff Mahoney   btrfs: take an fs...
640
  static void btrfs_delayed_inode_release_metadata(struct btrfs_fs_info *fs_info,
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
641
642
  						struct btrfs_delayed_node *node,
  						bool qgroup_free)
16cdcec73   Miao Xie   btrfs: implement ...
643
644
645
646
647
  {
  	struct btrfs_block_rsv *rsv;
  
  	if (!node->bytes_reserved)
  		return;
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
648
649
  	rsv = &fs_info->delayed_block_rsv;
  	trace_btrfs_space_reservation(fs_info, "delayed_inode",
8c2a3ca20   Josef Bacik   Btrfs: space leak...
650
  				      node->inode_id, node->bytes_reserved, 0);
63f018be5   Nikolay Borisov   btrfs: Remove __ ...
651
  	btrfs_block_rsv_release(fs_info, rsv, node->bytes_reserved, NULL);
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
652
653
654
655
656
657
  	if (qgroup_free)
  		btrfs_qgroup_free_meta_prealloc(node->root,
  				node->bytes_reserved);
  	else
  		btrfs_qgroup_convert_reserved_meta(node->root,
  				node->bytes_reserved);
16cdcec73   Miao Xie   btrfs: implement ...
658
659
660
661
662
663
664
  	node->bytes_reserved = 0;
  }
  
  /*
   * This helper will insert some continuous items into the same leaf according
   * to the free space of the leaf.
   */
afe5fea72   Tsutomu Itoh   Btrfs: cleanup of...
665
666
667
  static int btrfs_batch_insert_items(struct btrfs_root *root,
  				    struct btrfs_path *path,
  				    struct btrfs_delayed_item *item)
16cdcec73   Miao Xie   btrfs: implement ...
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
  {
  	struct btrfs_delayed_item *curr, *next;
  	int free_space;
  	int total_data_size = 0, total_size = 0;
  	struct extent_buffer *leaf;
  	char *data_ptr;
  	struct btrfs_key *keys;
  	u32 *data_size;
  	struct list_head head;
  	int slot;
  	int nitems;
  	int i;
  	int ret = 0;
  
  	BUG_ON(!path->nodes[0]);
  
  	leaf = path->nodes[0];
e902baac6   David Sterba   btrfs: get fs_inf...
685
  	free_space = btrfs_leaf_free_space(leaf);
16cdcec73   Miao Xie   btrfs: implement ...
686
687
688
  	INIT_LIST_HEAD(&head);
  
  	next = item;
17aca1c98   Chris Mason   Btrfs: fix uninit...
689
  	nitems = 0;
16cdcec73   Miao Xie   btrfs: implement ...
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
  
  	/*
  	 * count the number of the continuous items that we can insert in batch
  	 */
  	while (total_size + next->data_len + sizeof(struct btrfs_item) <=
  	       free_space) {
  		total_data_size += next->data_len;
  		total_size += next->data_len + sizeof(struct btrfs_item);
  		list_add_tail(&next->tree_list, &head);
  		nitems++;
  
  		curr = next;
  		next = __btrfs_next_delayed_item(curr);
  		if (!next)
  			break;
  
  		if (!btrfs_is_continuous_delayed_item(curr, next))
  			break;
  	}
  
  	if (!nitems) {
  		ret = 0;
  		goto out;
  	}
  
  	/*
  	 * we need allocate some memory space, but it might cause the task
  	 * to sleep, so we set all locked nodes in the path to blocking locks
  	 * first.
  	 */
  	btrfs_set_path_blocking(path);
d9b0d9ba0   Dulshani Gunawardhana   btrfs: Replace km...
721
  	keys = kmalloc_array(nitems, sizeof(struct btrfs_key), GFP_NOFS);
16cdcec73   Miao Xie   btrfs: implement ...
722
723
724
725
  	if (!keys) {
  		ret = -ENOMEM;
  		goto out;
  	}
d9b0d9ba0   Dulshani Gunawardhana   btrfs: Replace km...
726
  	data_size = kmalloc_array(nitems, sizeof(u32), GFP_NOFS);
16cdcec73   Miao Xie   btrfs: implement ...
727
728
729
730
731
732
733
734
735
736
737
738
  	if (!data_size) {
  		ret = -ENOMEM;
  		goto error;
  	}
  
  	/* get keys of all the delayed items */
  	i = 0;
  	list_for_each_entry(next, &head, tree_list) {
  		keys[i] = next->key;
  		data_size[i] = next->data_len;
  		i++;
  	}
16cdcec73   Miao Xie   btrfs: implement ...
739
  	/* insert the keys of the items */
afe5fea72   Tsutomu Itoh   Btrfs: cleanup of...
740
  	setup_items_for_insert(root, path, keys, data_size,
143bede52   Jeff Mahoney   btrfs: return voi...
741
  			       total_data_size, total_size, nitems);
16cdcec73   Miao Xie   btrfs: implement ...
742
743
744
745
746
747
748
749
750
  
  	/* insert the dir index items */
  	slot = path->slots[0];
  	list_for_each_entry_safe(curr, next, &head, tree_list) {
  		data_ptr = btrfs_item_ptr(leaf, slot, char);
  		write_extent_buffer(leaf, &curr->data,
  				    (unsigned long)data_ptr,
  				    curr->data_len);
  		slot++;
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
751
  		btrfs_delayed_item_release_metadata(root, curr);
16cdcec73   Miao Xie   btrfs: implement ...
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
  
  		list_del(&curr->tree_list);
  		btrfs_release_delayed_item(curr);
  	}
  
  error:
  	kfree(data_size);
  	kfree(keys);
  out:
  	return ret;
  }
  
  /*
   * This helper can just do simple insertion that needn't extend item for new
   * data, such as directory name index insertion, inode insertion.
   */
  static int btrfs_insert_delayed_item(struct btrfs_trans_handle *trans,
  				     struct btrfs_root *root,
  				     struct btrfs_path *path,
  				     struct btrfs_delayed_item *delayed_item)
  {
  	struct extent_buffer *leaf;
351cbf6e4   Josef Bacik   btrfs: use nofs a...
774
  	unsigned int nofs_flag;
16cdcec73   Miao Xie   btrfs: implement ...
775
776
  	char *ptr;
  	int ret;
351cbf6e4   Josef Bacik   btrfs: use nofs a...
777
  	nofs_flag = memalloc_nofs_save();
16cdcec73   Miao Xie   btrfs: implement ...
778
779
  	ret = btrfs_insert_empty_item(trans, root, path, &delayed_item->key,
  				      delayed_item->data_len);
351cbf6e4   Josef Bacik   btrfs: use nofs a...
780
  	memalloc_nofs_restore(nofs_flag);
16cdcec73   Miao Xie   btrfs: implement ...
781
782
783
784
  	if (ret < 0 && ret != -EEXIST)
  		return ret;
  
  	leaf = path->nodes[0];
16cdcec73   Miao Xie   btrfs: implement ...
785
786
787
788
789
  	ptr = btrfs_item_ptr(leaf, path->slots[0], char);
  
  	write_extent_buffer(leaf, delayed_item->data, (unsigned long)ptr,
  			    delayed_item->data_len);
  	btrfs_mark_buffer_dirty(leaf);
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
790
  	btrfs_delayed_item_release_metadata(root, delayed_item);
16cdcec73   Miao Xie   btrfs: implement ...
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
  	return 0;
  }
  
  /*
   * we insert an item first, then if there are some continuous items, we try
   * to insert those items into the same leaf.
   */
  static int btrfs_insert_delayed_items(struct btrfs_trans_handle *trans,
  				      struct btrfs_path *path,
  				      struct btrfs_root *root,
  				      struct btrfs_delayed_node *node)
  {
  	struct btrfs_delayed_item *curr, *prev;
  	int ret = 0;
  
  do_again:
  	mutex_lock(&node->mutex);
  	curr = __btrfs_first_delayed_insertion_item(node);
  	if (!curr)
  		goto insert_end;
  
  	ret = btrfs_insert_delayed_item(trans, root, path, curr);
  	if (ret < 0) {
945d8962c   Chris Mason   Merge branch 'cle...
814
  		btrfs_release_path(path);
16cdcec73   Miao Xie   btrfs: implement ...
815
816
817
818
819
820
821
822
  		goto insert_end;
  	}
  
  	prev = curr;
  	curr = __btrfs_next_delayed_item(prev);
  	if (curr && btrfs_is_continuous_delayed_item(prev, curr)) {
  		/* insert the continuous items into the same leaf */
  		path->slots[0]++;
afe5fea72   Tsutomu Itoh   Btrfs: cleanup of...
823
  		btrfs_batch_insert_items(root, path, curr);
16cdcec73   Miao Xie   btrfs: implement ...
824
825
826
  	}
  	btrfs_release_delayed_item(prev);
  	btrfs_mark_buffer_dirty(path->nodes[0]);
945d8962c   Chris Mason   Merge branch 'cle...
827
  	btrfs_release_path(path);
16cdcec73   Miao Xie   btrfs: implement ...
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
  	mutex_unlock(&node->mutex);
  	goto do_again;
  
  insert_end:
  	mutex_unlock(&node->mutex);
  	return ret;
  }
  
  static int btrfs_batch_delete_items(struct btrfs_trans_handle *trans,
  				    struct btrfs_root *root,
  				    struct btrfs_path *path,
  				    struct btrfs_delayed_item *item)
  {
  	struct btrfs_delayed_item *curr, *next;
  	struct extent_buffer *leaf;
  	struct btrfs_key key;
  	struct list_head head;
  	int nitems, i, last_item;
  	int ret = 0;
  
  	BUG_ON(!path->nodes[0]);
  
  	leaf = path->nodes[0];
  
  	i = path->slots[0];
  	last_item = btrfs_header_nritems(leaf) - 1;
  	if (i > last_item)
  		return -ENOENT;	/* FIXME: Is errno suitable? */
  
  	next = item;
  	INIT_LIST_HEAD(&head);
  	btrfs_item_key_to_cpu(leaf, &key, i);
  	nitems = 0;
  	/*
  	 * count the number of the dir index items that we can delete in batch
  	 */
  	while (btrfs_comp_cpu_keys(&next->key, &key) == 0) {
  		list_add_tail(&next->tree_list, &head);
  		nitems++;
  
  		curr = next;
  		next = __btrfs_next_delayed_item(curr);
  		if (!next)
  			break;
  
  		if (!btrfs_is_continuous_delayed_item(curr, next))
  			break;
  
  		i++;
  		if (i > last_item)
  			break;
  		btrfs_item_key_to_cpu(leaf, &key, i);
  	}
  
  	if (!nitems)
  		return 0;
  
  	ret = btrfs_del_items(trans, root, path, path->slots[0], nitems);
  	if (ret)
  		goto out;
  
  	list_for_each_entry_safe(curr, next, &head, tree_list) {
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
890
  		btrfs_delayed_item_release_metadata(root, curr);
16cdcec73   Miao Xie   btrfs: implement ...
891
892
893
894
895
896
897
898
899
900
901
902
903
904
  		list_del(&curr->tree_list);
  		btrfs_release_delayed_item(curr);
  	}
  
  out:
  	return ret;
  }
  
  static int btrfs_delete_delayed_items(struct btrfs_trans_handle *trans,
  				      struct btrfs_path *path,
  				      struct btrfs_root *root,
  				      struct btrfs_delayed_node *node)
  {
  	struct btrfs_delayed_item *curr, *prev;
351cbf6e4   Josef Bacik   btrfs: use nofs a...
905
  	unsigned int nofs_flag;
16cdcec73   Miao Xie   btrfs: implement ...
906
907
908
909
910
911
912
  	int ret = 0;
  
  do_again:
  	mutex_lock(&node->mutex);
  	curr = __btrfs_first_delayed_deletion_item(node);
  	if (!curr)
  		goto delete_fail;
351cbf6e4   Josef Bacik   btrfs: use nofs a...
913
  	nofs_flag = memalloc_nofs_save();
16cdcec73   Miao Xie   btrfs: implement ...
914
  	ret = btrfs_search_slot(trans, root, &curr->key, path, -1, 1);
351cbf6e4   Josef Bacik   btrfs: use nofs a...
915
  	memalloc_nofs_restore(nofs_flag);
16cdcec73   Miao Xie   btrfs: implement ...
916
917
918
919
920
921
922
923
924
925
926
  	if (ret < 0)
  		goto delete_fail;
  	else if (ret > 0) {
  		/*
  		 * can't find the item which the node points to, so this node
  		 * is invalid, just drop it.
  		 */
  		prev = curr;
  		curr = __btrfs_next_delayed_item(prev);
  		btrfs_release_delayed_item(prev);
  		ret = 0;
945d8962c   Chris Mason   Merge branch 'cle...
927
  		btrfs_release_path(path);
620952653   Fengguang Wu   btrfs: fix second...
928
929
  		if (curr) {
  			mutex_unlock(&node->mutex);
16cdcec73   Miao Xie   btrfs: implement ...
930
  			goto do_again;
620952653   Fengguang Wu   btrfs: fix second...
931
  		} else
16cdcec73   Miao Xie   btrfs: implement ...
932
933
934
935
  			goto delete_fail;
  	}
  
  	btrfs_batch_delete_items(trans, root, path, curr);
945d8962c   Chris Mason   Merge branch 'cle...
936
  	btrfs_release_path(path);
16cdcec73   Miao Xie   btrfs: implement ...
937
938
939
940
  	mutex_unlock(&node->mutex);
  	goto do_again;
  
  delete_fail:
945d8962c   Chris Mason   Merge branch 'cle...
941
  	btrfs_release_path(path);
16cdcec73   Miao Xie   btrfs: implement ...
942
943
944
945
946
947
948
  	mutex_unlock(&node->mutex);
  	return ret;
  }
  
  static void btrfs_release_delayed_inode(struct btrfs_delayed_node *delayed_node)
  {
  	struct btrfs_delayed_root *delayed_root;
7cf35d91b   Miao Xie   Btrfs: use flags ...
949
950
  	if (delayed_node &&
  	    test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags)) {
16cdcec73   Miao Xie   btrfs: implement ...
951
  		BUG_ON(!delayed_node->root);
7cf35d91b   Miao Xie   Btrfs: use flags ...
952
  		clear_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags);
16cdcec73   Miao Xie   btrfs: implement ...
953
954
955
  		delayed_node->count--;
  
  		delayed_root = delayed_node->root->fs_info->delayed_root;
de3cb945d   Chris Mason   Btrfs: improve th...
956
  		finish_one_item(delayed_root);
16cdcec73   Miao Xie   btrfs: implement ...
957
958
  	}
  }
67de11769   Miao Xie   Btrfs: introduce ...
959
960
961
962
963
964
965
966
967
968
969
  static void btrfs_release_delayed_iref(struct btrfs_delayed_node *delayed_node)
  {
  	struct btrfs_delayed_root *delayed_root;
  
  	ASSERT(delayed_node->root);
  	clear_bit(BTRFS_DELAYED_NODE_DEL_IREF, &delayed_node->flags);
  	delayed_node->count--;
  
  	delayed_root = delayed_node->root->fs_info->delayed_root;
  	finish_one_item(delayed_root);
  }
0e8c36a9f   Miao Xie   Btrfs: fix lots o...
970
971
972
973
  static int __btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
  					struct btrfs_root *root,
  					struct btrfs_path *path,
  					struct btrfs_delayed_node *node)
16cdcec73   Miao Xie   btrfs: implement ...
974
  {
2ff7e61e0   Jeff Mahoney   btrfs: take an fs...
975
  	struct btrfs_fs_info *fs_info = root->fs_info;
16cdcec73   Miao Xie   btrfs: implement ...
976
977
978
  	struct btrfs_key key;
  	struct btrfs_inode_item *inode_item;
  	struct extent_buffer *leaf;
351cbf6e4   Josef Bacik   btrfs: use nofs a...
979
  	unsigned int nofs_flag;
67de11769   Miao Xie   Btrfs: introduce ...
980
  	int mod;
16cdcec73   Miao Xie   btrfs: implement ...
981
  	int ret;
16cdcec73   Miao Xie   btrfs: implement ...
982
  	key.objectid = node->inode_id;
962a298f3   David Sterba   btrfs: kill the k...
983
  	key.type = BTRFS_INODE_ITEM_KEY;
16cdcec73   Miao Xie   btrfs: implement ...
984
  	key.offset = 0;
0e8c36a9f   Miao Xie   Btrfs: fix lots o...
985

67de11769   Miao Xie   Btrfs: introduce ...
986
987
988
989
  	if (test_bit(BTRFS_DELAYED_NODE_DEL_IREF, &node->flags))
  		mod = -1;
  	else
  		mod = 1;
351cbf6e4   Josef Bacik   btrfs: use nofs a...
990
  	nofs_flag = memalloc_nofs_save();
67de11769   Miao Xie   Btrfs: introduce ...
991
  	ret = btrfs_lookup_inode(trans, root, path, &key, mod);
351cbf6e4   Josef Bacik   btrfs: use nofs a...
992
  	memalloc_nofs_restore(nofs_flag);
16cdcec73   Miao Xie   btrfs: implement ...
993
  	if (ret > 0) {
945d8962c   Chris Mason   Merge branch 'cle...
994
  		btrfs_release_path(path);
16cdcec73   Miao Xie   btrfs: implement ...
995
996
  		return -ENOENT;
  	} else if (ret < 0) {
16cdcec73   Miao Xie   btrfs: implement ...
997
998
  		return ret;
  	}
16cdcec73   Miao Xie   btrfs: implement ...
999
1000
1001
1002
1003
1004
  	leaf = path->nodes[0];
  	inode_item = btrfs_item_ptr(leaf, path->slots[0],
  				    struct btrfs_inode_item);
  	write_extent_buffer(leaf, &node->inode_item, (unsigned long)inode_item,
  			    sizeof(struct btrfs_inode_item));
  	btrfs_mark_buffer_dirty(leaf);
16cdcec73   Miao Xie   btrfs: implement ...
1005

67de11769   Miao Xie   Btrfs: introduce ...
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
  	if (!test_bit(BTRFS_DELAYED_NODE_DEL_IREF, &node->flags))
  		goto no_iref;
  
  	path->slots[0]++;
  	if (path->slots[0] >= btrfs_header_nritems(leaf))
  		goto search;
  again:
  	btrfs_item_key_to_cpu(leaf, &key, path->slots[0]);
  	if (key.objectid != node->inode_id)
  		goto out;
  
  	if (key.type != BTRFS_INODE_REF_KEY &&
  	    key.type != BTRFS_INODE_EXTREF_KEY)
  		goto out;
  
  	/*
  	 * Delayed iref deletion is for the inode who has only one link,
  	 * so there is only one iref. The case that several irefs are
  	 * in the same item doesn't exist.
  	 */
  	btrfs_del_item(trans, root, path);
  out:
  	btrfs_release_delayed_iref(node);
  no_iref:
  	btrfs_release_path(path);
  err_out:
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
1032
  	btrfs_delayed_inode_release_metadata(fs_info, node, (ret < 0));
16cdcec73   Miao Xie   btrfs: implement ...
1033
  	btrfs_release_delayed_inode(node);
16cdcec73   Miao Xie   btrfs: implement ...
1034

67de11769   Miao Xie   Btrfs: introduce ...
1035
1036
1037
1038
  	return ret;
  
  search:
  	btrfs_release_path(path);
962a298f3   David Sterba   btrfs: kill the k...
1039
  	key.type = BTRFS_INODE_EXTREF_KEY;
67de11769   Miao Xie   Btrfs: introduce ...
1040
  	key.offset = -1;
351cbf6e4   Josef Bacik   btrfs: use nofs a...
1041
1042
  
  	nofs_flag = memalloc_nofs_save();
67de11769   Miao Xie   Btrfs: introduce ...
1043
  	ret = btrfs_search_slot(trans, root, &key, path, -1, 1);
351cbf6e4   Josef Bacik   btrfs: use nofs a...
1044
  	memalloc_nofs_restore(nofs_flag);
67de11769   Miao Xie   Btrfs: introduce ...
1045
1046
1047
1048
1049
1050
1051
1052
  	if (ret < 0)
  		goto err_out;
  	ASSERT(ret);
  
  	ret = 0;
  	leaf = path->nodes[0];
  	path->slots[0]--;
  	goto again;
16cdcec73   Miao Xie   btrfs: implement ...
1053
  }
0e8c36a9f   Miao Xie   Btrfs: fix lots o...
1054
1055
1056
1057
1058
1059
1060
1061
  static inline int btrfs_update_delayed_inode(struct btrfs_trans_handle *trans,
  					     struct btrfs_root *root,
  					     struct btrfs_path *path,
  					     struct btrfs_delayed_node *node)
  {
  	int ret;
  
  	mutex_lock(&node->mutex);
7cf35d91b   Miao Xie   Btrfs: use flags ...
1062
  	if (!test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &node->flags)) {
0e8c36a9f   Miao Xie   Btrfs: fix lots o...
1063
1064
1065
1066
1067
1068
1069
1070
  		mutex_unlock(&node->mutex);
  		return 0;
  	}
  
  	ret = __btrfs_update_delayed_inode(trans, root, path, node);
  	mutex_unlock(&node->mutex);
  	return ret;
  }
4ea41ce07   Miao Xie   Btrfs: cleanup si...
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
  static inline int
  __btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
  				   struct btrfs_path *path,
  				   struct btrfs_delayed_node *node)
  {
  	int ret;
  
  	ret = btrfs_insert_delayed_items(trans, path, node->root, node);
  	if (ret)
  		return ret;
  
  	ret = btrfs_delete_delayed_items(trans, path, node->root, node);
  	if (ret)
  		return ret;
  
  	ret = btrfs_update_delayed_inode(trans, node->root, path, node);
  	return ret;
  }
79787eaab   Jeff Mahoney   btrfs: replace ma...
1089
1090
1091
1092
1093
1094
  /*
   * Called when committing the transaction.
   * Returns 0 on success.
   * Returns < 0 on error and returns with an aborted transaction with any
   * outstanding delayed items cleaned up.
   */
b84acab38   Nikolay Borisov   btrfs: Don't pass...
1095
  static int __btrfs_run_delayed_items(struct btrfs_trans_handle *trans, int nr)
16cdcec73   Miao Xie   btrfs: implement ...
1096
  {
b84acab38   Nikolay Borisov   btrfs: Don't pass...
1097
  	struct btrfs_fs_info *fs_info = trans->fs_info;
16cdcec73   Miao Xie   btrfs: implement ...
1098
1099
1100
  	struct btrfs_delayed_root *delayed_root;
  	struct btrfs_delayed_node *curr_node, *prev_node;
  	struct btrfs_path *path;
19fd29495   Miao Xie   btrfs: fix wrong ...
1101
  	struct btrfs_block_rsv *block_rsv;
16cdcec73   Miao Xie   btrfs: implement ...
1102
  	int ret = 0;
96c3f4331   Josef Bacik   Btrfs: flush dela...
1103
  	bool count = (nr > 0);
16cdcec73   Miao Xie   btrfs: implement ...
1104

bf31f87f7   David Sterba   btrfs: add wrappe...
1105
  	if (TRANS_ABORTED(trans))
79787eaab   Jeff Mahoney   btrfs: replace ma...
1106
  		return -EIO;
16cdcec73   Miao Xie   btrfs: implement ...
1107
1108
1109
1110
  	path = btrfs_alloc_path();
  	if (!path)
  		return -ENOMEM;
  	path->leave_spinning = 1;
19fd29495   Miao Xie   btrfs: fix wrong ...
1111
  	block_rsv = trans->block_rsv;
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
1112
  	trans->block_rsv = &fs_info->delayed_block_rsv;
19fd29495   Miao Xie   btrfs: fix wrong ...
1113

ccdf9b305   Jeff Mahoney   btrfs: root->fs_i...
1114
  	delayed_root = fs_info->delayed_root;
16cdcec73   Miao Xie   btrfs: implement ...
1115
1116
  
  	curr_node = btrfs_first_delayed_node(delayed_root);
96c3f4331   Josef Bacik   Btrfs: flush dela...
1117
  	while (curr_node && (!count || (count && nr--))) {
4ea41ce07   Miao Xie   Btrfs: cleanup si...
1118
1119
  		ret = __btrfs_commit_inode_delayed_items(trans, path,
  							 curr_node);
16cdcec73   Miao Xie   btrfs: implement ...
1120
1121
  		if (ret) {
  			btrfs_release_delayed_node(curr_node);
96c3f4331   Josef Bacik   Btrfs: flush dela...
1122
  			curr_node = NULL;
66642832f   Jeff Mahoney   btrfs: btrfs_abor...
1123
  			btrfs_abort_transaction(trans, ret);
16cdcec73   Miao Xie   btrfs: implement ...
1124
1125
1126
1127
1128
1129
1130
  			break;
  		}
  
  		prev_node = curr_node;
  		curr_node = btrfs_next_delayed_node(curr_node);
  		btrfs_release_delayed_node(prev_node);
  	}
96c3f4331   Josef Bacik   Btrfs: flush dela...
1131
1132
  	if (curr_node)
  		btrfs_release_delayed_node(curr_node);
16cdcec73   Miao Xie   btrfs: implement ...
1133
  	btrfs_free_path(path);
19fd29495   Miao Xie   btrfs: fix wrong ...
1134
  	trans->block_rsv = block_rsv;
79787eaab   Jeff Mahoney   btrfs: replace ma...
1135

16cdcec73   Miao Xie   btrfs: implement ...
1136
1137
  	return ret;
  }
e5c304e65   Nikolay Borisov   btrfs: Don't pass...
1138
  int btrfs_run_delayed_items(struct btrfs_trans_handle *trans)
96c3f4331   Josef Bacik   Btrfs: flush dela...
1139
  {
b84acab38   Nikolay Borisov   btrfs: Don't pass...
1140
  	return __btrfs_run_delayed_items(trans, -1);
96c3f4331   Josef Bacik   Btrfs: flush dela...
1141
  }
e5c304e65   Nikolay Borisov   btrfs: Don't pass...
1142
  int btrfs_run_delayed_items_nr(struct btrfs_trans_handle *trans, int nr)
96c3f4331   Josef Bacik   Btrfs: flush dela...
1143
  {
b84acab38   Nikolay Borisov   btrfs: Don't pass...
1144
  	return __btrfs_run_delayed_items(trans, nr);
96c3f4331   Josef Bacik   Btrfs: flush dela...
1145
  }
16cdcec73   Miao Xie   btrfs: implement ...
1146
  int btrfs_commit_inode_delayed_items(struct btrfs_trans_handle *trans,
5f4b32e94   Nikolay Borisov   btrfs: Make btrfs...
1147
  				     struct btrfs_inode *inode)
16cdcec73   Miao Xie   btrfs: implement ...
1148
  {
5f4b32e94   Nikolay Borisov   btrfs: Make btrfs...
1149
  	struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode);
4ea41ce07   Miao Xie   Btrfs: cleanup si...
1150
1151
  	struct btrfs_path *path;
  	struct btrfs_block_rsv *block_rsv;
16cdcec73   Miao Xie   btrfs: implement ...
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
  	int ret;
  
  	if (!delayed_node)
  		return 0;
  
  	mutex_lock(&delayed_node->mutex);
  	if (!delayed_node->count) {
  		mutex_unlock(&delayed_node->mutex);
  		btrfs_release_delayed_node(delayed_node);
  		return 0;
  	}
  	mutex_unlock(&delayed_node->mutex);
4ea41ce07   Miao Xie   Btrfs: cleanup si...
1164
  	path = btrfs_alloc_path();
3c77bd94e   Filipe David Borba Manana   Btrfs: don't leak...
1165
1166
  	if (!path) {
  		btrfs_release_delayed_node(delayed_node);
4ea41ce07   Miao Xie   Btrfs: cleanup si...
1167
  		return -ENOMEM;
3c77bd94e   Filipe David Borba Manana   Btrfs: don't leak...
1168
  	}
4ea41ce07   Miao Xie   Btrfs: cleanup si...
1169
1170
1171
1172
1173
1174
  	path->leave_spinning = 1;
  
  	block_rsv = trans->block_rsv;
  	trans->block_rsv = &delayed_node->root->fs_info->delayed_block_rsv;
  
  	ret = __btrfs_commit_inode_delayed_items(trans, path, delayed_node);
16cdcec73   Miao Xie   btrfs: implement ...
1175
  	btrfs_release_delayed_node(delayed_node);
4ea41ce07   Miao Xie   Btrfs: cleanup si...
1176
1177
  	btrfs_free_path(path);
  	trans->block_rsv = block_rsv;
16cdcec73   Miao Xie   btrfs: implement ...
1178
1179
  	return ret;
  }
aa79021fd   Nikolay Borisov   btrfs: Make btrfs...
1180
  int btrfs_commit_inode_delayed_inode(struct btrfs_inode *inode)
0e8c36a9f   Miao Xie   Btrfs: fix lots o...
1181
  {
3ffbd68c4   David Sterba   btrfs: simplify p...
1182
  	struct btrfs_fs_info *fs_info = inode->root->fs_info;
0e8c36a9f   Miao Xie   Btrfs: fix lots o...
1183
  	struct btrfs_trans_handle *trans;
aa79021fd   Nikolay Borisov   btrfs: Make btrfs...
1184
  	struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode);
0e8c36a9f   Miao Xie   Btrfs: fix lots o...
1185
1186
1187
1188
1189
1190
1191
1192
  	struct btrfs_path *path;
  	struct btrfs_block_rsv *block_rsv;
  	int ret;
  
  	if (!delayed_node)
  		return 0;
  
  	mutex_lock(&delayed_node->mutex);
7cf35d91b   Miao Xie   Btrfs: use flags ...
1193
  	if (!test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags)) {
0e8c36a9f   Miao Xie   Btrfs: fix lots o...
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
  		mutex_unlock(&delayed_node->mutex);
  		btrfs_release_delayed_node(delayed_node);
  		return 0;
  	}
  	mutex_unlock(&delayed_node->mutex);
  
  	trans = btrfs_join_transaction(delayed_node->root);
  	if (IS_ERR(trans)) {
  		ret = PTR_ERR(trans);
  		goto out;
  	}
  
  	path = btrfs_alloc_path();
  	if (!path) {
  		ret = -ENOMEM;
  		goto trans_out;
  	}
  	path->leave_spinning = 1;
  
  	block_rsv = trans->block_rsv;
2ff7e61e0   Jeff Mahoney   btrfs: take an fs...
1214
  	trans->block_rsv = &fs_info->delayed_block_rsv;
0e8c36a9f   Miao Xie   Btrfs: fix lots o...
1215
1216
  
  	mutex_lock(&delayed_node->mutex);
7cf35d91b   Miao Xie   Btrfs: use flags ...
1217
  	if (test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags))
0e8c36a9f   Miao Xie   Btrfs: fix lots o...
1218
1219
1220
1221
1222
1223
1224
1225
1226
  		ret = __btrfs_update_delayed_inode(trans, delayed_node->root,
  						   path, delayed_node);
  	else
  		ret = 0;
  	mutex_unlock(&delayed_node->mutex);
  
  	btrfs_free_path(path);
  	trans->block_rsv = block_rsv;
  trans_out:
3a45bb207   Jeff Mahoney   btrfs: remove roo...
1227
  	btrfs_end_transaction(trans);
2ff7e61e0   Jeff Mahoney   btrfs: take an fs...
1228
  	btrfs_btree_balance_dirty(fs_info);
0e8c36a9f   Miao Xie   Btrfs: fix lots o...
1229
1230
1231
1232
1233
  out:
  	btrfs_release_delayed_node(delayed_node);
  
  	return ret;
  }
f48d1cf59   Nikolay Borisov   btrfs: Make btrfs...
1234
  void btrfs_remove_delayed_node(struct btrfs_inode *inode)
16cdcec73   Miao Xie   btrfs: implement ...
1235
1236
  {
  	struct btrfs_delayed_node *delayed_node;
f48d1cf59   Nikolay Borisov   btrfs: Make btrfs...
1237
  	delayed_node = READ_ONCE(inode->delayed_node);
16cdcec73   Miao Xie   btrfs: implement ...
1238
1239
  	if (!delayed_node)
  		return;
f48d1cf59   Nikolay Borisov   btrfs: Make btrfs...
1240
  	inode->delayed_node = NULL;
16cdcec73   Miao Xie   btrfs: implement ...
1241
1242
  	btrfs_release_delayed_node(delayed_node);
  }
de3cb945d   Chris Mason   Btrfs: improve th...
1243
1244
1245
  struct btrfs_async_delayed_work {
  	struct btrfs_delayed_root *delayed_root;
  	int nr;
d458b0540   Qu Wenruo   btrfs: Cleanup th...
1246
  	struct btrfs_work work;
16cdcec73   Miao Xie   btrfs: implement ...
1247
  };
d458b0540   Qu Wenruo   btrfs: Cleanup th...
1248
  static void btrfs_async_run_delayed_root(struct btrfs_work *work)
16cdcec73   Miao Xie   btrfs: implement ...
1249
  {
de3cb945d   Chris Mason   Btrfs: improve th...
1250
1251
  	struct btrfs_async_delayed_work *async_work;
  	struct btrfs_delayed_root *delayed_root;
16cdcec73   Miao Xie   btrfs: implement ...
1252
1253
1254
1255
  	struct btrfs_trans_handle *trans;
  	struct btrfs_path *path;
  	struct btrfs_delayed_node *delayed_node = NULL;
  	struct btrfs_root *root;
19fd29495   Miao Xie   btrfs: fix wrong ...
1256
  	struct btrfs_block_rsv *block_rsv;
de3cb945d   Chris Mason   Btrfs: improve th...
1257
  	int total_done = 0;
16cdcec73   Miao Xie   btrfs: implement ...
1258

de3cb945d   Chris Mason   Btrfs: improve th...
1259
1260
  	async_work = container_of(work, struct btrfs_async_delayed_work, work);
  	delayed_root = async_work->delayed_root;
16cdcec73   Miao Xie   btrfs: implement ...
1261
1262
1263
1264
  
  	path = btrfs_alloc_path();
  	if (!path)
  		goto out;
16cdcec73   Miao Xie   btrfs: implement ...
1265

617c54a88   Nikolay Borisov   btrfs: Make btrfs...
1266
1267
1268
1269
  	do {
  		if (atomic_read(&delayed_root->items) <
  		    BTRFS_DELAYED_BACKGROUND / 2)
  			break;
de3cb945d   Chris Mason   Btrfs: improve th...
1270

617c54a88   Nikolay Borisov   btrfs: Make btrfs...
1271
1272
1273
  		delayed_node = btrfs_first_prepared_delayed_node(delayed_root);
  		if (!delayed_node)
  			break;
de3cb945d   Chris Mason   Btrfs: improve th...
1274

617c54a88   Nikolay Borisov   btrfs: Make btrfs...
1275
1276
  		path->leave_spinning = 1;
  		root = delayed_node->root;
16cdcec73   Miao Xie   btrfs: implement ...
1277

617c54a88   Nikolay Borisov   btrfs: Make btrfs...
1278
1279
1280
1281
1282
1283
1284
  		trans = btrfs_join_transaction(root);
  		if (IS_ERR(trans)) {
  			btrfs_release_path(path);
  			btrfs_release_prepared_delayed_node(delayed_node);
  			total_done++;
  			continue;
  		}
16cdcec73   Miao Xie   btrfs: implement ...
1285

617c54a88   Nikolay Borisov   btrfs: Make btrfs...
1286
1287
  		block_rsv = trans->block_rsv;
  		trans->block_rsv = &root->fs_info->delayed_block_rsv;
19fd29495   Miao Xie   btrfs: fix wrong ...
1288

617c54a88   Nikolay Borisov   btrfs: Make btrfs...
1289
  		__btrfs_commit_inode_delayed_items(trans, path, delayed_node);
16cdcec73   Miao Xie   btrfs: implement ...
1290

617c54a88   Nikolay Borisov   btrfs: Make btrfs...
1291
1292
1293
  		trans->block_rsv = block_rsv;
  		btrfs_end_transaction(trans);
  		btrfs_btree_balance_dirty_nodelay(root->fs_info);
de3cb945d   Chris Mason   Btrfs: improve th...
1294

617c54a88   Nikolay Borisov   btrfs: Make btrfs...
1295
1296
1297
  		btrfs_release_path(path);
  		btrfs_release_prepared_delayed_node(delayed_node);
  		total_done++;
de3cb945d   Chris Mason   Btrfs: improve th...
1298

617c54a88   Nikolay Borisov   btrfs: Make btrfs...
1299
1300
  	} while ((async_work->nr == 0 && total_done < BTRFS_DELAYED_WRITEBACK)
  		 || total_done < async_work->nr);
de3cb945d   Chris Mason   Btrfs: improve th...
1301

16cdcec73   Miao Xie   btrfs: implement ...
1302
1303
  	btrfs_free_path(path);
  out:
de3cb945d   Chris Mason   Btrfs: improve th...
1304
1305
  	wake_up(&delayed_root->wait);
  	kfree(async_work);
16cdcec73   Miao Xie   btrfs: implement ...
1306
  }
de3cb945d   Chris Mason   Btrfs: improve th...
1307

16cdcec73   Miao Xie   btrfs: implement ...
1308
  static int btrfs_wq_run_delayed_node(struct btrfs_delayed_root *delayed_root,
a585e9489   Daniel Dressler   Btrfs: delayed-in...
1309
  				     struct btrfs_fs_info *fs_info, int nr)
16cdcec73   Miao Xie   btrfs: implement ...
1310
  {
de3cb945d   Chris Mason   Btrfs: improve th...
1311
  	struct btrfs_async_delayed_work *async_work;
16cdcec73   Miao Xie   btrfs: implement ...
1312

de3cb945d   Chris Mason   Btrfs: improve th...
1313
1314
  	async_work = kmalloc(sizeof(*async_work), GFP_NOFS);
  	if (!async_work)
16cdcec73   Miao Xie   btrfs: implement ...
1315
  		return -ENOMEM;
16cdcec73   Miao Xie   btrfs: implement ...
1316

de3cb945d   Chris Mason   Btrfs: improve th...
1317
  	async_work->delayed_root = delayed_root;
a0cac0ec9   Omar Sandoval   btrfs: get rid of...
1318
1319
  	btrfs_init_work(&async_work->work, btrfs_async_run_delayed_root, NULL,
  			NULL);
de3cb945d   Chris Mason   Btrfs: improve th...
1320
  	async_work->nr = nr;
16cdcec73   Miao Xie   btrfs: implement ...
1321

a585e9489   Daniel Dressler   Btrfs: delayed-in...
1322
  	btrfs_queue_work(fs_info->delayed_workers, &async_work->work);
16cdcec73   Miao Xie   btrfs: implement ...
1323
1324
  	return 0;
  }
ccdf9b305   Jeff Mahoney   btrfs: root->fs_i...
1325
  void btrfs_assert_delayed_root_empty(struct btrfs_fs_info *fs_info)
e999376f0   Chris Mason   Btrfs: avoid dela...
1326
  {
ccdf9b305   Jeff Mahoney   btrfs: root->fs_i...
1327
  	WARN_ON(btrfs_first_delayed_node(fs_info->delayed_root));
e999376f0   Chris Mason   Btrfs: avoid dela...
1328
  }
0353808ca   Miao Xie   Btrfs: cleanup co...
1329
  static int could_end_wait(struct btrfs_delayed_root *delayed_root, int seq)
de3cb945d   Chris Mason   Btrfs: improve th...
1330
1331
  {
  	int val = atomic_read(&delayed_root->items_seq);
0353808ca   Miao Xie   Btrfs: cleanup co...
1332
  	if (val < seq || val >= seq + BTRFS_DELAYED_BATCH)
de3cb945d   Chris Mason   Btrfs: improve th...
1333
  		return 1;
0353808ca   Miao Xie   Btrfs: cleanup co...
1334
1335
1336
  
  	if (atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND)
  		return 1;
de3cb945d   Chris Mason   Btrfs: improve th...
1337
1338
  	return 0;
  }
2ff7e61e0   Jeff Mahoney   btrfs: take an fs...
1339
  void btrfs_balance_delayed_items(struct btrfs_fs_info *fs_info)
16cdcec73   Miao Xie   btrfs: implement ...
1340
  {
2ff7e61e0   Jeff Mahoney   btrfs: take an fs...
1341
  	struct btrfs_delayed_root *delayed_root = fs_info->delayed_root;
16cdcec73   Miao Xie   btrfs: implement ...
1342

8577787fa   Nikolay Borisov   btrfs: Move check...
1343
1344
  	if ((atomic_read(&delayed_root->items) < BTRFS_DELAYED_BACKGROUND) ||
  		btrfs_workqueue_normal_congested(fs_info->delayed_workers))
16cdcec73   Miao Xie   btrfs: implement ...
1345
1346
1347
  		return;
  
  	if (atomic_read(&delayed_root->items) >= BTRFS_DELAYED_WRITEBACK) {
0353808ca   Miao Xie   Btrfs: cleanup co...
1348
  		int seq;
16cdcec73   Miao Xie   btrfs: implement ...
1349
  		int ret;
0353808ca   Miao Xie   Btrfs: cleanup co...
1350
1351
  
  		seq = atomic_read(&delayed_root->items_seq);
de3cb945d   Chris Mason   Btrfs: improve th...
1352

a585e9489   Daniel Dressler   Btrfs: delayed-in...
1353
  		ret = btrfs_wq_run_delayed_node(delayed_root, fs_info, 0);
16cdcec73   Miao Xie   btrfs: implement ...
1354
1355
  		if (ret)
  			return;
0353808ca   Miao Xie   Btrfs: cleanup co...
1356
1357
  		wait_event_interruptible(delayed_root->wait,
  					 could_end_wait(delayed_root, seq));
4dd466d36   Miao Xie   Btrfs: don't run ...
1358
  		return;
16cdcec73   Miao Xie   btrfs: implement ...
1359
  	}
a585e9489   Daniel Dressler   Btrfs: delayed-in...
1360
  	btrfs_wq_run_delayed_node(delayed_root, fs_info, BTRFS_DELAYED_BATCH);
16cdcec73   Miao Xie   btrfs: implement ...
1361
  }
79787eaab   Jeff Mahoney   btrfs: replace ma...
1362
  /* Will return 0 or -ENOMEM */
16cdcec73   Miao Xie   btrfs: implement ...
1363
  int btrfs_insert_delayed_dir_index(struct btrfs_trans_handle *trans,
2ff7e61e0   Jeff Mahoney   btrfs: take an fs...
1364
  				   const char *name, int name_len,
6f45d1856   Nikolay Borisov   btrfs: Make btrfs...
1365
  				   struct btrfs_inode *dir,
16cdcec73   Miao Xie   btrfs: implement ...
1366
1367
1368
1369
1370
1371
1372
  				   struct btrfs_disk_key *disk_key, u8 type,
  				   u64 index)
  {
  	struct btrfs_delayed_node *delayed_node;
  	struct btrfs_delayed_item *delayed_item;
  	struct btrfs_dir_item *dir_item;
  	int ret;
6f45d1856   Nikolay Borisov   btrfs: Make btrfs...
1373
  	delayed_node = btrfs_get_or_create_delayed_node(dir);
16cdcec73   Miao Xie   btrfs: implement ...
1374
1375
1376
1377
1378
1379
1380
1381
  	if (IS_ERR(delayed_node))
  		return PTR_ERR(delayed_node);
  
  	delayed_item = btrfs_alloc_delayed_item(sizeof(*dir_item) + name_len);
  	if (!delayed_item) {
  		ret = -ENOMEM;
  		goto release_node;
  	}
6f45d1856   Nikolay Borisov   btrfs: Make btrfs...
1382
  	delayed_item->key.objectid = btrfs_ino(dir);
962a298f3   David Sterba   btrfs: kill the k...
1383
  	delayed_item->key.type = BTRFS_DIR_INDEX_KEY;
16cdcec73   Miao Xie   btrfs: implement ...
1384
1385
1386
1387
  	delayed_item->key.offset = index;
  
  	dir_item = (struct btrfs_dir_item *)delayed_item->data;
  	dir_item->location = *disk_key;
3cae210fa   Qu Wenruo   btrfs: Cleanup fo...
1388
1389
1390
1391
  	btrfs_set_stack_dir_transid(dir_item, trans->transid);
  	btrfs_set_stack_dir_data_len(dir_item, 0);
  	btrfs_set_stack_dir_name_len(dir_item, name_len);
  	btrfs_set_stack_dir_type(dir_item, type);
16cdcec73   Miao Xie   btrfs: implement ...
1392
  	memcpy((char *)(dir_item + 1), name, name_len);
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
1393
  	ret = btrfs_delayed_item_reserve_metadata(trans, dir->root, delayed_item);
8c2a3ca20   Josef Bacik   Btrfs: space leak...
1394
1395
1396
1397
1398
  	/*
  	 * we have reserved enough space when we start a new transaction,
  	 * so reserving metadata failure is impossible
  	 */
  	BUG_ON(ret);
16cdcec73   Miao Xie   btrfs: implement ...
1399
1400
1401
  	mutex_lock(&delayed_node->mutex);
  	ret = __btrfs_add_delayed_insertion_item(delayed_node, delayed_item);
  	if (unlikely(ret)) {
4465c8b42   Lu Fengqi   btrfs: Remove fs_...
1402
  		btrfs_err(trans->fs_info,
5d163e0e6   Jeff Mahoney   btrfs: unsplit pr...
1403
  			  "err add delayed dir index item(name: %.*s) into the insertion tree of the delayed node(root id: %llu, inode id: %llu, errno: %d)",
4fd786e6c   Misono Tomohiro   btrfs: Remove 'ob...
1404
  			  name_len, name, delayed_node->root->root_key.objectid,
5d163e0e6   Jeff Mahoney   btrfs: unsplit pr...
1405
  			  delayed_node->inode_id, ret);
16cdcec73   Miao Xie   btrfs: implement ...
1406
1407
1408
1409
1410
1411
1412
1413
  		BUG();
  	}
  	mutex_unlock(&delayed_node->mutex);
  
  release_node:
  	btrfs_release_delayed_node(delayed_node);
  	return ret;
  }
2ff7e61e0   Jeff Mahoney   btrfs: take an fs...
1414
  static int btrfs_delete_delayed_insertion_item(struct btrfs_fs_info *fs_info,
16cdcec73   Miao Xie   btrfs: implement ...
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
  					       struct btrfs_delayed_node *node,
  					       struct btrfs_key *key)
  {
  	struct btrfs_delayed_item *item;
  
  	mutex_lock(&node->mutex);
  	item = __btrfs_lookup_delayed_insertion_item(node, key);
  	if (!item) {
  		mutex_unlock(&node->mutex);
  		return 1;
  	}
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
1426
  	btrfs_delayed_item_release_metadata(node->root, item);
16cdcec73   Miao Xie   btrfs: implement ...
1427
1428
1429
1430
1431
1432
  	btrfs_release_delayed_item(item);
  	mutex_unlock(&node->mutex);
  	return 0;
  }
  
  int btrfs_delete_delayed_dir_index(struct btrfs_trans_handle *trans,
e67bbbb9d   Nikolay Borisov   btrfs: Make btrfs...
1433
  				   struct btrfs_inode *dir, u64 index)
16cdcec73   Miao Xie   btrfs: implement ...
1434
1435
1436
1437
1438
  {
  	struct btrfs_delayed_node *node;
  	struct btrfs_delayed_item *item;
  	struct btrfs_key item_key;
  	int ret;
e67bbbb9d   Nikolay Borisov   btrfs: Make btrfs...
1439
  	node = btrfs_get_or_create_delayed_node(dir);
16cdcec73   Miao Xie   btrfs: implement ...
1440
1441
  	if (IS_ERR(node))
  		return PTR_ERR(node);
e67bbbb9d   Nikolay Borisov   btrfs: Make btrfs...
1442
  	item_key.objectid = btrfs_ino(dir);
962a298f3   David Sterba   btrfs: kill the k...
1443
  	item_key.type = BTRFS_DIR_INDEX_KEY;
16cdcec73   Miao Xie   btrfs: implement ...
1444
  	item_key.offset = index;
9add29457   Lu Fengqi   btrfs: Remove fs_...
1445
1446
  	ret = btrfs_delete_delayed_insertion_item(trans->fs_info, node,
  						  &item_key);
16cdcec73   Miao Xie   btrfs: implement ...
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
  	if (!ret)
  		goto end;
  
  	item = btrfs_alloc_delayed_item(0);
  	if (!item) {
  		ret = -ENOMEM;
  		goto end;
  	}
  
  	item->key = item_key;
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
1457
  	ret = btrfs_delayed_item_reserve_metadata(trans, dir->root, item);
16cdcec73   Miao Xie   btrfs: implement ...
1458
1459
1460
1461
  	/*
  	 * we have reserved enough space when we start a new transaction,
  	 * so reserving metadata failure is impossible.
  	 */
933c22a75   Qu Wenruo   btrfs: delayed-in...
1462
1463
1464
1465
1466
1467
  	if (ret < 0) {
  		btrfs_err(trans->fs_info,
  "metadata reservation failed for delayed dir item deltiona, should have been reserved");
  		btrfs_release_delayed_item(item);
  		goto end;
  	}
16cdcec73   Miao Xie   btrfs: implement ...
1468
1469
1470
1471
  
  	mutex_lock(&node->mutex);
  	ret = __btrfs_add_delayed_deletion_item(node, item);
  	if (unlikely(ret)) {
9add29457   Lu Fengqi   btrfs: Remove fs_...
1472
  		btrfs_err(trans->fs_info,
5d163e0e6   Jeff Mahoney   btrfs: unsplit pr...
1473
  			  "err add delayed dir index item(index: %llu) into the deletion tree of the delayed node(root id: %llu, inode id: %llu, errno: %d)",
4fd786e6c   Misono Tomohiro   btrfs: Remove 'ob...
1474
1475
  			  index, node->root->root_key.objectid,
  			  node->inode_id, ret);
933c22a75   Qu Wenruo   btrfs: delayed-in...
1476
1477
  		btrfs_delayed_item_release_metadata(dir->root, item);
  		btrfs_release_delayed_item(item);
16cdcec73   Miao Xie   btrfs: implement ...
1478
1479
1480
1481
1482
1483
  	}
  	mutex_unlock(&node->mutex);
  end:
  	btrfs_release_delayed_node(node);
  	return ret;
  }
f5cc7b80a   Nikolay Borisov   btrfs: Make btrfs...
1484
  int btrfs_inode_delayed_dir_index_count(struct btrfs_inode *inode)
16cdcec73   Miao Xie   btrfs: implement ...
1485
  {
f5cc7b80a   Nikolay Borisov   btrfs: Make btrfs...
1486
  	struct btrfs_delayed_node *delayed_node = btrfs_get_delayed_node(inode);
16cdcec73   Miao Xie   btrfs: implement ...
1487
1488
1489
1490
1491
1492
1493
1494
1495
  
  	if (!delayed_node)
  		return -ENOENT;
  
  	/*
  	 * Since we have held i_mutex of this directory, it is impossible that
  	 * a new directory index is added into the delayed node and index_cnt
  	 * is updated now. So we needn't lock the delayed node.
  	 */
2f7e33d43   Miao Xie   btrfs: fix incons...
1496
1497
  	if (!delayed_node->index_cnt) {
  		btrfs_release_delayed_node(delayed_node);
16cdcec73   Miao Xie   btrfs: implement ...
1498
  		return -EINVAL;
2f7e33d43   Miao Xie   btrfs: fix incons...
1499
  	}
16cdcec73   Miao Xie   btrfs: implement ...
1500

f5cc7b80a   Nikolay Borisov   btrfs: Make btrfs...
1501
  	inode->index_cnt = delayed_node->index_cnt;
2f7e33d43   Miao Xie   btrfs: fix incons...
1502
1503
  	btrfs_release_delayed_node(delayed_node);
  	return 0;
16cdcec73   Miao Xie   btrfs: implement ...
1504
  }
02dbfc99b   Omar Sandoval   Btrfs: fix ->iter...
1505
1506
1507
  bool btrfs_readdir_get_delayed_items(struct inode *inode,
  				     struct list_head *ins_list,
  				     struct list_head *del_list)
16cdcec73   Miao Xie   btrfs: implement ...
1508
1509
1510
  {
  	struct btrfs_delayed_node *delayed_node;
  	struct btrfs_delayed_item *item;
340c6ca9f   Nikolay Borisov   btrfs: Make btrfs...
1511
  	delayed_node = btrfs_get_delayed_node(BTRFS_I(inode));
16cdcec73   Miao Xie   btrfs: implement ...
1512
  	if (!delayed_node)
02dbfc99b   Omar Sandoval   Btrfs: fix ->iter...
1513
1514
1515
1516
1517
1518
1519
1520
  		return false;
  
  	/*
  	 * We can only do one readdir with delayed items at a time because of
  	 * item->readdir_list.
  	 */
  	inode_unlock_shared(inode);
  	inode_lock(inode);
16cdcec73   Miao Xie   btrfs: implement ...
1521
1522
1523
1524
  
  	mutex_lock(&delayed_node->mutex);
  	item = __btrfs_first_delayed_insertion_item(delayed_node);
  	while (item) {
089e77e10   Elena Reshetova   btrfs: convert bt...
1525
  		refcount_inc(&item->refs);
16cdcec73   Miao Xie   btrfs: implement ...
1526
1527
1528
1529
1530
1531
  		list_add_tail(&item->readdir_list, ins_list);
  		item = __btrfs_next_delayed_item(item);
  	}
  
  	item = __btrfs_first_delayed_deletion_item(delayed_node);
  	while (item) {
089e77e10   Elena Reshetova   btrfs: convert bt...
1532
  		refcount_inc(&item->refs);
16cdcec73   Miao Xie   btrfs: implement ...
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
  		list_add_tail(&item->readdir_list, del_list);
  		item = __btrfs_next_delayed_item(item);
  	}
  	mutex_unlock(&delayed_node->mutex);
  	/*
  	 * This delayed node is still cached in the btrfs inode, so refs
  	 * must be > 1 now, and we needn't check it is going to be freed
  	 * or not.
  	 *
  	 * Besides that, this function is used to read dir, we do not
  	 * insert/delete delayed items in this period. So we also needn't
  	 * requeue or dequeue this delayed node.
  	 */
6de5f18e7   Elena Reshetova   btrfs: convert bt...
1546
  	refcount_dec(&delayed_node->refs);
02dbfc99b   Omar Sandoval   Btrfs: fix ->iter...
1547
1548
  
  	return true;
16cdcec73   Miao Xie   btrfs: implement ...
1549
  }
02dbfc99b   Omar Sandoval   Btrfs: fix ->iter...
1550
1551
1552
  void btrfs_readdir_put_delayed_items(struct inode *inode,
  				     struct list_head *ins_list,
  				     struct list_head *del_list)
16cdcec73   Miao Xie   btrfs: implement ...
1553
1554
1555
1556
1557
  {
  	struct btrfs_delayed_item *curr, *next;
  
  	list_for_each_entry_safe(curr, next, ins_list, readdir_list) {
  		list_del(&curr->readdir_list);
089e77e10   Elena Reshetova   btrfs: convert bt...
1558
  		if (refcount_dec_and_test(&curr->refs))
16cdcec73   Miao Xie   btrfs: implement ...
1559
1560
1561
1562
1563
  			kfree(curr);
  	}
  
  	list_for_each_entry_safe(curr, next, del_list, readdir_list) {
  		list_del(&curr->readdir_list);
089e77e10   Elena Reshetova   btrfs: convert bt...
1564
  		if (refcount_dec_and_test(&curr->refs))
16cdcec73   Miao Xie   btrfs: implement ...
1565
1566
  			kfree(curr);
  	}
02dbfc99b   Omar Sandoval   Btrfs: fix ->iter...
1567
1568
1569
1570
1571
1572
  
  	/*
  	 * The VFS is going to do up_read(), so we need to downgrade back to a
  	 * read lock.
  	 */
  	downgrade_write(&inode->i_rwsem);
16cdcec73   Miao Xie   btrfs: implement ...
1573
1574
1575
1576
1577
  }
  
  int btrfs_should_delete_dir_index(struct list_head *del_list,
  				  u64 index)
  {
e4fd493c0   Josef Bacik   Btrfs: fix stale ...
1578
1579
  	struct btrfs_delayed_item *curr;
  	int ret = 0;
16cdcec73   Miao Xie   btrfs: implement ...
1580

e4fd493c0   Josef Bacik   Btrfs: fix stale ...
1581
  	list_for_each_entry(curr, del_list, readdir_list) {
16cdcec73   Miao Xie   btrfs: implement ...
1582
1583
  		if (curr->key.offset > index)
  			break;
e4fd493c0   Josef Bacik   Btrfs: fix stale ...
1584
1585
1586
1587
  		if (curr->key.offset == index) {
  			ret = 1;
  			break;
  		}
16cdcec73   Miao Xie   btrfs: implement ...
1588
  	}
e4fd493c0   Josef Bacik   Btrfs: fix stale ...
1589
  	return ret;
16cdcec73   Miao Xie   btrfs: implement ...
1590
1591
1592
1593
1594
1595
  }
  
  /*
   * btrfs_readdir_delayed_dir_index - read dir info stored in the delayed tree
   *
   */
9cdda8d31   Al Viro   [readdir] convert...
1596
  int btrfs_readdir_delayed_dir_index(struct dir_context *ctx,
d2fbb2b58   Jeff Mahoney   btrfs: increment ...
1597
  				    struct list_head *ins_list)
16cdcec73   Miao Xie   btrfs: implement ...
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
  {
  	struct btrfs_dir_item *di;
  	struct btrfs_delayed_item *curr, *next;
  	struct btrfs_key location;
  	char *name;
  	int name_len;
  	int over = 0;
  	unsigned char d_type;
  
  	if (list_empty(ins_list))
  		return 0;
  
  	/*
  	 * Changing the data of the delayed item is impossible. So
  	 * we needn't lock them. And we have held i_mutex of the
  	 * directory, nobody can delete any directory indexes now.
  	 */
  	list_for_each_entry_safe(curr, next, ins_list, readdir_list) {
  		list_del(&curr->readdir_list);
9cdda8d31   Al Viro   [readdir] convert...
1617
  		if (curr->key.offset < ctx->pos) {
089e77e10   Elena Reshetova   btrfs: convert bt...
1618
  			if (refcount_dec_and_test(&curr->refs))
16cdcec73   Miao Xie   btrfs: implement ...
1619
1620
1621
  				kfree(curr);
  			continue;
  		}
9cdda8d31   Al Viro   [readdir] convert...
1622
  		ctx->pos = curr->key.offset;
16cdcec73   Miao Xie   btrfs: implement ...
1623
1624
1625
  
  		di = (struct btrfs_dir_item *)curr->data;
  		name = (char *)(di + 1);
3cae210fa   Qu Wenruo   btrfs: Cleanup fo...
1626
  		name_len = btrfs_stack_dir_name_len(di);
16cdcec73   Miao Xie   btrfs: implement ...
1627

7d157c3d4   Phillip Potter   btrfs: use common...
1628
  		d_type = fs_ftype_to_dtype(di->type);
16cdcec73   Miao Xie   btrfs: implement ...
1629
  		btrfs_disk_key_to_cpu(&location, &di->location);
9cdda8d31   Al Viro   [readdir] convert...
1630
  		over = !dir_emit(ctx, name, name_len,
16cdcec73   Miao Xie   btrfs: implement ...
1631
  			       location.objectid, d_type);
089e77e10   Elena Reshetova   btrfs: convert bt...
1632
  		if (refcount_dec_and_test(&curr->refs))
16cdcec73   Miao Xie   btrfs: implement ...
1633
1634
1635
1636
  			kfree(curr);
  
  		if (over)
  			return 1;
42e9cc46f   Josef Bacik   btrfs: increase c...
1637
  		ctx->pos++;
16cdcec73   Miao Xie   btrfs: implement ...
1638
1639
1640
  	}
  	return 0;
  }
16cdcec73   Miao Xie   btrfs: implement ...
1641
1642
1643
1644
  static void fill_stack_inode_item(struct btrfs_trans_handle *trans,
  				  struct btrfs_inode_item *inode_item,
  				  struct inode *inode)
  {
2f2f43d3c   Eric W. Biederman   userns: Convert b...
1645
1646
  	btrfs_set_stack_inode_uid(inode_item, i_uid_read(inode));
  	btrfs_set_stack_inode_gid(inode_item, i_gid_read(inode));
16cdcec73   Miao Xie   btrfs: implement ...
1647
1648
1649
1650
1651
1652
  	btrfs_set_stack_inode_size(inode_item, BTRFS_I(inode)->disk_i_size);
  	btrfs_set_stack_inode_mode(inode_item, inode->i_mode);
  	btrfs_set_stack_inode_nlink(inode_item, inode->i_nlink);
  	btrfs_set_stack_inode_nbytes(inode_item, inode_get_bytes(inode));
  	btrfs_set_stack_inode_generation(inode_item,
  					 BTRFS_I(inode)->generation);
c7f88c4e7   Jeff Layton   btrfs: convert to...
1653
1654
  	btrfs_set_stack_inode_sequence(inode_item,
  				       inode_peek_iversion(inode));
16cdcec73   Miao Xie   btrfs: implement ...
1655
1656
1657
  	btrfs_set_stack_inode_transid(inode_item, trans->transid);
  	btrfs_set_stack_inode_rdev(inode_item, inode->i_rdev);
  	btrfs_set_stack_inode_flags(inode_item, BTRFS_I(inode)->flags);
ff5714cca   Chris Mason   Merge branch 'for...
1658
  	btrfs_set_stack_inode_block_group(inode_item, 0);
16cdcec73   Miao Xie   btrfs: implement ...
1659

a937b9791   David Sterba   btrfs: kill btrfs...
1660
  	btrfs_set_stack_timespec_sec(&inode_item->atime,
16cdcec73   Miao Xie   btrfs: implement ...
1661
  				     inode->i_atime.tv_sec);
a937b9791   David Sterba   btrfs: kill btrfs...
1662
  	btrfs_set_stack_timespec_nsec(&inode_item->atime,
16cdcec73   Miao Xie   btrfs: implement ...
1663
  				      inode->i_atime.tv_nsec);
a937b9791   David Sterba   btrfs: kill btrfs...
1664
  	btrfs_set_stack_timespec_sec(&inode_item->mtime,
16cdcec73   Miao Xie   btrfs: implement ...
1665
  				     inode->i_mtime.tv_sec);
a937b9791   David Sterba   btrfs: kill btrfs...
1666
  	btrfs_set_stack_timespec_nsec(&inode_item->mtime,
16cdcec73   Miao Xie   btrfs: implement ...
1667
  				      inode->i_mtime.tv_nsec);
a937b9791   David Sterba   btrfs: kill btrfs...
1668
  	btrfs_set_stack_timespec_sec(&inode_item->ctime,
16cdcec73   Miao Xie   btrfs: implement ...
1669
  				     inode->i_ctime.tv_sec);
a937b9791   David Sterba   btrfs: kill btrfs...
1670
  	btrfs_set_stack_timespec_nsec(&inode_item->ctime,
16cdcec73   Miao Xie   btrfs: implement ...
1671
  				      inode->i_ctime.tv_nsec);
9cc97d646   chandan r   Btrfs: Add code t...
1672
1673
1674
1675
1676
  
  	btrfs_set_stack_timespec_sec(&inode_item->otime,
  				     BTRFS_I(inode)->i_otime.tv_sec);
  	btrfs_set_stack_timespec_nsec(&inode_item->otime,
  				     BTRFS_I(inode)->i_otime.tv_nsec);
16cdcec73   Miao Xie   btrfs: implement ...
1677
  }
2f7e33d43   Miao Xie   btrfs: fix incons...
1678
1679
  int btrfs_fill_inode(struct inode *inode, u32 *rdev)
  {
9ddc959e8   Josef Bacik   btrfs: use the fi...
1680
  	struct btrfs_fs_info *fs_info = BTRFS_I(inode)->root->fs_info;
2f7e33d43   Miao Xie   btrfs: fix incons...
1681
1682
  	struct btrfs_delayed_node *delayed_node;
  	struct btrfs_inode_item *inode_item;
2f7e33d43   Miao Xie   btrfs: fix incons...
1683

340c6ca9f   Nikolay Borisov   btrfs: Make btrfs...
1684
  	delayed_node = btrfs_get_delayed_node(BTRFS_I(inode));
2f7e33d43   Miao Xie   btrfs: fix incons...
1685
1686
1687
1688
  	if (!delayed_node)
  		return -ENOENT;
  
  	mutex_lock(&delayed_node->mutex);
7cf35d91b   Miao Xie   Btrfs: use flags ...
1689
  	if (!test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags)) {
2f7e33d43   Miao Xie   btrfs: fix incons...
1690
1691
1692
1693
1694
1695
  		mutex_unlock(&delayed_node->mutex);
  		btrfs_release_delayed_node(delayed_node);
  		return -ENOENT;
  	}
  
  	inode_item = &delayed_node->inode_item;
2f2f43d3c   Eric W. Biederman   userns: Convert b...
1696
1697
  	i_uid_write(inode, btrfs_stack_inode_uid(inode_item));
  	i_gid_write(inode, btrfs_stack_inode_gid(inode_item));
6ef06d279   Nikolay Borisov   btrfs: Make btrfs...
1698
  	btrfs_i_size_write(BTRFS_I(inode), btrfs_stack_inode_size(inode_item));
9ddc959e8   Josef Bacik   btrfs: use the fi...
1699
1700
  	btrfs_inode_set_file_extent_range(BTRFS_I(inode), 0,
  			round_up(i_size_read(inode), fs_info->sectorsize));
2f7e33d43   Miao Xie   btrfs: fix incons...
1701
  	inode->i_mode = btrfs_stack_inode_mode(inode_item);
bfe868486   Miklos Szeredi   filesystems: add ...
1702
  	set_nlink(inode, btrfs_stack_inode_nlink(inode_item));
2f7e33d43   Miao Xie   btrfs: fix incons...
1703
1704
  	inode_set_bytes(inode, btrfs_stack_inode_nbytes(inode_item));
  	BTRFS_I(inode)->generation = btrfs_stack_inode_generation(inode_item);
6e17d30bf   Yang Dongsheng   Btrfs: fill ->las...
1705
          BTRFS_I(inode)->last_trans = btrfs_stack_inode_transid(inode_item);
c7f88c4e7   Jeff Layton   btrfs: convert to...
1706
1707
  	inode_set_iversion_queried(inode,
  				   btrfs_stack_inode_sequence(inode_item));
2f7e33d43   Miao Xie   btrfs: fix incons...
1708
1709
1710
  	inode->i_rdev = 0;
  	*rdev = btrfs_stack_inode_rdev(inode_item);
  	BTRFS_I(inode)->flags = btrfs_stack_inode_flags(inode_item);
a937b9791   David Sterba   btrfs: kill btrfs...
1711
1712
  	inode->i_atime.tv_sec = btrfs_stack_timespec_sec(&inode_item->atime);
  	inode->i_atime.tv_nsec = btrfs_stack_timespec_nsec(&inode_item->atime);
2f7e33d43   Miao Xie   btrfs: fix incons...
1713

a937b9791   David Sterba   btrfs: kill btrfs...
1714
1715
  	inode->i_mtime.tv_sec = btrfs_stack_timespec_sec(&inode_item->mtime);
  	inode->i_mtime.tv_nsec = btrfs_stack_timespec_nsec(&inode_item->mtime);
2f7e33d43   Miao Xie   btrfs: fix incons...
1716

a937b9791   David Sterba   btrfs: kill btrfs...
1717
1718
  	inode->i_ctime.tv_sec = btrfs_stack_timespec_sec(&inode_item->ctime);
  	inode->i_ctime.tv_nsec = btrfs_stack_timespec_nsec(&inode_item->ctime);
2f7e33d43   Miao Xie   btrfs: fix incons...
1719

9cc97d646   chandan r   Btrfs: Add code t...
1720
1721
1722
1723
  	BTRFS_I(inode)->i_otime.tv_sec =
  		btrfs_stack_timespec_sec(&inode_item->otime);
  	BTRFS_I(inode)->i_otime.tv_nsec =
  		btrfs_stack_timespec_nsec(&inode_item->otime);
2f7e33d43   Miao Xie   btrfs: fix incons...
1724
1725
1726
1727
1728
1729
1730
  	inode->i_generation = BTRFS_I(inode)->generation;
  	BTRFS_I(inode)->index_cnt = (u64)-1;
  
  	mutex_unlock(&delayed_node->mutex);
  	btrfs_release_delayed_node(delayed_node);
  	return 0;
  }
16cdcec73   Miao Xie   btrfs: implement ...
1731
1732
1733
1734
  int btrfs_delayed_update_inode(struct btrfs_trans_handle *trans,
  			       struct btrfs_root *root, struct inode *inode)
  {
  	struct btrfs_delayed_node *delayed_node;
aa0467d8d   David Sterba   btrfs: fix uninit...
1735
  	int ret = 0;
16cdcec73   Miao Xie   btrfs: implement ...
1736

e5517a7bf   Nikolay Borisov   btrfs: Make btrfs...
1737
  	delayed_node = btrfs_get_or_create_delayed_node(BTRFS_I(inode));
16cdcec73   Miao Xie   btrfs: implement ...
1738
1739
1740
1741
  	if (IS_ERR(delayed_node))
  		return PTR_ERR(delayed_node);
  
  	mutex_lock(&delayed_node->mutex);
7cf35d91b   Miao Xie   Btrfs: use flags ...
1742
  	if (test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags)) {
16cdcec73   Miao Xie   btrfs: implement ...
1743
1744
1745
  		fill_stack_inode_item(trans, &delayed_node->inode_item, inode);
  		goto release_node;
  	}
fcabdd1ca   Nikolay Borisov   btrfs: Make btrfs...
1746
  	ret = btrfs_delayed_inode_reserve_metadata(trans, root, BTRFS_I(inode),
7fd2ae21a   Josef Bacik   Btrfs: fix our re...
1747
  						   delayed_node);
c06a0e120   Josef Bacik   Btrfs: fix delaye...
1748
1749
  	if (ret)
  		goto release_node;
16cdcec73   Miao Xie   btrfs: implement ...
1750
1751
  
  	fill_stack_inode_item(trans, &delayed_node->inode_item, inode);
7cf35d91b   Miao Xie   Btrfs: use flags ...
1752
  	set_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags);
16cdcec73   Miao Xie   btrfs: implement ...
1753
1754
1755
1756
1757
1758
1759
  	delayed_node->count++;
  	atomic_inc(&root->fs_info->delayed_root->items);
  release_node:
  	mutex_unlock(&delayed_node->mutex);
  	btrfs_release_delayed_node(delayed_node);
  	return ret;
  }
e07222c7d   Nikolay Borisov   btrfs: Make btrfs...
1760
  int btrfs_delayed_delete_inode_ref(struct btrfs_inode *inode)
67de11769   Miao Xie   Btrfs: introduce ...
1761
  {
3ffbd68c4   David Sterba   btrfs: simplify p...
1762
  	struct btrfs_fs_info *fs_info = inode->root->fs_info;
67de11769   Miao Xie   Btrfs: introduce ...
1763
  	struct btrfs_delayed_node *delayed_node;
6f8960541   Chris Mason   Btrfs: don't dela...
1764
1765
1766
1767
1768
  	/*
  	 * we don't do delayed inode updates during log recovery because it
  	 * leads to enospc problems.  This means we also can't do
  	 * delayed inode refs
  	 */
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
1769
  	if (test_bit(BTRFS_FS_LOG_RECOVERING, &fs_info->flags))
6f8960541   Chris Mason   Btrfs: don't dela...
1770
  		return -EAGAIN;
e07222c7d   Nikolay Borisov   btrfs: Make btrfs...
1771
  	delayed_node = btrfs_get_or_create_delayed_node(inode);
67de11769   Miao Xie   Btrfs: introduce ...
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
  	if (IS_ERR(delayed_node))
  		return PTR_ERR(delayed_node);
  
  	/*
  	 * We don't reserve space for inode ref deletion is because:
  	 * - We ONLY do async inode ref deletion for the inode who has only
  	 *   one link(i_nlink == 1), it means there is only one inode ref.
  	 *   And in most case, the inode ref and the inode item are in the
  	 *   same leaf, and we will deal with them at the same time.
  	 *   Since we are sure we will reserve the space for the inode item,
  	 *   it is unnecessary to reserve space for inode ref deletion.
  	 * - If the inode ref and the inode item are not in the same leaf,
  	 *   We also needn't worry about enospc problem, because we reserve
  	 *   much more space for the inode update than it needs.
  	 * - At the worst, we can steal some space from the global reservation.
  	 *   It is very rare.
  	 */
  	mutex_lock(&delayed_node->mutex);
  	if (test_bit(BTRFS_DELAYED_NODE_DEL_IREF, &delayed_node->flags))
  		goto release_node;
  
  	set_bit(BTRFS_DELAYED_NODE_DEL_IREF, &delayed_node->flags);
  	delayed_node->count++;
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
1795
  	atomic_inc(&fs_info->delayed_root->items);
67de11769   Miao Xie   Btrfs: introduce ...
1796
1797
1798
1799
1800
  release_node:
  	mutex_unlock(&delayed_node->mutex);
  	btrfs_release_delayed_node(delayed_node);
  	return 0;
  }
16cdcec73   Miao Xie   btrfs: implement ...
1801
1802
1803
  static void __btrfs_kill_delayed_node(struct btrfs_delayed_node *delayed_node)
  {
  	struct btrfs_root *root = delayed_node->root;
2ff7e61e0   Jeff Mahoney   btrfs: take an fs...
1804
  	struct btrfs_fs_info *fs_info = root->fs_info;
16cdcec73   Miao Xie   btrfs: implement ...
1805
1806
1807
1808
1809
  	struct btrfs_delayed_item *curr_item, *prev_item;
  
  	mutex_lock(&delayed_node->mutex);
  	curr_item = __btrfs_first_delayed_insertion_item(delayed_node);
  	while (curr_item) {
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
1810
  		btrfs_delayed_item_release_metadata(root, curr_item);
16cdcec73   Miao Xie   btrfs: implement ...
1811
1812
1813
1814
1815
1816
1817
  		prev_item = curr_item;
  		curr_item = __btrfs_next_delayed_item(prev_item);
  		btrfs_release_delayed_item(prev_item);
  	}
  
  	curr_item = __btrfs_first_delayed_deletion_item(delayed_node);
  	while (curr_item) {
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
1818
  		btrfs_delayed_item_release_metadata(root, curr_item);
16cdcec73   Miao Xie   btrfs: implement ...
1819
1820
1821
1822
  		prev_item = curr_item;
  		curr_item = __btrfs_next_delayed_item(prev_item);
  		btrfs_release_delayed_item(prev_item);
  	}
67de11769   Miao Xie   Btrfs: introduce ...
1823
1824
  	if (test_bit(BTRFS_DELAYED_NODE_DEL_IREF, &delayed_node->flags))
  		btrfs_release_delayed_iref(delayed_node);
7cf35d91b   Miao Xie   Btrfs: use flags ...
1825
  	if (test_bit(BTRFS_DELAYED_NODE_INODE_DIRTY, &delayed_node->flags)) {
4f5427ccc   Qu Wenruo   btrfs: delayed-in...
1826
  		btrfs_delayed_inode_release_metadata(fs_info, delayed_node, false);
16cdcec73   Miao Xie   btrfs: implement ...
1827
1828
1829
1830
  		btrfs_release_delayed_inode(delayed_node);
  	}
  	mutex_unlock(&delayed_node->mutex);
  }
4ccb5c723   Nikolay Borisov   btrfs: Make btrfs...
1831
  void btrfs_kill_delayed_inode_items(struct btrfs_inode *inode)
16cdcec73   Miao Xie   btrfs: implement ...
1832
1833
  {
  	struct btrfs_delayed_node *delayed_node;
4ccb5c723   Nikolay Borisov   btrfs: Make btrfs...
1834
  	delayed_node = btrfs_get_delayed_node(inode);
16cdcec73   Miao Xie   btrfs: implement ...
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
  	if (!delayed_node)
  		return;
  
  	__btrfs_kill_delayed_node(delayed_node);
  	btrfs_release_delayed_node(delayed_node);
  }
  
  void btrfs_kill_all_delayed_nodes(struct btrfs_root *root)
  {
  	u64 inode_id = 0;
  	struct btrfs_delayed_node *delayed_nodes[8];
  	int i, n;
  
  	while (1) {
  		spin_lock(&root->inode_lock);
  		n = radix_tree_gang_lookup(&root->delayed_nodes_tree,
  					   (void **)delayed_nodes, inode_id,
  					   ARRAY_SIZE(delayed_nodes));
  		if (!n) {
  			spin_unlock(&root->inode_lock);
  			break;
  		}
  
  		inode_id = delayed_nodes[n - 1]->inode_id + 1;
baf320b9d   Josef Bacik   btrfs: use refcou...
1859
1860
1861
1862
1863
1864
1865
1866
  		for (i = 0; i < n; i++) {
  			/*
  			 * Don't increase refs in case the node is dead and
  			 * about to be removed from the tree in the loop below
  			 */
  			if (!refcount_inc_not_zero(&delayed_nodes[i]->refs))
  				delayed_nodes[i] = NULL;
  		}
16cdcec73   Miao Xie   btrfs: implement ...
1867
1868
1869
  		spin_unlock(&root->inode_lock);
  
  		for (i = 0; i < n; i++) {
baf320b9d   Josef Bacik   btrfs: use refcou...
1870
1871
  			if (!delayed_nodes[i])
  				continue;
16cdcec73   Miao Xie   btrfs: implement ...
1872
1873
1874
1875
1876
  			__btrfs_kill_delayed_node(delayed_nodes[i]);
  			btrfs_release_delayed_node(delayed_nodes[i]);
  		}
  	}
  }
67cde3448   Miao Xie   Btrfs: destroy th...
1877

ccdf9b305   Jeff Mahoney   btrfs: root->fs_i...
1878
  void btrfs_destroy_delayed_inodes(struct btrfs_fs_info *fs_info)
67cde3448   Miao Xie   Btrfs: destroy th...
1879
  {
67cde3448   Miao Xie   Btrfs: destroy th...
1880
  	struct btrfs_delayed_node *curr_node, *prev_node;
ccdf9b305   Jeff Mahoney   btrfs: root->fs_i...
1881
  	curr_node = btrfs_first_delayed_node(fs_info->delayed_root);
67cde3448   Miao Xie   Btrfs: destroy th...
1882
1883
1884
1885
1886
1887
1888
1889
  	while (curr_node) {
  		__btrfs_kill_delayed_node(curr_node);
  
  		prev_node = curr_node;
  		curr_node = btrfs_next_delayed_node(curr_node);
  		btrfs_release_delayed_node(prev_node);
  	}
  }