Blame view

fs/btrfs/ordered-data.c 31.4 KB
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  /*
   * Copyright (C) 2007 Oracle.  All rights reserved.
   *
   * This program is free software; you can redistribute it and/or
   * modify it under the terms of the GNU General Public
   * License v2 as published by the Free Software Foundation.
   *
   * This program is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * General Public License for more details.
   *
   * You should have received a copy of the GNU General Public
   * License along with this program; if not, write to the
   * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   * Boston, MA 021110-1307, USA.
   */
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
18
  #include <linux/slab.h>
d6bfde876   Chris Mason   Btrfs: Fixes for ...
19
  #include <linux/blkdev.h>
f421950f8   Chris Mason   Btrfs: Fix some d...
20
21
  #include <linux/writeback.h>
  #include <linux/pagevec.h>
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
22
23
24
  #include "ctree.h"
  #include "transaction.h"
  #include "btrfs_inode.h"
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
25
  #include "extent_io.h"
199c2a9c3   Miao Xie   Btrfs: introduce ...
26
  #include "disk-io.h"
ebb8765b2   Anand Jain   btrfs: move btrfs...
27
  #include "compression.h"
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
28

6352b91da   Miao Xie   Btrfs: use a slab...
29
  static struct kmem_cache *btrfs_ordered_extent_cache;
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
30
  static u64 entry_end(struct btrfs_ordered_extent *entry)
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
31
  {
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
32
33
34
  	if (entry->file_offset + entry->len < entry->file_offset)
  		return (u64)-1;
  	return entry->file_offset + entry->len;
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
35
  }
d352ac681   Chris Mason   Btrfs: add and im...
36
37
38
  /* returns NULL if the insertion worked, or it returns the node it did find
   * in the tree
   */
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
39
40
  static struct rb_node *tree_insert(struct rb_root *root, u64 file_offset,
  				   struct rb_node *node)
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
41
  {
d397712bc   Chris Mason   Btrfs: Fix checkp...
42
43
  	struct rb_node **p = &root->rb_node;
  	struct rb_node *parent = NULL;
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
44
  	struct btrfs_ordered_extent *entry;
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
45

d397712bc   Chris Mason   Btrfs: Fix checkp...
46
  	while (*p) {
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
47
  		parent = *p;
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
48
  		entry = rb_entry(parent, struct btrfs_ordered_extent, rb_node);
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
49

e6dcd2dc9   Chris Mason   Btrfs: New data=o...
50
  		if (file_offset < entry->file_offset)
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
51
  			p = &(*p)->rb_left;
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
52
  		else if (file_offset >= entry_end(entry))
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
53
54
55
56
57
58
59
60
61
  			p = &(*p)->rb_right;
  		else
  			return parent;
  	}
  
  	rb_link_node(node, parent, p);
  	rb_insert_color(node, root);
  	return NULL;
  }
43c04fb1b   Jeff Mahoney   btrfs: Panic on b...
62
63
64
65
  static void ordered_data_tree_panic(struct inode *inode, int errno,
  					       u64 offset)
  {
  	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
5d163e0e6   Jeff Mahoney   btrfs: unsplit pr...
66
67
  	btrfs_panic(fs_info, errno,
  		    "Inconsistency in ordered tree at offset %llu", offset);
43c04fb1b   Jeff Mahoney   btrfs: Panic on b...
68
  }
d352ac681   Chris Mason   Btrfs: add and im...
69
70
71
72
  /*
   * look for a given offset in the tree, and if it can't be found return the
   * first lesser offset
   */
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
73
74
  static struct rb_node *__tree_search(struct rb_root *root, u64 file_offset,
  				     struct rb_node **prev_ret)
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
75
  {
d397712bc   Chris Mason   Btrfs: Fix checkp...
76
  	struct rb_node *n = root->rb_node;
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
77
  	struct rb_node *prev = NULL;
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
78
79
80
  	struct rb_node *test;
  	struct btrfs_ordered_extent *entry;
  	struct btrfs_ordered_extent *prev_entry = NULL;
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
81

d397712bc   Chris Mason   Btrfs: Fix checkp...
82
  	while (n) {
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
83
  		entry = rb_entry(n, struct btrfs_ordered_extent, rb_node);
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
84
85
  		prev = n;
  		prev_entry = entry;
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
86

e6dcd2dc9   Chris Mason   Btrfs: New data=o...
87
  		if (file_offset < entry->file_offset)
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
88
  			n = n->rb_left;
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
89
  		else if (file_offset >= entry_end(entry))
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
90
91
92
93
94
95
  			n = n->rb_right;
  		else
  			return n;
  	}
  	if (!prev_ret)
  		return NULL;
d397712bc   Chris Mason   Btrfs: Fix checkp...
96
  	while (prev && file_offset >= entry_end(prev_entry)) {
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
97
98
99
100
101
102
103
104
105
106
107
108
109
  		test = rb_next(prev);
  		if (!test)
  			break;
  		prev_entry = rb_entry(test, struct btrfs_ordered_extent,
  				      rb_node);
  		if (file_offset < entry_end(prev_entry))
  			break;
  
  		prev = test;
  	}
  	if (prev)
  		prev_entry = rb_entry(prev, struct btrfs_ordered_extent,
  				      rb_node);
d397712bc   Chris Mason   Btrfs: Fix checkp...
110
  	while (prev && file_offset < entry_end(prev_entry)) {
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
111
112
113
114
115
116
  		test = rb_prev(prev);
  		if (!test)
  			break;
  		prev_entry = rb_entry(test, struct btrfs_ordered_extent,
  				      rb_node);
  		prev = test;
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
117
118
119
120
  	}
  	*prev_ret = prev;
  	return NULL;
  }
d352ac681   Chris Mason   Btrfs: add and im...
121
122
123
  /*
   * helper to check if a given offset is inside a given entry
   */
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
124
125
126
127
128
129
130
  static int offset_in_entry(struct btrfs_ordered_extent *entry, u64 file_offset)
  {
  	if (file_offset < entry->file_offset ||
  	    entry->file_offset + entry->len <= file_offset)
  		return 0;
  	return 1;
  }
4b46fce23   Josef Bacik   Btrfs: add basic ...
131
132
133
134
135
136
137
138
  static int range_overlaps(struct btrfs_ordered_extent *entry, u64 file_offset,
  			  u64 len)
  {
  	if (file_offset + len <= entry->file_offset ||
  	    entry->file_offset + entry->len <= file_offset)
  		return 0;
  	return 1;
  }
d352ac681   Chris Mason   Btrfs: add and im...
139
140
141
142
  /*
   * look find the first ordered struct that has this offset, otherwise
   * the first one less than this offset
   */
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
143
144
  static inline struct rb_node *tree_search(struct btrfs_ordered_inode_tree *tree,
  					  u64 file_offset)
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
145
  {
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
146
  	struct rb_root *root = &tree->tree;
c87fb6fdc   Chris Mason   Btrfs: avoid unin...
147
  	struct rb_node *prev = NULL;
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
148
  	struct rb_node *ret;
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
149
150
151
152
153
154
155
156
157
  	struct btrfs_ordered_extent *entry;
  
  	if (tree->last) {
  		entry = rb_entry(tree->last, struct btrfs_ordered_extent,
  				 rb_node);
  		if (offset_in_entry(entry, file_offset))
  			return tree->last;
  	}
  	ret = __tree_search(root, file_offset, &prev);
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
158
  	if (!ret)
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
159
160
161
  		ret = prev;
  	if (ret)
  		tree->last = ret;
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
162
163
  	return ret;
  }
eb84ae039   Chris Mason   Btrfs: Cleanup an...
164
165
166
167
168
169
170
171
  /* allocate and add a new ordered_extent into the per-inode tree.
   * file_offset is the logical offset in the file
   *
   * start is the disk block number of an extent already reserved in the
   * extent allocation tree
   *
   * len is the length of the extent
   *
eb84ae039   Chris Mason   Btrfs: Cleanup an...
172
173
174
   * The tree is given a single reference on the ordered extent that was
   * inserted.
   */
4b46fce23   Josef Bacik   Btrfs: add basic ...
175
176
  static int __btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
  				      u64 start, u64 len, u64 disk_len,
261507a02   Li Zefan   btrfs: Allow to a...
177
  				      int type, int dio, int compress_type)
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
178
  {
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
179
  	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
199c2a9c3   Miao Xie   Btrfs: introduce ...
180
  	struct btrfs_root *root = BTRFS_I(inode)->root;
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
181
  	struct btrfs_ordered_inode_tree *tree;
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
182
183
  	struct rb_node *node;
  	struct btrfs_ordered_extent *entry;
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
184

e6dcd2dc9   Chris Mason   Btrfs: New data=o...
185
  	tree = &BTRFS_I(inode)->ordered_tree;
6352b91da   Miao Xie   Btrfs: use a slab...
186
  	entry = kmem_cache_zalloc(btrfs_ordered_extent_cache, GFP_NOFS);
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
187
188
  	if (!entry)
  		return -ENOMEM;
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
189
190
191
  	entry->file_offset = file_offset;
  	entry->start = start;
  	entry->len = len;
c8b978188   Chris Mason   Btrfs: Add zlib c...
192
  	entry->disk_len = disk_len;
8b62b72b2   Chris Mason   Btrfs: Use PagePr...
193
  	entry->bytes_left = len;
5fd020435   Josef Bacik   Btrfs: finish ord...
194
  	entry->inode = igrab(inode);
261507a02   Li Zefan   btrfs: Allow to a...
195
  	entry->compress_type = compress_type;
77cef2ec5   Josef Bacik   Btrfs: allow part...
196
  	entry->truncated_len = (u64)-1;
d899e0521   Yan Zheng   Btrfs: Add falloc...
197
  	if (type != BTRFS_ORDERED_IO_DONE && type != BTRFS_ORDERED_COMPLETE)
80ff38566   Yan Zheng   Btrfs: update nod...
198
  		set_bit(type, &entry->flags);
3eaa28852   Chris Mason   Btrfs: Fix the de...
199

4b46fce23   Josef Bacik   Btrfs: add basic ...
200
201
  	if (dio)
  		set_bit(BTRFS_ORDERED_DIRECT, &entry->flags);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
202
  	/* one ref for the tree */
e76edab7f   Elena Reshetova   btrfs: convert bt...
203
  	refcount_set(&entry->refs, 1);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
204
205
  	init_waitqueue_head(&entry->wait);
  	INIT_LIST_HEAD(&entry->list);
3eaa28852   Chris Mason   Btrfs: Fix the de...
206
  	INIT_LIST_HEAD(&entry->root_extent_list);
9afab8820   Miao Xie   Btrfs: make order...
207
208
  	INIT_LIST_HEAD(&entry->work_list);
  	init_completion(&entry->completion);
2ab28f322   Josef Bacik   Btrfs: wait on or...
209
  	INIT_LIST_HEAD(&entry->log_list);
50d9aa99b   Josef Bacik   Btrfs: make sure ...
210
  	INIT_LIST_HEAD(&entry->trans_list);
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
211

1abe9b8a1   liubo   Btrfs: add initia...
212
  	trace_btrfs_ordered_extent_add(inode, entry);
5fd020435   Josef Bacik   Btrfs: finish ord...
213
  	spin_lock_irq(&tree->lock);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
214
215
  	node = tree_insert(&tree->tree, file_offset,
  			   &entry->rb_node);
43c04fb1b   Jeff Mahoney   btrfs: Panic on b...
216
217
  	if (node)
  		ordered_data_tree_panic(inode, -EEXIST, file_offset);
5fd020435   Josef Bacik   Btrfs: finish ord...
218
  	spin_unlock_irq(&tree->lock);
d397712bc   Chris Mason   Btrfs: Fix checkp...
219

199c2a9c3   Miao Xie   Btrfs: introduce ...
220
  	spin_lock(&root->ordered_extent_lock);
3eaa28852   Chris Mason   Btrfs: Fix the de...
221
  	list_add_tail(&entry->root_extent_list,
199c2a9c3   Miao Xie   Btrfs: introduce ...
222
223
224
  		      &root->ordered_extents);
  	root->nr_ordered_extents++;
  	if (root->nr_ordered_extents == 1) {
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
225
  		spin_lock(&fs_info->ordered_root_lock);
199c2a9c3   Miao Xie   Btrfs: introduce ...
226
  		BUG_ON(!list_empty(&root->ordered_root));
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
227
228
  		list_add_tail(&root->ordered_root, &fs_info->ordered_roots);
  		spin_unlock(&fs_info->ordered_root_lock);
199c2a9c3   Miao Xie   Btrfs: introduce ...
229
230
  	}
  	spin_unlock(&root->ordered_extent_lock);
3eaa28852   Chris Mason   Btrfs: Fix the de...
231

dc17ff8f1   Chris Mason   Btrfs: Add data=o...
232
233
  	return 0;
  }
4b46fce23   Josef Bacik   Btrfs: add basic ...
234
235
236
237
  int btrfs_add_ordered_extent(struct inode *inode, u64 file_offset,
  			     u64 start, u64 len, u64 disk_len, int type)
  {
  	return __btrfs_add_ordered_extent(inode, file_offset, start, len,
261507a02   Li Zefan   btrfs: Allow to a...
238
239
  					  disk_len, type, 0,
  					  BTRFS_COMPRESS_NONE);
4b46fce23   Josef Bacik   Btrfs: add basic ...
240
241
242
243
244
245
  }
  
  int btrfs_add_ordered_extent_dio(struct inode *inode, u64 file_offset,
  				 u64 start, u64 len, u64 disk_len, int type)
  {
  	return __btrfs_add_ordered_extent(inode, file_offset, start, len,
261507a02   Li Zefan   btrfs: Allow to a...
246
247
248
249
250
251
252
253
254
255
256
  					  disk_len, type, 1,
  					  BTRFS_COMPRESS_NONE);
  }
  
  int btrfs_add_ordered_extent_compress(struct inode *inode, u64 file_offset,
  				      u64 start, u64 len, u64 disk_len,
  				      int type, int compress_type)
  {
  	return __btrfs_add_ordered_extent(inode, file_offset, start, len,
  					  disk_len, type, 0,
  					  compress_type);
4b46fce23   Josef Bacik   Btrfs: add basic ...
257
  }
eb84ae039   Chris Mason   Btrfs: Cleanup an...
258
259
  /*
   * Add a struct btrfs_ordered_sum into the list of checksums to be inserted
3edf7d33f   Chris Mason   Btrfs: Handle dat...
260
261
   * when an ordered extent is finished.  If the list covers more than one
   * ordered extent, it is split across multiples.
eb84ae039   Chris Mason   Btrfs: Cleanup an...
262
   */
143bede52   Jeff Mahoney   btrfs: return voi...
263
264
265
  void btrfs_add_ordered_sum(struct inode *inode,
  			   struct btrfs_ordered_extent *entry,
  			   struct btrfs_ordered_sum *sum)
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
266
  {
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
267
  	struct btrfs_ordered_inode_tree *tree;
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
268

e6dcd2dc9   Chris Mason   Btrfs: New data=o...
269
  	tree = &BTRFS_I(inode)->ordered_tree;
5fd020435   Josef Bacik   Btrfs: finish ord...
270
  	spin_lock_irq(&tree->lock);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
271
  	list_add_tail(&sum->list, &entry->list);
5fd020435   Josef Bacik   Btrfs: finish ord...
272
  	spin_unlock_irq(&tree->lock);
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
273
  }
eb84ae039   Chris Mason   Btrfs: Cleanup an...
274
275
  /*
   * this is used to account for finished IO across a given range
163cf09c2   Chris Mason   Btrfs: deal with ...
276
277
278
279
280
281
282
283
284
285
286
287
   * of the file.  The IO may span ordered extents.  If
   * a given ordered_extent is completely done, 1 is returned, otherwise
   * 0.
   *
   * test_and_set_bit on a flag in the struct btrfs_ordered_extent is used
   * to make sure this function only returns 1 once for a given ordered extent.
   *
   * file_offset is updated to one byte past the range that is recorded as
   * complete.  This allows you to walk forward in the file.
   */
  int btrfs_dec_test_first_ordered_pending(struct inode *inode,
  				   struct btrfs_ordered_extent **cached,
5fd020435   Josef Bacik   Btrfs: finish ord...
288
  				   u64 *file_offset, u64 io_size, int uptodate)
163cf09c2   Chris Mason   Btrfs: deal with ...
289
  {
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
290
  	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
163cf09c2   Chris Mason   Btrfs: deal with ...
291
292
293
294
  	struct btrfs_ordered_inode_tree *tree;
  	struct rb_node *node;
  	struct btrfs_ordered_extent *entry = NULL;
  	int ret;
5fd020435   Josef Bacik   Btrfs: finish ord...
295
  	unsigned long flags;
163cf09c2   Chris Mason   Btrfs: deal with ...
296
297
298
299
300
  	u64 dec_end;
  	u64 dec_start;
  	u64 to_dec;
  
  	tree = &BTRFS_I(inode)->ordered_tree;
5fd020435   Josef Bacik   Btrfs: finish ord...
301
  	spin_lock_irqsave(&tree->lock, flags);
163cf09c2   Chris Mason   Btrfs: deal with ...
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
  	node = tree_search(tree, *file_offset);
  	if (!node) {
  		ret = 1;
  		goto out;
  	}
  
  	entry = rb_entry(node, struct btrfs_ordered_extent, rb_node);
  	if (!offset_in_entry(entry, *file_offset)) {
  		ret = 1;
  		goto out;
  	}
  
  	dec_start = max(*file_offset, entry->file_offset);
  	dec_end = min(*file_offset + io_size, entry->file_offset +
  		      entry->len);
  	*file_offset = dec_end;
  	if (dec_start > dec_end) {
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
319
320
  		btrfs_crit(fs_info, "bad ordering dec_start %llu end %llu",
  			   dec_start, dec_end);
163cf09c2   Chris Mason   Btrfs: deal with ...
321
322
323
  	}
  	to_dec = dec_end - dec_start;
  	if (to_dec > entry->bytes_left) {
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
324
325
326
  		btrfs_crit(fs_info,
  			   "bad ordered accounting left %llu size %llu",
  			   entry->bytes_left, to_dec);
163cf09c2   Chris Mason   Btrfs: deal with ...
327
328
  	}
  	entry->bytes_left -= to_dec;
5fd020435   Josef Bacik   Btrfs: finish ord...
329
330
  	if (!uptodate)
  		set_bit(BTRFS_ORDERED_IOERR, &entry->flags);
af7a65097   Miao Xie   Btrfs: wake up th...
331
  	if (entry->bytes_left == 0) {
163cf09c2   Chris Mason   Btrfs: deal with ...
332
  		ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags);
a83342aa0   David Sterba   btrfs: add commen...
333
334
335
  		/*
  		 * Implicit memory barrier after test_and_set_bit
  		 */
af7a65097   Miao Xie   Btrfs: wake up th...
336
337
338
  		if (waitqueue_active(&entry->wait))
  			wake_up(&entry->wait);
  	} else {
163cf09c2   Chris Mason   Btrfs: deal with ...
339
  		ret = 1;
af7a65097   Miao Xie   Btrfs: wake up th...
340
  	}
163cf09c2   Chris Mason   Btrfs: deal with ...
341
342
343
  out:
  	if (!ret && cached && entry) {
  		*cached = entry;
e76edab7f   Elena Reshetova   btrfs: convert bt...
344
  		refcount_inc(&entry->refs);
163cf09c2   Chris Mason   Btrfs: deal with ...
345
  	}
5fd020435   Josef Bacik   Btrfs: finish ord...
346
  	spin_unlock_irqrestore(&tree->lock, flags);
163cf09c2   Chris Mason   Btrfs: deal with ...
347
348
349
350
351
  	return ret == 0;
  }
  
  /*
   * this is used to account for finished IO across a given range
eb84ae039   Chris Mason   Btrfs: Cleanup an...
352
353
354
355
356
357
358
   * of the file.  The IO should not span ordered extents.  If
   * a given ordered_extent is completely done, 1 is returned, otherwise
   * 0.
   *
   * test_and_set_bit on a flag in the struct btrfs_ordered_extent is used
   * to make sure this function only returns 1 once for a given ordered extent.
   */
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
359
  int btrfs_dec_test_ordered_pending(struct inode *inode,
5a1a3df1f   Josef Bacik   Btrfs: cache orde...
360
  				   struct btrfs_ordered_extent **cached,
5fd020435   Josef Bacik   Btrfs: finish ord...
361
  				   u64 file_offset, u64 io_size, int uptodate)
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
362
  {
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
363
  	struct btrfs_ordered_inode_tree *tree;
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
364
  	struct rb_node *node;
5a1a3df1f   Josef Bacik   Btrfs: cache orde...
365
  	struct btrfs_ordered_extent *entry = NULL;
5fd020435   Josef Bacik   Btrfs: finish ord...
366
  	unsigned long flags;
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
367
368
369
  	int ret;
  
  	tree = &BTRFS_I(inode)->ordered_tree;
5fd020435   Josef Bacik   Btrfs: finish ord...
370
371
372
373
374
  	spin_lock_irqsave(&tree->lock, flags);
  	if (cached && *cached) {
  		entry = *cached;
  		goto have_entry;
  	}
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
375
  	node = tree_search(tree, file_offset);
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
376
  	if (!node) {
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
377
378
  		ret = 1;
  		goto out;
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
379
  	}
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
380
  	entry = rb_entry(node, struct btrfs_ordered_extent, rb_node);
5fd020435   Josef Bacik   Btrfs: finish ord...
381
  have_entry:
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
382
383
384
  	if (!offset_in_entry(entry, file_offset)) {
  		ret = 1;
  		goto out;
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
385
  	}
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
386

8b62b72b2   Chris Mason   Btrfs: Use PagePr...
387
  	if (io_size > entry->bytes_left) {
efe120a06   Frank Holton   Btrfs: convert pr...
388
389
  		btrfs_crit(BTRFS_I(inode)->root->fs_info,
  			   "bad ordered accounting left %llu size %llu",
c1c9ff7c9   Geert Uytterhoeven   Btrfs: Remove sup...
390
  		       entry->bytes_left, io_size);
8b62b72b2   Chris Mason   Btrfs: Use PagePr...
391
392
  	}
  	entry->bytes_left -= io_size;
5fd020435   Josef Bacik   Btrfs: finish ord...
393
394
  	if (!uptodate)
  		set_bit(BTRFS_ORDERED_IOERR, &entry->flags);
af7a65097   Miao Xie   Btrfs: wake up th...
395
  	if (entry->bytes_left == 0) {
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
396
  		ret = test_and_set_bit(BTRFS_ORDERED_IO_DONE, &entry->flags);
a83342aa0   David Sterba   btrfs: add commen...
397
398
399
  		/*
  		 * Implicit memory barrier after test_and_set_bit
  		 */
af7a65097   Miao Xie   Btrfs: wake up th...
400
401
402
  		if (waitqueue_active(&entry->wait))
  			wake_up(&entry->wait);
  	} else {
8b62b72b2   Chris Mason   Btrfs: Use PagePr...
403
  		ret = 1;
af7a65097   Miao Xie   Btrfs: wake up th...
404
  	}
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
405
  out:
5a1a3df1f   Josef Bacik   Btrfs: cache orde...
406
407
  	if (!ret && cached && entry) {
  		*cached = entry;
e76edab7f   Elena Reshetova   btrfs: convert bt...
408
  		refcount_inc(&entry->refs);
5a1a3df1f   Josef Bacik   Btrfs: cache orde...
409
  	}
5fd020435   Josef Bacik   Btrfs: finish ord...
410
  	spin_unlock_irqrestore(&tree->lock, flags);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
411
412
  	return ret == 0;
  }
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
413

2ab28f322   Josef Bacik   Btrfs: wait on or...
414
  /* Needs to either be called under a log transaction or the log_mutex */
223466370   Nikolay Borisov   btrfs: Make btrfs...
415
  void btrfs_get_logged_extents(struct btrfs_inode *inode,
0870295b2   Filipe Manana   Btrfs: collect on...
416
417
418
  			      struct list_head *logged_list,
  			      const loff_t start,
  			      const loff_t end)
2ab28f322   Josef Bacik   Btrfs: wait on or...
419
420
421
422
  {
  	struct btrfs_ordered_inode_tree *tree;
  	struct btrfs_ordered_extent *ordered;
  	struct rb_node *n;
0870295b2   Filipe Manana   Btrfs: collect on...
423
  	struct rb_node *prev;
2ab28f322   Josef Bacik   Btrfs: wait on or...
424

223466370   Nikolay Borisov   btrfs: Make btrfs...
425
  	tree = &inode->ordered_tree;
2ab28f322   Josef Bacik   Btrfs: wait on or...
426
  	spin_lock_irq(&tree->lock);
0870295b2   Filipe Manana   Btrfs: collect on...
427
428
429
430
  	n = __tree_search(&tree->tree, end, &prev);
  	if (!n)
  		n = prev;
  	for (; n; n = rb_prev(n)) {
2ab28f322   Josef Bacik   Btrfs: wait on or...
431
  		ordered = rb_entry(n, struct btrfs_ordered_extent, rb_node);
0870295b2   Filipe Manana   Btrfs: collect on...
432
433
434
435
  		if (ordered->file_offset > end)
  			continue;
  		if (entry_end(ordered) <= start)
  			break;
4d884fcea   Filipe Manana   Btrfs: fix fsync ...
436
  		if (test_and_set_bit(BTRFS_ORDERED_LOGGED, &ordered->flags))
50d9aa99b   Josef Bacik   Btrfs: make sure ...
437
  			continue;
0870295b2   Filipe Manana   Btrfs: collect on...
438
  		list_add(&ordered->log_list, logged_list);
e76edab7f   Elena Reshetova   btrfs: convert bt...
439
  		refcount_inc(&ordered->refs);
2ab28f322   Josef Bacik   Btrfs: wait on or...
440
441
442
  	}
  	spin_unlock_irq(&tree->lock);
  }
827463c49   Miao Xie   Btrfs: don't mix ...
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
  void btrfs_put_logged_extents(struct list_head *logged_list)
  {
  	struct btrfs_ordered_extent *ordered;
  
  	while (!list_empty(logged_list)) {
  		ordered = list_first_entry(logged_list,
  					   struct btrfs_ordered_extent,
  					   log_list);
  		list_del_init(&ordered->log_list);
  		btrfs_put_ordered_extent(ordered);
  	}
  }
  
  void btrfs_submit_logged_extents(struct list_head *logged_list,
  				 struct btrfs_root *log)
  {
  	int index = log->log_transid % 2;
  
  	spin_lock_irq(&log->log_extents_lock[index]);
  	list_splice_tail(logged_list, &log->logged_list[index]);
  	spin_unlock_irq(&log->log_extents_lock[index]);
  }
50d9aa99b   Josef Bacik   Btrfs: make sure ...
465
466
  void btrfs_wait_logged_extents(struct btrfs_trans_handle *trans,
  			       struct btrfs_root *log, u64 transid)
2ab28f322   Josef Bacik   Btrfs: wait on or...
467
468
469
470
471
472
  {
  	struct btrfs_ordered_extent *ordered;
  	int index = transid % 2;
  
  	spin_lock_irq(&log->log_extents_lock[index]);
  	while (!list_empty(&log->logged_list[index])) {
161c3549b   Josef Bacik   Btrfs: change how...
473
  		struct inode *inode;
2ab28f322   Josef Bacik   Btrfs: wait on or...
474
475
476
477
  		ordered = list_first_entry(&log->logged_list[index],
  					   struct btrfs_ordered_extent,
  					   log_list);
  		list_del_init(&ordered->log_list);
161c3549b   Josef Bacik   Btrfs: change how...
478
  		inode = ordered->inode;
2ab28f322   Josef Bacik   Btrfs: wait on or...
479
  		spin_unlock_irq(&log->log_extents_lock[index]);
98ce2deda   Liu Bo   Btrfs: fix abnorm...
480
481
482
  
  		if (!test_bit(BTRFS_ORDERED_IO_DONE, &ordered->flags) &&
  		    !test_bit(BTRFS_ORDERED_DIRECT, &ordered->flags)) {
98ce2deda   Liu Bo   Btrfs: fix abnorm...
483
484
485
486
487
488
  			u64 start = ordered->file_offset;
  			u64 end = ordered->file_offset + ordered->len - 1;
  
  			WARN_ON(!inode);
  			filemap_fdatawrite_range(inode->i_mapping, start, end);
  		}
2ab28f322   Josef Bacik   Btrfs: wait on or...
489
490
  		wait_event(ordered->wait, test_bit(BTRFS_ORDERED_IO_DONE,
  						   &ordered->flags));
98ce2deda   Liu Bo   Btrfs: fix abnorm...
491

7558c8bc1   Filipe Manana   Btrfs: don't atta...
492
  		/*
161c3549b   Josef Bacik   Btrfs: change how...
493
494
495
496
497
498
  		 * In order to keep us from losing our ordered extent
  		 * information when committing the transaction we have to make
  		 * sure that any logged extents are completed when we go to
  		 * commit the transaction.  To do this we simply increase the
  		 * current transactions pending_ordered counter and decrement it
  		 * when the ordered extent completes.
7558c8bc1   Filipe Manana   Btrfs: don't atta...
499
  		 */
161c3549b   Josef Bacik   Btrfs: change how...
500
501
502
503
504
505
506
507
508
509
510
511
  		if (!test_bit(BTRFS_ORDERED_COMPLETE, &ordered->flags)) {
  			struct btrfs_ordered_inode_tree *tree;
  
  			tree = &BTRFS_I(inode)->ordered_tree;
  			spin_lock_irq(&tree->lock);
  			if (!test_bit(BTRFS_ORDERED_COMPLETE, &ordered->flags)) {
  				set_bit(BTRFS_ORDERED_PENDING, &ordered->flags);
  				atomic_inc(&trans->transaction->pending_ordered);
  			}
  			spin_unlock_irq(&tree->lock);
  		}
  		btrfs_put_ordered_extent(ordered);
2ab28f322   Josef Bacik   Btrfs: wait on or...
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
  		spin_lock_irq(&log->log_extents_lock[index]);
  	}
  	spin_unlock_irq(&log->log_extents_lock[index]);
  }
  
  void btrfs_free_logged_extents(struct btrfs_root *log, u64 transid)
  {
  	struct btrfs_ordered_extent *ordered;
  	int index = transid % 2;
  
  	spin_lock_irq(&log->log_extents_lock[index]);
  	while (!list_empty(&log->logged_list[index])) {
  		ordered = list_first_entry(&log->logged_list[index],
  					   struct btrfs_ordered_extent,
  					   log_list);
  		list_del_init(&ordered->log_list);
  		spin_unlock_irq(&log->log_extents_lock[index]);
  		btrfs_put_ordered_extent(ordered);
  		spin_lock_irq(&log->log_extents_lock[index]);
  	}
  	spin_unlock_irq(&log->log_extents_lock[index]);
  }
eb84ae039   Chris Mason   Btrfs: Cleanup an...
534
535
536
537
  /*
   * used to drop a reference on an ordered extent.  This will free
   * the extent if the last reference is dropped
   */
143bede52   Jeff Mahoney   btrfs: return voi...
538
  void btrfs_put_ordered_extent(struct btrfs_ordered_extent *entry)
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
539
  {
ba1da2f44   Chris Mason   Btrfs: Don't pin ...
540
541
  	struct list_head *cur;
  	struct btrfs_ordered_sum *sum;
1abe9b8a1   liubo   Btrfs: add initia...
542
  	trace_btrfs_ordered_extent_put(entry->inode, entry);
e76edab7f   Elena Reshetova   btrfs: convert bt...
543
  	if (refcount_dec_and_test(&entry->refs)) {
61de718fc   Filipe Manana   Btrfs: fix memory...
544
545
546
547
  		ASSERT(list_empty(&entry->log_list));
  		ASSERT(list_empty(&entry->trans_list));
  		ASSERT(list_empty(&entry->root_extent_list));
  		ASSERT(RB_EMPTY_NODE(&entry->rb_node));
5fd020435   Josef Bacik   Btrfs: finish ord...
548
549
  		if (entry->inode)
  			btrfs_add_delayed_iput(entry->inode);
d397712bc   Chris Mason   Btrfs: Fix checkp...
550
  		while (!list_empty(&entry->list)) {
ba1da2f44   Chris Mason   Btrfs: Don't pin ...
551
552
553
554
555
  			cur = entry->list.next;
  			sum = list_entry(cur, struct btrfs_ordered_sum, list);
  			list_del(&sum->list);
  			kfree(sum);
  		}
6352b91da   Miao Xie   Btrfs: use a slab...
556
  		kmem_cache_free(btrfs_ordered_extent_cache, entry);
ba1da2f44   Chris Mason   Btrfs: Don't pin ...
557
  	}
dc17ff8f1   Chris Mason   Btrfs: Add data=o...
558
  }
cee36a03e   Chris Mason   Rework btrfs_drop...
559

eb84ae039   Chris Mason   Btrfs: Cleanup an...
560
561
  /*
   * remove an ordered extent from the tree.  No references are dropped
5fd020435   Josef Bacik   Btrfs: finish ord...
562
   * and waiters are woken up.
eb84ae039   Chris Mason   Btrfs: Cleanup an...
563
   */
5fd020435   Josef Bacik   Btrfs: finish ord...
564
565
  void btrfs_remove_ordered_extent(struct inode *inode,
  				 struct btrfs_ordered_extent *entry)
cee36a03e   Chris Mason   Rework btrfs_drop...
566
  {
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
567
  	struct btrfs_fs_info *fs_info = btrfs_sb(inode->i_sb);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
568
  	struct btrfs_ordered_inode_tree *tree;
287a0ab91   Josef Bacik   Btrfs: kill max_e...
569
  	struct btrfs_root *root = BTRFS_I(inode)->root;
cee36a03e   Chris Mason   Rework btrfs_drop...
570
  	struct rb_node *node;
161c3549b   Josef Bacik   Btrfs: change how...
571
  	bool dec_pending_ordered = false;
cee36a03e   Chris Mason   Rework btrfs_drop...
572

e6dcd2dc9   Chris Mason   Btrfs: New data=o...
573
  	tree = &BTRFS_I(inode)->ordered_tree;
5fd020435   Josef Bacik   Btrfs: finish ord...
574
  	spin_lock_irq(&tree->lock);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
575
  	node = &entry->rb_node;
cee36a03e   Chris Mason   Rework btrfs_drop...
576
  	rb_erase(node, &tree->tree);
61de718fc   Filipe Manana   Btrfs: fix memory...
577
  	RB_CLEAR_NODE(node);
1b8e7e45e   Filipe David Borba Manana   Btrfs: avoid unne...
578
579
  	if (tree->last == node)
  		tree->last = NULL;
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
580
  	set_bit(BTRFS_ORDERED_COMPLETE, &entry->flags);
161c3549b   Josef Bacik   Btrfs: change how...
581
582
  	if (test_and_clear_bit(BTRFS_ORDERED_PENDING, &entry->flags))
  		dec_pending_ordered = true;
5fd020435   Josef Bacik   Btrfs: finish ord...
583
  	spin_unlock_irq(&tree->lock);
3eaa28852   Chris Mason   Btrfs: Fix the de...
584

161c3549b   Josef Bacik   Btrfs: change how...
585
586
587
588
589
590
591
592
593
594
595
596
597
  	/*
  	 * The current running transaction is waiting on us, we need to let it
  	 * know that we're complete and wake it up.
  	 */
  	if (dec_pending_ordered) {
  		struct btrfs_transaction *trans;
  
  		/*
  		 * The checks for trans are just a formality, it should be set,
  		 * but if it isn't we don't want to deref/assert under the spin
  		 * lock, so be nice and check if trans is set, but ASSERT() so
  		 * if it isn't set a developer will notice.
  		 */
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
598
599
  		spin_lock(&fs_info->trans_lock);
  		trans = fs_info->running_transaction;
161c3549b   Josef Bacik   Btrfs: change how...
600
  		if (trans)
9b64f57dd   Elena Reshetova   btrfs: convert bt...
601
  			refcount_inc(&trans->use_count);
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
602
  		spin_unlock(&fs_info->trans_lock);
161c3549b   Josef Bacik   Btrfs: change how...
603
604
605
606
607
608
609
610
  
  		ASSERT(trans);
  		if (trans) {
  			if (atomic_dec_and_test(&trans->pending_ordered))
  				wake_up(&trans->pending_wait);
  			btrfs_put_transaction(trans);
  		}
  	}
199c2a9c3   Miao Xie   Btrfs: introduce ...
611
  	spin_lock(&root->ordered_extent_lock);
3eaa28852   Chris Mason   Btrfs: Fix the de...
612
  	list_del_init(&entry->root_extent_list);
199c2a9c3   Miao Xie   Btrfs: introduce ...
613
  	root->nr_ordered_extents--;
5a3f23d51   Chris Mason   Btrfs: add extra ...
614

1abe9b8a1   liubo   Btrfs: add initia...
615
  	trace_btrfs_ordered_extent_remove(inode, entry);
199c2a9c3   Miao Xie   Btrfs: introduce ...
616
  	if (!root->nr_ordered_extents) {
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
617
  		spin_lock(&fs_info->ordered_root_lock);
199c2a9c3   Miao Xie   Btrfs: introduce ...
618
619
  		BUG_ON(list_empty(&root->ordered_root));
  		list_del_init(&root->ordered_root);
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
620
  		spin_unlock(&fs_info->ordered_root_lock);
199c2a9c3   Miao Xie   Btrfs: introduce ...
621
622
  	}
  	spin_unlock(&root->ordered_extent_lock);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
623
  	wake_up(&entry->wait);
cee36a03e   Chris Mason   Rework btrfs_drop...
624
  }
d458b0540   Qu Wenruo   btrfs: Cleanup th...
625
  static void btrfs_run_ordered_extent_work(struct btrfs_work *work)
9afab8820   Miao Xie   Btrfs: make order...
626
627
628
629
630
631
632
  {
  	struct btrfs_ordered_extent *ordered;
  
  	ordered = container_of(work, struct btrfs_ordered_extent, flush_work);
  	btrfs_start_ordered_extent(ordered->inode, ordered, 1);
  	complete(&ordered->completion);
  }
d352ac681   Chris Mason   Btrfs: add and im...
633
634
635
636
  /*
   * wait for all the ordered extents in a root.  This is done when balancing
   * space between drives.
   */
6374e57ad   Chris Mason   btrfs: fix intege...
637
  u64 btrfs_wait_ordered_extents(struct btrfs_root *root, u64 nr,
578def7c5   Filipe Manana   Btrfs: don't wait...
638
  			       const u64 range_start, const u64 range_len)
3eaa28852   Chris Mason   Btrfs: Fix the de...
639
  {
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
640
  	struct btrfs_fs_info *fs_info = root->fs_info;
578def7c5   Filipe Manana   Btrfs: don't wait...
641
642
643
  	LIST_HEAD(splice);
  	LIST_HEAD(skipped);
  	LIST_HEAD(works);
9afab8820   Miao Xie   Btrfs: make order...
644
  	struct btrfs_ordered_extent *ordered, *next;
6374e57ad   Chris Mason   btrfs: fix intege...
645
  	u64 count = 0;
578def7c5   Filipe Manana   Btrfs: don't wait...
646
  	const u64 range_end = range_start + range_len;
3eaa28852   Chris Mason   Btrfs: Fix the de...
647

31f3d255c   Miao Xie   Btrfs: split the ...
648
  	mutex_lock(&root->ordered_extent_mutex);
199c2a9c3   Miao Xie   Btrfs: introduce ...
649
650
  	spin_lock(&root->ordered_extent_lock);
  	list_splice_init(&root->ordered_extents, &splice);
b02441999   Miao Xie   Btrfs: don't wait...
651
  	while (!list_empty(&splice) && nr) {
199c2a9c3   Miao Xie   Btrfs: introduce ...
652
653
  		ordered = list_first_entry(&splice, struct btrfs_ordered_extent,
  					   root_extent_list);
578def7c5   Filipe Manana   Btrfs: don't wait...
654
655
656
657
658
659
660
  
  		if (range_end <= ordered->start ||
  		    ordered->start + ordered->disk_len <= range_start) {
  			list_move_tail(&ordered->root_extent_list, &skipped);
  			cond_resched_lock(&root->ordered_extent_lock);
  			continue;
  		}
199c2a9c3   Miao Xie   Btrfs: introduce ...
661
662
  		list_move_tail(&ordered->root_extent_list,
  			       &root->ordered_extents);
e76edab7f   Elena Reshetova   btrfs: convert bt...
663
  		refcount_inc(&ordered->refs);
199c2a9c3   Miao Xie   Btrfs: introduce ...
664
  		spin_unlock(&root->ordered_extent_lock);
3eaa28852   Chris Mason   Btrfs: Fix the de...
665

a44903abe   Qu Wenruo   btrfs: Replace fs...
666
  		btrfs_init_work(&ordered->flush_work,
9e0af2376   Liu Bo   Btrfs: fix task h...
667
  				btrfs_flush_delalloc_helper,
a44903abe   Qu Wenruo   btrfs: Replace fs...
668
  				btrfs_run_ordered_extent_work, NULL, NULL);
199c2a9c3   Miao Xie   Btrfs: introduce ...
669
  		list_add_tail(&ordered->work_list, &works);
0b246afa6   Jeff Mahoney   btrfs: root->fs_i...
670
  		btrfs_queue_work(fs_info->flush_workers, &ordered->flush_work);
3eaa28852   Chris Mason   Btrfs: Fix the de...
671

9afab8820   Miao Xie   Btrfs: make order...
672
  		cond_resched();
199c2a9c3   Miao Xie   Btrfs: introduce ...
673
  		spin_lock(&root->ordered_extent_lock);
6374e57ad   Chris Mason   btrfs: fix intege...
674
  		if (nr != U64_MAX)
b02441999   Miao Xie   Btrfs: don't wait...
675
676
  			nr--;
  		count++;
3eaa28852   Chris Mason   Btrfs: Fix the de...
677
  	}
578def7c5   Filipe Manana   Btrfs: don't wait...
678
  	list_splice_tail(&skipped, &root->ordered_extents);
b02441999   Miao Xie   Btrfs: don't wait...
679
  	list_splice_tail(&splice, &root->ordered_extents);
199c2a9c3   Miao Xie   Btrfs: introduce ...
680
  	spin_unlock(&root->ordered_extent_lock);
9afab8820   Miao Xie   Btrfs: make order...
681
682
683
684
  
  	list_for_each_entry_safe(ordered, next, &works, work_list) {
  		list_del_init(&ordered->work_list);
  		wait_for_completion(&ordered->completion);
9afab8820   Miao Xie   Btrfs: make order...
685
  		btrfs_put_ordered_extent(ordered);
9afab8820   Miao Xie   Btrfs: make order...
686
687
  		cond_resched();
  	}
31f3d255c   Miao Xie   Btrfs: split the ...
688
  	mutex_unlock(&root->ordered_extent_mutex);
b02441999   Miao Xie   Btrfs: don't wait...
689
690
  
  	return count;
3eaa28852   Chris Mason   Btrfs: Fix the de...
691
  }
6374e57ad   Chris Mason   btrfs: fix intege...
692
693
  u64 btrfs_wait_ordered_roots(struct btrfs_fs_info *fs_info, u64 nr,
  			     const u64 range_start, const u64 range_len)
199c2a9c3   Miao Xie   Btrfs: introduce ...
694
695
696
  {
  	struct btrfs_root *root;
  	struct list_head splice;
6374e57ad   Chris Mason   btrfs: fix intege...
697
698
  	u64 total_done = 0;
  	u64 done;
199c2a9c3   Miao Xie   Btrfs: introduce ...
699
700
  
  	INIT_LIST_HEAD(&splice);
8b9d83cd6   Miao Xie   Btrfs: fix early ...
701
  	mutex_lock(&fs_info->ordered_operations_mutex);
199c2a9c3   Miao Xie   Btrfs: introduce ...
702
703
  	spin_lock(&fs_info->ordered_root_lock);
  	list_splice_init(&fs_info->ordered_roots, &splice);
b02441999   Miao Xie   Btrfs: don't wait...
704
  	while (!list_empty(&splice) && nr) {
199c2a9c3   Miao Xie   Btrfs: introduce ...
705
706
707
708
709
710
711
  		root = list_first_entry(&splice, struct btrfs_root,
  					ordered_root);
  		root = btrfs_grab_fs_root(root);
  		BUG_ON(!root);
  		list_move_tail(&root->ordered_root,
  			       &fs_info->ordered_roots);
  		spin_unlock(&fs_info->ordered_root_lock);
578def7c5   Filipe Manana   Btrfs: don't wait...
712
713
  		done = btrfs_wait_ordered_extents(root, nr,
  						  range_start, range_len);
199c2a9c3   Miao Xie   Btrfs: introduce ...
714
  		btrfs_put_fs_root(root);
f0e9b7d64   Filipe Manana   Btrfs: fix race s...
715
  		total_done += done;
199c2a9c3   Miao Xie   Btrfs: introduce ...
716
717
  
  		spin_lock(&fs_info->ordered_root_lock);
6374e57ad   Chris Mason   btrfs: fix intege...
718
  		if (nr != U64_MAX) {
b02441999   Miao Xie   Btrfs: don't wait...
719
  			nr -= done;
b02441999   Miao Xie   Btrfs: don't wait...
720
  		}
199c2a9c3   Miao Xie   Btrfs: introduce ...
721
  	}
931aa8779   Miao Xie   Btrfs: fix list d...
722
  	list_splice_tail(&splice, &fs_info->ordered_roots);
199c2a9c3   Miao Xie   Btrfs: introduce ...
723
  	spin_unlock(&fs_info->ordered_root_lock);
8b9d83cd6   Miao Xie   Btrfs: fix early ...
724
  	mutex_unlock(&fs_info->ordered_operations_mutex);
f0e9b7d64   Filipe Manana   Btrfs: fix race s...
725
726
  
  	return total_done;
199c2a9c3   Miao Xie   Btrfs: introduce ...
727
  }
eb84ae039   Chris Mason   Btrfs: Cleanup an...
728
729
730
731
732
733
734
735
736
737
  /*
   * Used to start IO or wait for a given ordered extent to finish.
   *
   * If wait is one, this effectively waits on page writeback for all the pages
   * in the extent, and it waits on the io completion code to insert
   * metadata into the btree corresponding to the extent
   */
  void btrfs_start_ordered_extent(struct inode *inode,
  				       struct btrfs_ordered_extent *entry,
  				       int wait)
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
738
739
740
  {
  	u64 start = entry->file_offset;
  	u64 end = start + entry->len - 1;
e1b81e676   Mingming   btrfs delete orde...
741

1abe9b8a1   liubo   Btrfs: add initia...
742
  	trace_btrfs_ordered_extent_start(inode, entry);
eb84ae039   Chris Mason   Btrfs: Cleanup an...
743
744
745
  	/*
  	 * pages in the range can be dirty, clean or writeback.  We
  	 * start IO on any dirty ones so the wait doesn't stall waiting
b25703140   Artem Bityutskiy   btrfs: nuke pdflu...
746
  	 * for the flusher thread to find them
eb84ae039   Chris Mason   Btrfs: Cleanup an...
747
  	 */
4b46fce23   Josef Bacik   Btrfs: add basic ...
748
749
  	if (!test_bit(BTRFS_ORDERED_DIRECT, &entry->flags))
  		filemap_fdatawrite_range(inode->i_mapping, start, end);
c8b978188   Chris Mason   Btrfs: Add zlib c...
750
  	if (wait) {
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
751
752
  		wait_event(entry->wait, test_bit(BTRFS_ORDERED_COMPLETE,
  						 &entry->flags));
c8b978188   Chris Mason   Btrfs: Add zlib c...
753
  	}
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
754
  }
cee36a03e   Chris Mason   Rework btrfs_drop...
755

eb84ae039   Chris Mason   Btrfs: Cleanup an...
756
757
758
  /*
   * Used to wait on ordered extents across a large range of bytes.
   */
0ef8b7260   Josef Bacik   Btrfs: return an ...
759
  int btrfs_wait_ordered_range(struct inode *inode, u64 start, u64 len)
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
760
  {
0ef8b7260   Josef Bacik   Btrfs: return an ...
761
  	int ret = 0;
28aeeac1d   Filipe Manana   Btrfs: fix panic ...
762
  	int ret_wb = 0;
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
763
  	u64 end;
e5a2217ef   Chris Mason   Fix btrfs_wait_or...
764
  	u64 orig_end;
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
765
  	struct btrfs_ordered_extent *ordered;
e5a2217ef   Chris Mason   Fix btrfs_wait_or...
766
767
  
  	if (start + len < start) {
f421950f8   Chris Mason   Btrfs: Fix some d...
768
  		orig_end = INT_LIMIT(loff_t);
e5a2217ef   Chris Mason   Fix btrfs_wait_or...
769
770
  	} else {
  		orig_end = start + len - 1;
f421950f8   Chris Mason   Btrfs: Fix some d...
771
772
  		if (orig_end > INT_LIMIT(loff_t))
  			orig_end = INT_LIMIT(loff_t);
e5a2217ef   Chris Mason   Fix btrfs_wait_or...
773
  	}
551ebb2d3   Josef Bacik   Btrfs: remove use...
774

e5a2217ef   Chris Mason   Fix btrfs_wait_or...
775
776
777
  	/* start IO across the range first to instantiate any delalloc
  	 * extents
  	 */
728404dac   Filipe Manana   Btrfs: add helper...
778
  	ret = btrfs_fdatawrite_range(inode, start, orig_end);
0ef8b7260   Josef Bacik   Btrfs: return an ...
779
780
  	if (ret)
  		return ret;
728404dac   Filipe Manana   Btrfs: add helper...
781

28aeeac1d   Filipe Manana   Btrfs: fix panic ...
782
783
784
785
786
787
788
789
  	/*
  	 * If we have a writeback error don't return immediately. Wait first
  	 * for any ordered extents that haven't completed yet. This is to make
  	 * sure no one can dirty the same page ranges and call writepages()
  	 * before the ordered extents complete - to avoid failures (-EEXIST)
  	 * when adding the new ordered extents to the ordered tree.
  	 */
  	ret_wb = filemap_fdatawait_range(inode->i_mapping, start, orig_end);
e5a2217ef   Chris Mason   Fix btrfs_wait_or...
790

f421950f8   Chris Mason   Btrfs: Fix some d...
791
  	end = orig_end;
d397712bc   Chris Mason   Btrfs: Fix checkp...
792
  	while (1) {
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
793
  		ordered = btrfs_lookup_first_ordered_extent(inode, end);
d397712bc   Chris Mason   Btrfs: Fix checkp...
794
  		if (!ordered)
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
795
  			break;
e5a2217ef   Chris Mason   Fix btrfs_wait_or...
796
  		if (ordered->file_offset > orig_end) {
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
797
798
799
  			btrfs_put_ordered_extent(ordered);
  			break;
  		}
b52abf1e3   Filipe David Borba Manana   Btrfs: don't wait...
800
  		if (ordered->file_offset + ordered->len <= start) {
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
801
802
803
  			btrfs_put_ordered_extent(ordered);
  			break;
  		}
e5a2217ef   Chris Mason   Fix btrfs_wait_or...
804
  		btrfs_start_ordered_extent(inode, ordered, 1);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
805
  		end = ordered->file_offset;
0ef8b7260   Josef Bacik   Btrfs: return an ...
806
807
  		if (test_bit(BTRFS_ORDERED_IOERR, &ordered->flags))
  			ret = -EIO;
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
808
  		btrfs_put_ordered_extent(ordered);
0ef8b7260   Josef Bacik   Btrfs: return an ...
809
  		if (ret || end == 0 || end == start)
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
810
811
812
  			break;
  		end--;
  	}
28aeeac1d   Filipe Manana   Btrfs: fix panic ...
813
  	return ret_wb ? ret_wb : ret;
cee36a03e   Chris Mason   Rework btrfs_drop...
814
  }
eb84ae039   Chris Mason   Btrfs: Cleanup an...
815
816
817
818
  /*
   * find an ordered extent corresponding to file_offset.  return NULL if
   * nothing is found, otherwise take a reference on the extent and return it
   */
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
819
820
821
822
823
824
825
826
  struct btrfs_ordered_extent *btrfs_lookup_ordered_extent(struct inode *inode,
  							 u64 file_offset)
  {
  	struct btrfs_ordered_inode_tree *tree;
  	struct rb_node *node;
  	struct btrfs_ordered_extent *entry = NULL;
  
  	tree = &BTRFS_I(inode)->ordered_tree;
5fd020435   Josef Bacik   Btrfs: finish ord...
827
  	spin_lock_irq(&tree->lock);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
828
829
830
831
832
833
834
835
  	node = tree_search(tree, file_offset);
  	if (!node)
  		goto out;
  
  	entry = rb_entry(node, struct btrfs_ordered_extent, rb_node);
  	if (!offset_in_entry(entry, file_offset))
  		entry = NULL;
  	if (entry)
e76edab7f   Elena Reshetova   btrfs: convert bt...
836
  		refcount_inc(&entry->refs);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
837
  out:
5fd020435   Josef Bacik   Btrfs: finish ord...
838
  	spin_unlock_irq(&tree->lock);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
839
840
  	return entry;
  }
4b46fce23   Josef Bacik   Btrfs: add basic ...
841
842
843
  /* Since the DIO code tries to lock a wide area we need to look for any ordered
   * extents that exist in the range, rather than just the start of the range.
   */
a776c6fa1   Nikolay Borisov   btrfs: Make btrfs...
844
845
  struct btrfs_ordered_extent *btrfs_lookup_ordered_range(
  		struct btrfs_inode *inode, u64 file_offset, u64 len)
4b46fce23   Josef Bacik   Btrfs: add basic ...
846
847
848
849
  {
  	struct btrfs_ordered_inode_tree *tree;
  	struct rb_node *node;
  	struct btrfs_ordered_extent *entry = NULL;
a776c6fa1   Nikolay Borisov   btrfs: Make btrfs...
850
  	tree = &inode->ordered_tree;
5fd020435   Josef Bacik   Btrfs: finish ord...
851
  	spin_lock_irq(&tree->lock);
4b46fce23   Josef Bacik   Btrfs: add basic ...
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
  	node = tree_search(tree, file_offset);
  	if (!node) {
  		node = tree_search(tree, file_offset + len);
  		if (!node)
  			goto out;
  	}
  
  	while (1) {
  		entry = rb_entry(node, struct btrfs_ordered_extent, rb_node);
  		if (range_overlaps(entry, file_offset, len))
  			break;
  
  		if (entry->file_offset >= file_offset + len) {
  			entry = NULL;
  			break;
  		}
  		entry = NULL;
  		node = rb_next(node);
  		if (!node)
  			break;
  	}
  out:
  	if (entry)
e76edab7f   Elena Reshetova   btrfs: convert bt...
875
  		refcount_inc(&entry->refs);
5fd020435   Josef Bacik   Btrfs: finish ord...
876
  	spin_unlock_irq(&tree->lock);
4b46fce23   Josef Bacik   Btrfs: add basic ...
877
878
  	return entry;
  }
b659ef027   Filipe Manana   Btrfs: avoid sync...
879
880
881
882
883
  bool btrfs_have_ordered_extents_in_range(struct inode *inode,
  					 u64 file_offset,
  					 u64 len)
  {
  	struct btrfs_ordered_extent *oe;
a776c6fa1   Nikolay Borisov   btrfs: Make btrfs...
884
  	oe = btrfs_lookup_ordered_range(BTRFS_I(inode), file_offset, len);
b659ef027   Filipe Manana   Btrfs: avoid sync...
885
886
887
888
889
890
  	if (oe) {
  		btrfs_put_ordered_extent(oe);
  		return true;
  	}
  	return false;
  }
eb84ae039   Chris Mason   Btrfs: Cleanup an...
891
892
893
894
  /*
   * lookup and return any extent before 'file_offset'.  NULL is returned
   * if none is found
   */
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
895
  struct btrfs_ordered_extent *
d397712bc   Chris Mason   Btrfs: Fix checkp...
896
  btrfs_lookup_first_ordered_extent(struct inode *inode, u64 file_offset)
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
897
898
899
900
901
902
  {
  	struct btrfs_ordered_inode_tree *tree;
  	struct rb_node *node;
  	struct btrfs_ordered_extent *entry = NULL;
  
  	tree = &BTRFS_I(inode)->ordered_tree;
5fd020435   Josef Bacik   Btrfs: finish ord...
903
  	spin_lock_irq(&tree->lock);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
904
905
906
907
908
  	node = tree_search(tree, file_offset);
  	if (!node)
  		goto out;
  
  	entry = rb_entry(node, struct btrfs_ordered_extent, rb_node);
e76edab7f   Elena Reshetova   btrfs: convert bt...
909
  	refcount_inc(&entry->refs);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
910
  out:
5fd020435   Josef Bacik   Btrfs: finish ord...
911
  	spin_unlock_irq(&tree->lock);
e6dcd2dc9   Chris Mason   Btrfs: New data=o...
912
  	return entry;
81d7ed29f   Chris Mason   Btrfs: Throttle f...
913
  }
dbe674a99   Chris Mason   Btrfs: Update on ...
914

eb84ae039   Chris Mason   Btrfs: Cleanup an...
915
916
917
918
  /*
   * After an extent is done, call this to conditionally update the on disk
   * i_size.  i_size is updated to cover any fully written part of the file.
   */
c21677545   Yan, Zheng   Btrfs: Fix disk_i...
919
  int btrfs_ordered_update_i_size(struct inode *inode, u64 offset,
dbe674a99   Chris Mason   Btrfs: Update on ...
920
921
922
  				struct btrfs_ordered_extent *ordered)
  {
  	struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree;
dbe674a99   Chris Mason   Btrfs: Update on ...
923
924
  	u64 disk_i_size;
  	u64 new_i_size;
c21677545   Yan, Zheng   Btrfs: Fix disk_i...
925
  	u64 i_size = i_size_read(inode);
dbe674a99   Chris Mason   Btrfs: Update on ...
926
  	struct rb_node *node;
c21677545   Yan, Zheng   Btrfs: Fix disk_i...
927
  	struct rb_node *prev = NULL;
dbe674a99   Chris Mason   Btrfs: Update on ...
928
  	struct btrfs_ordered_extent *test;
c21677545   Yan, Zheng   Btrfs: Fix disk_i...
929
  	int ret = 1;
c0d2f6104   Wang Xiaoguang   btrfs: fix disk_i...
930
  	u64 orig_offset = offset;
c21677545   Yan, Zheng   Btrfs: Fix disk_i...
931

77cef2ec5   Josef Bacik   Btrfs: allow part...
932
933
  	spin_lock_irq(&tree->lock);
  	if (ordered) {
c21677545   Yan, Zheng   Btrfs: Fix disk_i...
934
  		offset = entry_end(ordered);
77cef2ec5   Josef Bacik   Btrfs: allow part...
935
936
937
938
939
  		if (test_bit(BTRFS_ORDERED_TRUNCATED, &ordered->flags))
  			offset = min(offset,
  				     ordered->file_offset +
  				     ordered->truncated_len);
  	} else {
da17066c4   Jeff Mahoney   btrfs: pull node/...
940
  		offset = ALIGN(offset, btrfs_inode_sectorsize(inode));
77cef2ec5   Josef Bacik   Btrfs: allow part...
941
  	}
dbe674a99   Chris Mason   Btrfs: Update on ...
942
  	disk_i_size = BTRFS_I(inode)->disk_i_size;
19fd2df5b   Liu Bo   Btrfs: fix btrfs_...
943
944
945
946
947
948
949
950
951
952
953
954
  	/*
  	 * truncate file.
  	 * If ordered is not NULL, then this is called from endio and
  	 * disk_i_size will be updated by either truncate itself or any
  	 * in-flight IOs which are inside the disk_i_size.
  	 *
  	 * Because btrfs_setsize() may set i_size with disk_i_size if truncate
  	 * fails somehow, we need to make sure we have a precise disk_i_size by
  	 * updating it as usual.
  	 *
  	 */
  	if (!ordered && disk_i_size > i_size) {
c0d2f6104   Wang Xiaoguang   btrfs: fix disk_i...
955
  		BTRFS_I(inode)->disk_i_size = orig_offset;
c21677545   Yan, Zheng   Btrfs: Fix disk_i...
956
957
958
  		ret = 0;
  		goto out;
  	}
dbe674a99   Chris Mason   Btrfs: Update on ...
959
960
961
962
  	/*
  	 * if the disk i_size is already at the inode->i_size, or
  	 * this ordered extent is inside the disk i_size, we're done
  	 */
5d1f40202   Josef Bacik   Btrfs: fix missin...
963
964
965
966
967
968
969
970
971
  	if (disk_i_size == i_size)
  		goto out;
  
  	/*
  	 * We still need to update disk_i_size if outstanding_isize is greater
  	 * than disk_i_size.
  	 */
  	if (offset <= disk_i_size &&
  	    (!ordered || ordered->outstanding_isize <= disk_i_size))
dbe674a99   Chris Mason   Btrfs: Update on ...
972
  		goto out;
dbe674a99   Chris Mason   Btrfs: Update on ...
973
974
  
  	/*
dbe674a99   Chris Mason   Btrfs: Update on ...
975
976
977
978
  	 * walk backward from this ordered extent to disk_i_size.
  	 * if we find an ordered extent then we can't update disk i_size
  	 * yet
  	 */
c21677545   Yan, Zheng   Btrfs: Fix disk_i...
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
  	if (ordered) {
  		node = rb_prev(&ordered->rb_node);
  	} else {
  		prev = tree_search(tree, offset);
  		/*
  		 * we insert file extents without involving ordered struct,
  		 * so there should be no ordered struct cover this offset
  		 */
  		if (prev) {
  			test = rb_entry(prev, struct btrfs_ordered_extent,
  					rb_node);
  			BUG_ON(offset_in_entry(test, offset));
  		}
  		node = prev;
  	}
5fd020435   Josef Bacik   Btrfs: finish ord...
994
  	for (; node; node = rb_prev(node)) {
dbe674a99   Chris Mason   Btrfs: Update on ...
995
  		test = rb_entry(node, struct btrfs_ordered_extent, rb_node);
5fd020435   Josef Bacik   Btrfs: finish ord...
996

bb7ab3b92   Adam Buchbinder   btrfs: Fix misspe...
997
  		/* We treat this entry as if it doesn't exist */
5fd020435   Josef Bacik   Btrfs: finish ord...
998
999
  		if (test_bit(BTRFS_ORDERED_UPDATED_ISIZE, &test->flags))
  			continue;
62c821a8e   Liu Bo   Btrfs: clean up b...
1000
1001
  
  		if (entry_end(test) <= disk_i_size)
dbe674a99   Chris Mason   Btrfs: Update on ...
1002
  			break;
c21677545   Yan, Zheng   Btrfs: Fix disk_i...
1003
  		if (test->file_offset >= i_size)
dbe674a99   Chris Mason   Btrfs: Update on ...
1004
  			break;
62c821a8e   Liu Bo   Btrfs: clean up b...
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
  
  		/*
  		 * We don't update disk_i_size now, so record this undealt
  		 * i_size. Or we will not know the real i_size.
  		 */
  		if (test->outstanding_isize < offset)
  			test->outstanding_isize = offset;
  		if (ordered &&
  		    ordered->outstanding_isize > test->outstanding_isize)
  			test->outstanding_isize = ordered->outstanding_isize;
  		goto out;
dbe674a99   Chris Mason   Btrfs: Update on ...
1016
  	}
b9a8cc5be   Miao Xie   Btrfs: fix file e...
1017
  	new_i_size = min_t(u64, offset, i_size);
dbe674a99   Chris Mason   Btrfs: Update on ...
1018
1019
  
  	/*
b9a8cc5be   Miao Xie   Btrfs: fix file e...
1020
1021
  	 * Some ordered extents may completed before the current one, and
  	 * we hold the real i_size in ->outstanding_isize.
dbe674a99   Chris Mason   Btrfs: Update on ...
1022
  	 */
b9a8cc5be   Miao Xie   Btrfs: fix file e...
1023
1024
  	if (ordered && ordered->outstanding_isize > new_i_size)
  		new_i_size = min_t(u64, ordered->outstanding_isize, i_size);
dbe674a99   Chris Mason   Btrfs: Update on ...
1025
  	BTRFS_I(inode)->disk_i_size = new_i_size;
c21677545   Yan, Zheng   Btrfs: Fix disk_i...
1026
  	ret = 0;
dbe674a99   Chris Mason   Btrfs: Update on ...
1027
  out:
c21677545   Yan, Zheng   Btrfs: Fix disk_i...
1028
  	/*
5fd020435   Josef Bacik   Btrfs: finish ord...
1029
1030
1031
1032
1033
  	 * We need to do this because we can't remove ordered extents until
  	 * after the i_disk_size has been updated and then the inode has been
  	 * updated to reflect the change, so we need to tell anybody who finds
  	 * this ordered extent that we've already done all the real work, we
  	 * just haven't completed all the other work.
c21677545   Yan, Zheng   Btrfs: Fix disk_i...
1034
1035
  	 */
  	if (ordered)
5fd020435   Josef Bacik   Btrfs: finish ord...
1036
1037
  		set_bit(BTRFS_ORDERED_UPDATED_ISIZE, &ordered->flags);
  	spin_unlock_irq(&tree->lock);
c21677545   Yan, Zheng   Btrfs: Fix disk_i...
1038
  	return ret;
dbe674a99   Chris Mason   Btrfs: Update on ...
1039
  }
ba1da2f44   Chris Mason   Btrfs: Don't pin ...
1040

eb84ae039   Chris Mason   Btrfs: Cleanup an...
1041
1042
1043
1044
1045
  /*
   * search the ordered extents for one corresponding to 'offset' and
   * try to find a checksum.  This is used because we allow pages to
   * be reclaimed before their checksum is actually put into the btree
   */
d20f7043f   Chris Mason   Btrfs: move data ...
1046
  int btrfs_find_ordered_sum(struct inode *inode, u64 offset, u64 disk_bytenr,
e4100d987   Miao Xie   Btrfs: improve th...
1047
  			   u32 *sum, int len)
ba1da2f44   Chris Mason   Btrfs: Don't pin ...
1048
1049
  {
  	struct btrfs_ordered_sum *ordered_sum;
ba1da2f44   Chris Mason   Btrfs: Don't pin ...
1050
1051
  	struct btrfs_ordered_extent *ordered;
  	struct btrfs_ordered_inode_tree *tree = &BTRFS_I(inode)->ordered_tree;
3edf7d33f   Chris Mason   Btrfs: Handle dat...
1052
1053
  	unsigned long num_sectors;
  	unsigned long i;
da17066c4   Jeff Mahoney   btrfs: pull node/...
1054
  	u32 sectorsize = btrfs_inode_sectorsize(inode);
e4100d987   Miao Xie   Btrfs: improve th...
1055
  	int index = 0;
ba1da2f44   Chris Mason   Btrfs: Don't pin ...
1056
1057
1058
  
  	ordered = btrfs_lookup_ordered_extent(inode, offset);
  	if (!ordered)
e4100d987   Miao Xie   Btrfs: improve th...
1059
  		return 0;
ba1da2f44   Chris Mason   Btrfs: Don't pin ...
1060

5fd020435   Josef Bacik   Btrfs: finish ord...
1061
  	spin_lock_irq(&tree->lock);
c6e308713   Qinghuang Feng   Btrfs: simplify i...
1062
  	list_for_each_entry_reverse(ordered_sum, &ordered->list, list) {
e4100d987   Miao Xie   Btrfs: improve th...
1063
1064
1065
1066
  		if (disk_bytenr >= ordered_sum->bytenr &&
  		    disk_bytenr < ordered_sum->bytenr + ordered_sum->len) {
  			i = (disk_bytenr - ordered_sum->bytenr) >>
  			    inode->i_sb->s_blocksize_bits;
e4100d987   Miao Xie   Btrfs: improve th...
1067
1068
  			num_sectors = ordered_sum->len >>
  				      inode->i_sb->s_blocksize_bits;
f51a4a182   Miao Xie   Btrfs: remove btr...
1069
1070
1071
1072
1073
1074
1075
1076
  			num_sectors = min_t(int, len - index, num_sectors - i);
  			memcpy(sum + index, ordered_sum->sums + i,
  			       num_sectors);
  
  			index += (int)num_sectors;
  			if (index == len)
  				goto out;
  			disk_bytenr += num_sectors * sectorsize;
ba1da2f44   Chris Mason   Btrfs: Don't pin ...
1077
1078
1079
  		}
  	}
  out:
5fd020435   Josef Bacik   Btrfs: finish ord...
1080
  	spin_unlock_irq(&tree->lock);
89642229a   Chris Mason   Btrfs: Search dat...
1081
  	btrfs_put_ordered_extent(ordered);
e4100d987   Miao Xie   Btrfs: improve th...
1082
  	return index;
ba1da2f44   Chris Mason   Btrfs: Don't pin ...
1083
  }
6352b91da   Miao Xie   Btrfs: use a slab...
1084
1085
1086
1087
  int __init ordered_data_init(void)
  {
  	btrfs_ordered_extent_cache = kmem_cache_create("btrfs_ordered_extent",
  				     sizeof(struct btrfs_ordered_extent), 0,
fba4b6977   Nikolay Borisov   btrfs: Fix slab a...
1088
  				     SLAB_MEM_SPREAD,
6352b91da   Miao Xie   Btrfs: use a slab...
1089
1090
1091
  				     NULL);
  	if (!btrfs_ordered_extent_cache)
  		return -ENOMEM;
25287e0a1   Miao Xie   Btrfs: make order...
1092

6352b91da   Miao Xie   Btrfs: use a slab...
1093
1094
1095
1096
1097
  	return 0;
  }
  
  void ordered_data_exit(void)
  {
5598e9005   Kinglong Mee   btrfs: drop null ...
1098
  	kmem_cache_destroy(btrfs_ordered_extent_cache);
6352b91da   Miao Xie   Btrfs: use a slab...
1099
  }