diff options
author | Chris Mason <chris.mason@oracle.com> | 2012-01-16 15:26:31 -0500 |
---|---|---|
committer | Chris Mason <chris.mason@oracle.com> | 2012-01-16 15:26:31 -0500 |
commit | 9785dbdf265ddc47d5c88267d89a97648c0dc14b (patch) | |
tree | 3a97a48d6f282f9e06c5446beeb886fcd86c4798 /fs | |
parent | d756bd2d9339447c29bde950910586df8f8941ec (diff) | |
parent | 6bf7e080d5bcb0d399ee38ce3dabbfad64448192 (diff) |
Merge branch 'for-chris' of git://git.jan-o-sch.net/btrfs-unstable into integration
Diffstat (limited to 'fs')
-rw-r--r-- | fs/btrfs/Makefile | 2 | ||||
-rw-r--r-- | fs/btrfs/backref.c | 1131 | ||||
-rw-r--r-- | fs/btrfs/backref.h | 5 | ||||
-rw-r--r-- | fs/btrfs/ctree.c | 42 | ||||
-rw-r--r-- | fs/btrfs/ctree.h | 24 | ||||
-rw-r--r-- | fs/btrfs/delayed-ref.c | 153 | ||||
-rw-r--r-- | fs/btrfs/delayed-ref.h | 104 | ||||
-rw-r--r-- | fs/btrfs/disk-io.c | 3 | ||||
-rw-r--r-- | fs/btrfs/extent-tree.c | 187 | ||||
-rw-r--r-- | fs/btrfs/extent_io.c | 1 | ||||
-rw-r--r-- | fs/btrfs/extent_io.h | 2 | ||||
-rw-r--r-- | fs/btrfs/file.c | 10 | ||||
-rw-r--r-- | fs/btrfs/inode.c | 4 | ||||
-rw-r--r-- | fs/btrfs/ioctl.c | 13 | ||||
-rw-r--r-- | fs/btrfs/locking.c | 53 | ||||
-rw-r--r-- | fs/btrfs/relocation.c | 18 | ||||
-rw-r--r-- | fs/btrfs/scrub.c | 7 | ||||
-rw-r--r-- | fs/btrfs/transaction.c | 9 | ||||
-rw-r--r-- | fs/btrfs/tree-log.c | 2 | ||||
-rw-r--r-- | fs/btrfs/ulist.c | 220 | ||||
-rw-r--r-- | fs/btrfs/ulist.h | 68 |
21 files changed, 1639 insertions, 419 deletions
diff --git a/fs/btrfs/Makefile b/fs/btrfs/Makefile index c0ddfd29c5e5..70798407b9a2 100644 --- a/fs/btrfs/Makefile +++ b/fs/btrfs/Makefile | |||
@@ -8,6 +8,6 @@ btrfs-y += super.o ctree.o extent-tree.o print-tree.o root-tree.o dir-item.o \ | |||
8 | extent_io.o volumes.o async-thread.o ioctl.o locking.o orphan.o \ | 8 | extent_io.o volumes.o async-thread.o ioctl.o locking.o orphan.o \ |
9 | export.o tree-log.o free-space-cache.o zlib.o lzo.o \ | 9 | export.o tree-log.o free-space-cache.o zlib.o lzo.o \ |
10 | compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o \ | 10 | compression.o delayed-ref.o relocation.o delayed-inode.o scrub.o \ |
11 | reada.o backref.o | 11 | reada.o backref.o ulist.o |
12 | 12 | ||
13 | btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o | 13 | btrfs-$(CONFIG_BTRFS_FS_POSIX_ACL) += acl.o |
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c index 22c64fff1bd5..b9a843226de8 100644 --- a/fs/btrfs/backref.c +++ b/fs/btrfs/backref.c | |||
@@ -19,18 +19,789 @@ | |||
19 | #include "ctree.h" | 19 | #include "ctree.h" |
20 | #include "disk-io.h" | 20 | #include "disk-io.h" |
21 | #include "backref.h" | 21 | #include "backref.h" |
22 | #include "ulist.h" | ||
23 | #include "transaction.h" | ||
24 | #include "delayed-ref.h" | ||
22 | 25 | ||
23 | struct __data_ref { | 26 | /* |
27 | * this structure records all encountered refs on the way up to the root | ||
28 | */ | ||
29 | struct __prelim_ref { | ||
24 | struct list_head list; | 30 | struct list_head list; |
25 | u64 inum; | 31 | u64 root_id; |
26 | u64 root; | 32 | struct btrfs_key key; |
27 | u64 extent_data_item_offset; | 33 | int level; |
34 | int count; | ||
35 | u64 parent; | ||
36 | u64 wanted_disk_byte; | ||
28 | }; | 37 | }; |
29 | 38 | ||
30 | struct __shared_ref { | 39 | static int __add_prelim_ref(struct list_head *head, u64 root_id, |
31 | struct list_head list; | 40 | struct btrfs_key *key, int level, u64 parent, |
41 | u64 wanted_disk_byte, int count) | ||
42 | { | ||
43 | struct __prelim_ref *ref; | ||
44 | |||
45 | /* in case we're adding delayed refs, we're holding the refs spinlock */ | ||
46 | ref = kmalloc(sizeof(*ref), GFP_ATOMIC); | ||
47 | if (!ref) | ||
48 | return -ENOMEM; | ||
49 | |||
50 | ref->root_id = root_id; | ||
51 | if (key) | ||
52 | ref->key = *key; | ||
53 | else | ||
54 | memset(&ref->key, 0, sizeof(ref->key)); | ||
55 | |||
56 | ref->level = level; | ||
57 | ref->count = count; | ||
58 | ref->parent = parent; | ||
59 | ref->wanted_disk_byte = wanted_disk_byte; | ||
60 | list_add_tail(&ref->list, head); | ||
61 | |||
62 | return 0; | ||
63 | } | ||
64 | |||
65 | static int add_all_parents(struct btrfs_root *root, struct btrfs_path *path, | ||
66 | struct ulist *parents, | ||
67 | struct extent_buffer *eb, int level, | ||
68 | u64 wanted_objectid, u64 wanted_disk_byte) | ||
69 | { | ||
70 | int ret; | ||
71 | int slot; | ||
72 | struct btrfs_file_extent_item *fi; | ||
73 | struct btrfs_key key; | ||
32 | u64 disk_byte; | 74 | u64 disk_byte; |
33 | }; | 75 | |
76 | add_parent: | ||
77 | ret = ulist_add(parents, eb->start, 0, GFP_NOFS); | ||
78 | if (ret < 0) | ||
79 | return ret; | ||
80 | |||
81 | if (level != 0) | ||
82 | return 0; | ||
83 | |||
84 | /* | ||
85 | * if the current leaf is full with EXTENT_DATA items, we must | ||
86 | * check the next one if that holds a reference as well. | ||
87 | * ref->count cannot be used to skip this check. | ||
88 | * repeat this until we don't find any additional EXTENT_DATA items. | ||
89 | */ | ||
90 | while (1) { | ||
91 | ret = btrfs_next_leaf(root, path); | ||
92 | if (ret < 0) | ||
93 | return ret; | ||
94 | if (ret) | ||
95 | return 0; | ||
96 | |||
97 | eb = path->nodes[0]; | ||
98 | for (slot = 0; slot < btrfs_header_nritems(eb); ++slot) { | ||
99 | btrfs_item_key_to_cpu(eb, &key, slot); | ||
100 | if (key.objectid != wanted_objectid || | ||
101 | key.type != BTRFS_EXTENT_DATA_KEY) | ||
102 | return 0; | ||
103 | fi = btrfs_item_ptr(eb, slot, | ||
104 | struct btrfs_file_extent_item); | ||
105 | disk_byte = btrfs_file_extent_disk_bytenr(eb, fi); | ||
106 | if (disk_byte == wanted_disk_byte) | ||
107 | goto add_parent; | ||
108 | } | ||
109 | } | ||
110 | |||
111 | return 0; | ||
112 | } | ||
113 | |||
114 | /* | ||
115 | * resolve an indirect backref in the form (root_id, key, level) | ||
116 | * to a logical address | ||
117 | */ | ||
118 | static int __resolve_indirect_ref(struct btrfs_fs_info *fs_info, | ||
119 | struct __prelim_ref *ref, | ||
120 | struct ulist *parents) | ||
121 | { | ||
122 | struct btrfs_path *path; | ||
123 | struct btrfs_root *root; | ||
124 | struct btrfs_key root_key; | ||
125 | struct btrfs_key key = {0}; | ||
126 | struct extent_buffer *eb; | ||
127 | int ret = 0; | ||
128 | int root_level; | ||
129 | int level = ref->level; | ||
130 | |||
131 | path = btrfs_alloc_path(); | ||
132 | if (!path) | ||
133 | return -ENOMEM; | ||
134 | |||
135 | root_key.objectid = ref->root_id; | ||
136 | root_key.type = BTRFS_ROOT_ITEM_KEY; | ||
137 | root_key.offset = (u64)-1; | ||
138 | root = btrfs_read_fs_root_no_name(fs_info, &root_key); | ||
139 | if (IS_ERR(root)) { | ||
140 | ret = PTR_ERR(root); | ||
141 | goto out; | ||
142 | } | ||
143 | |||
144 | rcu_read_lock(); | ||
145 | root_level = btrfs_header_level(root->node); | ||
146 | rcu_read_unlock(); | ||
147 | |||
148 | if (root_level + 1 == level) | ||
149 | goto out; | ||
150 | |||
151 | path->lowest_level = level; | ||
152 | ret = btrfs_search_slot(NULL, root, &ref->key, path, 0, 0); | ||
153 | pr_debug("search slot in root %llu (level %d, ref count %d) returned " | ||
154 | "%d for key (%llu %u %llu)\n", | ||
155 | (unsigned long long)ref->root_id, level, ref->count, ret, | ||
156 | (unsigned long long)ref->key.objectid, ref->key.type, | ||
157 | (unsigned long long)ref->key.offset); | ||
158 | if (ret < 0) | ||
159 | goto out; | ||
160 | |||
161 | eb = path->nodes[level]; | ||
162 | if (!eb) { | ||
163 | WARN_ON(1); | ||
164 | ret = 1; | ||
165 | goto out; | ||
166 | } | ||
167 | |||
168 | if (level == 0) { | ||
169 | if (ret == 1 && path->slots[0] >= btrfs_header_nritems(eb)) { | ||
170 | ret = btrfs_next_leaf(root, path); | ||
171 | if (ret) | ||
172 | goto out; | ||
173 | eb = path->nodes[0]; | ||
174 | } | ||
175 | |||
176 | btrfs_item_key_to_cpu(eb, &key, path->slots[0]); | ||
177 | } | ||
178 | |||
179 | /* the last two parameters will only be used for level == 0 */ | ||
180 | ret = add_all_parents(root, path, parents, eb, level, key.objectid, | ||
181 | ref->wanted_disk_byte); | ||
182 | out: | ||
183 | btrfs_free_path(path); | ||
184 | return ret; | ||
185 | } | ||
186 | |||
187 | /* | ||
188 | * resolve all indirect backrefs from the list | ||
189 | */ | ||
190 | static int __resolve_indirect_refs(struct btrfs_fs_info *fs_info, | ||
191 | struct list_head *head) | ||
192 | { | ||
193 | int err; | ||
194 | int ret = 0; | ||
195 | struct __prelim_ref *ref; | ||
196 | struct __prelim_ref *ref_safe; | ||
197 | struct __prelim_ref *new_ref; | ||
198 | struct ulist *parents; | ||
199 | struct ulist_node *node; | ||
200 | |||
201 | parents = ulist_alloc(GFP_NOFS); | ||
202 | if (!parents) | ||
203 | return -ENOMEM; | ||
204 | |||
205 | /* | ||
206 | * _safe allows us to insert directly after the current item without | ||
207 | * iterating over the newly inserted items. | ||
208 | * we're also allowed to re-assign ref during iteration. | ||
209 | */ | ||
210 | list_for_each_entry_safe(ref, ref_safe, head, list) { | ||
211 | if (ref->parent) /* already direct */ | ||
212 | continue; | ||
213 | if (ref->count == 0) | ||
214 | continue; | ||
215 | err = __resolve_indirect_ref(fs_info, ref, parents); | ||
216 | if (err) { | ||
217 | if (ret == 0) | ||
218 | ret = err; | ||
219 | continue; | ||
220 | } | ||
221 | |||
222 | /* we put the first parent into the ref at hand */ | ||
223 | node = ulist_next(parents, NULL); | ||
224 | ref->parent = node ? node->val : 0; | ||
225 | |||
226 | /* additional parents require new refs being added here */ | ||
227 | while ((node = ulist_next(parents, node))) { | ||
228 | new_ref = kmalloc(sizeof(*new_ref), GFP_NOFS); | ||
229 | if (!new_ref) { | ||
230 | ret = -ENOMEM; | ||
231 | break; | ||
232 | } | ||
233 | memcpy(new_ref, ref, sizeof(*ref)); | ||
234 | new_ref->parent = node->val; | ||
235 | list_add(&new_ref->list, &ref->list); | ||
236 | } | ||
237 | ulist_reinit(parents); | ||
238 | } | ||
239 | |||
240 | ulist_free(parents); | ||
241 | return ret; | ||
242 | } | ||
243 | |||
244 | /* | ||
245 | * merge two lists of backrefs and adjust counts accordingly | ||
246 | * | ||
247 | * mode = 1: merge identical keys, if key is set | ||
248 | * mode = 2: merge identical parents | ||
249 | */ | ||
250 | static int __merge_refs(struct list_head *head, int mode) | ||
251 | { | ||
252 | struct list_head *pos1; | ||
253 | |||
254 | list_for_each(pos1, head) { | ||
255 | struct list_head *n2; | ||
256 | struct list_head *pos2; | ||
257 | struct __prelim_ref *ref1; | ||
258 | |||
259 | ref1 = list_entry(pos1, struct __prelim_ref, list); | ||
260 | |||
261 | if (mode == 1 && ref1->key.type == 0) | ||
262 | continue; | ||
263 | for (pos2 = pos1->next, n2 = pos2->next; pos2 != head; | ||
264 | pos2 = n2, n2 = pos2->next) { | ||
265 | struct __prelim_ref *ref2; | ||
266 | |||
267 | ref2 = list_entry(pos2, struct __prelim_ref, list); | ||
268 | |||
269 | if (mode == 1) { | ||
270 | if (memcmp(&ref1->key, &ref2->key, | ||
271 | sizeof(ref1->key)) || | ||
272 | ref1->level != ref2->level || | ||
273 | ref1->root_id != ref2->root_id) | ||
274 | continue; | ||
275 | ref1->count += ref2->count; | ||
276 | } else { | ||
277 | if (ref1->parent != ref2->parent) | ||
278 | continue; | ||
279 | ref1->count += ref2->count; | ||
280 | } | ||
281 | list_del(&ref2->list); | ||
282 | kfree(ref2); | ||
283 | } | ||
284 | |||
285 | } | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | /* | ||
290 | * add all currently queued delayed refs from this head whose seq nr is | ||
291 | * smaller or equal that seq to the list | ||
292 | */ | ||
293 | static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq, | ||
294 | struct btrfs_key *info_key, | ||
295 | struct list_head *prefs) | ||
296 | { | ||
297 | struct btrfs_delayed_extent_op *extent_op = head->extent_op; | ||
298 | struct rb_node *n = &head->node.rb_node; | ||
299 | int sgn; | ||
300 | int ret; | ||
301 | |||
302 | if (extent_op && extent_op->update_key) | ||
303 | btrfs_disk_key_to_cpu(info_key, &extent_op->key); | ||
304 | |||
305 | while ((n = rb_prev(n))) { | ||
306 | struct btrfs_delayed_ref_node *node; | ||
307 | node = rb_entry(n, struct btrfs_delayed_ref_node, | ||
308 | rb_node); | ||
309 | if (node->bytenr != head->node.bytenr) | ||
310 | break; | ||
311 | WARN_ON(node->is_head); | ||
312 | |||
313 | if (node->seq > seq) | ||
314 | continue; | ||
315 | |||
316 | switch (node->action) { | ||
317 | case BTRFS_ADD_DELAYED_EXTENT: | ||
318 | case BTRFS_UPDATE_DELAYED_HEAD: | ||
319 | WARN_ON(1); | ||
320 | continue; | ||
321 | case BTRFS_ADD_DELAYED_REF: | ||
322 | sgn = 1; | ||
323 | break; | ||
324 | case BTRFS_DROP_DELAYED_REF: | ||
325 | sgn = -1; | ||
326 | break; | ||
327 | default: | ||
328 | BUG_ON(1); | ||
329 | } | ||
330 | switch (node->type) { | ||
331 | case BTRFS_TREE_BLOCK_REF_KEY: { | ||
332 | struct btrfs_delayed_tree_ref *ref; | ||
333 | |||
334 | ref = btrfs_delayed_node_to_tree_ref(node); | ||
335 | ret = __add_prelim_ref(prefs, ref->root, info_key, | ||
336 | ref->level + 1, 0, node->bytenr, | ||
337 | node->ref_mod * sgn); | ||
338 | break; | ||
339 | } | ||
340 | case BTRFS_SHARED_BLOCK_REF_KEY: { | ||
341 | struct btrfs_delayed_tree_ref *ref; | ||
342 | |||
343 | ref = btrfs_delayed_node_to_tree_ref(node); | ||
344 | ret = __add_prelim_ref(prefs, ref->root, info_key, | ||
345 | ref->level + 1, ref->parent, | ||
346 | node->bytenr, | ||
347 | node->ref_mod * sgn); | ||
348 | break; | ||
349 | } | ||
350 | case BTRFS_EXTENT_DATA_REF_KEY: { | ||
351 | struct btrfs_delayed_data_ref *ref; | ||
352 | struct btrfs_key key; | ||
353 | |||
354 | ref = btrfs_delayed_node_to_data_ref(node); | ||
355 | |||
356 | key.objectid = ref->objectid; | ||
357 | key.type = BTRFS_EXTENT_DATA_KEY; | ||
358 | key.offset = ref->offset; | ||
359 | ret = __add_prelim_ref(prefs, ref->root, &key, 0, 0, | ||
360 | node->bytenr, | ||
361 | node->ref_mod * sgn); | ||
362 | break; | ||
363 | } | ||
364 | case BTRFS_SHARED_DATA_REF_KEY: { | ||
365 | struct btrfs_delayed_data_ref *ref; | ||
366 | struct btrfs_key key; | ||
367 | |||
368 | ref = btrfs_delayed_node_to_data_ref(node); | ||
369 | |||
370 | key.objectid = ref->objectid; | ||
371 | key.type = BTRFS_EXTENT_DATA_KEY; | ||
372 | key.offset = ref->offset; | ||
373 | ret = __add_prelim_ref(prefs, ref->root, &key, 0, | ||
374 | ref->parent, node->bytenr, | ||
375 | node->ref_mod * sgn); | ||
376 | break; | ||
377 | } | ||
378 | default: | ||
379 | WARN_ON(1); | ||
380 | } | ||
381 | BUG_ON(ret); | ||
382 | } | ||
383 | |||
384 | return 0; | ||
385 | } | ||
386 | |||
387 | /* | ||
388 | * add all inline backrefs for bytenr to the list | ||
389 | */ | ||
390 | static int __add_inline_refs(struct btrfs_fs_info *fs_info, | ||
391 | struct btrfs_path *path, u64 bytenr, | ||
392 | struct btrfs_key *info_key, int *info_level, | ||
393 | struct list_head *prefs) | ||
394 | { | ||
395 | int ret; | ||
396 | int slot; | ||
397 | struct extent_buffer *leaf; | ||
398 | struct btrfs_key key; | ||
399 | unsigned long ptr; | ||
400 | unsigned long end; | ||
401 | struct btrfs_extent_item *ei; | ||
402 | u64 flags; | ||
403 | u64 item_size; | ||
404 | |||
405 | /* | ||
406 | * enumerate all inline refs | ||
407 | */ | ||
408 | leaf = path->nodes[0]; | ||
409 | slot = path->slots[0] - 1; | ||
410 | |||
411 | item_size = btrfs_item_size_nr(leaf, slot); | ||
412 | BUG_ON(item_size < sizeof(*ei)); | ||
413 | |||
414 | ei = btrfs_item_ptr(leaf, slot, struct btrfs_extent_item); | ||
415 | flags = btrfs_extent_flags(leaf, ei); | ||
416 | |||
417 | ptr = (unsigned long)(ei + 1); | ||
418 | end = (unsigned long)ei + item_size; | ||
419 | |||
420 | if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) { | ||
421 | struct btrfs_tree_block_info *info; | ||
422 | struct btrfs_disk_key disk_key; | ||
423 | |||
424 | info = (struct btrfs_tree_block_info *)ptr; | ||
425 | *info_level = btrfs_tree_block_level(leaf, info); | ||
426 | btrfs_tree_block_key(leaf, info, &disk_key); | ||
427 | btrfs_disk_key_to_cpu(info_key, &disk_key); | ||
428 | ptr += sizeof(struct btrfs_tree_block_info); | ||
429 | BUG_ON(ptr > end); | ||
430 | } else { | ||
431 | BUG_ON(!(flags & BTRFS_EXTENT_FLAG_DATA)); | ||
432 | } | ||
433 | |||
434 | while (ptr < end) { | ||
435 | struct btrfs_extent_inline_ref *iref; | ||
436 | u64 offset; | ||
437 | int type; | ||
438 | |||
439 | iref = (struct btrfs_extent_inline_ref *)ptr; | ||
440 | type = btrfs_extent_inline_ref_type(leaf, iref); | ||
441 | offset = btrfs_extent_inline_ref_offset(leaf, iref); | ||
442 | |||
443 | switch (type) { | ||
444 | case BTRFS_SHARED_BLOCK_REF_KEY: | ||
445 | ret = __add_prelim_ref(prefs, 0, info_key, | ||
446 | *info_level + 1, offset, | ||
447 | bytenr, 1); | ||
448 | break; | ||
449 | case BTRFS_SHARED_DATA_REF_KEY: { | ||
450 | struct btrfs_shared_data_ref *sdref; | ||
451 | int count; | ||
452 | |||
453 | sdref = (struct btrfs_shared_data_ref *)(iref + 1); | ||
454 | count = btrfs_shared_data_ref_count(leaf, sdref); | ||
455 | ret = __add_prelim_ref(prefs, 0, NULL, 0, offset, | ||
456 | bytenr, count); | ||
457 | break; | ||
458 | } | ||
459 | case BTRFS_TREE_BLOCK_REF_KEY: | ||
460 | ret = __add_prelim_ref(prefs, offset, info_key, | ||
461 | *info_level + 1, 0, bytenr, 1); | ||
462 | break; | ||
463 | case BTRFS_EXTENT_DATA_REF_KEY: { | ||
464 | struct btrfs_extent_data_ref *dref; | ||
465 | int count; | ||
466 | u64 root; | ||
467 | |||
468 | dref = (struct btrfs_extent_data_ref *)(&iref->offset); | ||
469 | count = btrfs_extent_data_ref_count(leaf, dref); | ||
470 | key.objectid = btrfs_extent_data_ref_objectid(leaf, | ||
471 | dref); | ||
472 | key.type = BTRFS_EXTENT_DATA_KEY; | ||
473 | key.offset = btrfs_extent_data_ref_offset(leaf, dref); | ||
474 | root = btrfs_extent_data_ref_root(leaf, dref); | ||
475 | ret = __add_prelim_ref(prefs, root, &key, 0, 0, bytenr, | ||
476 | count); | ||
477 | break; | ||
478 | } | ||
479 | default: | ||
480 | WARN_ON(1); | ||
481 | } | ||
482 | BUG_ON(ret); | ||
483 | ptr += btrfs_extent_inline_ref_size(type); | ||
484 | } | ||
485 | |||
486 | return 0; | ||
487 | } | ||
488 | |||
489 | /* | ||
490 | * add all non-inline backrefs for bytenr to the list | ||
491 | */ | ||
492 | static int __add_keyed_refs(struct btrfs_fs_info *fs_info, | ||
493 | struct btrfs_path *path, u64 bytenr, | ||
494 | struct btrfs_key *info_key, int info_level, | ||
495 | struct list_head *prefs) | ||
496 | { | ||
497 | struct btrfs_root *extent_root = fs_info->extent_root; | ||
498 | int ret; | ||
499 | int slot; | ||
500 | struct extent_buffer *leaf; | ||
501 | struct btrfs_key key; | ||
502 | |||
503 | while (1) { | ||
504 | ret = btrfs_next_item(extent_root, path); | ||
505 | if (ret < 0) | ||
506 | break; | ||
507 | if (ret) { | ||
508 | ret = 0; | ||
509 | break; | ||
510 | } | ||
511 | |||
512 | slot = path->slots[0]; | ||
513 | leaf = path->nodes[0]; | ||
514 | btrfs_item_key_to_cpu(leaf, &key, slot); | ||
515 | |||
516 | if (key.objectid != bytenr) | ||
517 | break; | ||
518 | if (key.type < BTRFS_TREE_BLOCK_REF_KEY) | ||
519 | continue; | ||
520 | if (key.type > BTRFS_SHARED_DATA_REF_KEY) | ||
521 | break; | ||
522 | |||
523 | switch (key.type) { | ||
524 | case BTRFS_SHARED_BLOCK_REF_KEY: | ||
525 | ret = __add_prelim_ref(prefs, 0, info_key, | ||
526 | info_level + 1, key.offset, | ||
527 | bytenr, 1); | ||
528 | break; | ||
529 | case BTRFS_SHARED_DATA_REF_KEY: { | ||
530 | struct btrfs_shared_data_ref *sdref; | ||
531 | int count; | ||
532 | |||
533 | sdref = btrfs_item_ptr(leaf, slot, | ||
534 | struct btrfs_shared_data_ref); | ||
535 | count = btrfs_shared_data_ref_count(leaf, sdref); | ||
536 | ret = __add_prelim_ref(prefs, 0, NULL, 0, key.offset, | ||
537 | bytenr, count); | ||
538 | break; | ||
539 | } | ||
540 | case BTRFS_TREE_BLOCK_REF_KEY: | ||
541 | ret = __add_prelim_ref(prefs, key.offset, info_key, | ||
542 | info_level + 1, 0, bytenr, 1); | ||
543 | break; | ||
544 | case BTRFS_EXTENT_DATA_REF_KEY: { | ||
545 | struct btrfs_extent_data_ref *dref; | ||
546 | int count; | ||
547 | u64 root; | ||
548 | |||
549 | dref = btrfs_item_ptr(leaf, slot, | ||
550 | struct btrfs_extent_data_ref); | ||
551 | count = btrfs_extent_data_ref_count(leaf, dref); | ||
552 | key.objectid = btrfs_extent_data_ref_objectid(leaf, | ||
553 | dref); | ||
554 | key.type = BTRFS_EXTENT_DATA_KEY; | ||
555 | key.offset = btrfs_extent_data_ref_offset(leaf, dref); | ||
556 | root = btrfs_extent_data_ref_root(leaf, dref); | ||
557 | ret = __add_prelim_ref(prefs, root, &key, 0, 0, | ||
558 | bytenr, count); | ||
559 | break; | ||
560 | } | ||
561 | default: | ||
562 | WARN_ON(1); | ||
563 | } | ||
564 | BUG_ON(ret); | ||
565 | } | ||
566 | |||
567 | return ret; | ||
568 | } | ||
569 | |||
570 | /* | ||
571 | * this adds all existing backrefs (inline backrefs, backrefs and delayed | ||
572 | * refs) for the given bytenr to the refs list, merges duplicates and resolves | ||
573 | * indirect refs to their parent bytenr. | ||
574 | * When roots are found, they're added to the roots list | ||
575 | * | ||
576 | * FIXME some caching might speed things up | ||
577 | */ | ||
578 | static int find_parent_nodes(struct btrfs_trans_handle *trans, | ||
579 | struct btrfs_fs_info *fs_info, u64 bytenr, | ||
580 | u64 seq, struct ulist *refs, struct ulist *roots) | ||
581 | { | ||
582 | struct btrfs_key key; | ||
583 | struct btrfs_path *path; | ||
584 | struct btrfs_key info_key = { 0 }; | ||
585 | struct btrfs_delayed_ref_root *delayed_refs = NULL; | ||
586 | struct btrfs_delayed_ref_head *head = NULL; | ||
587 | int info_level = 0; | ||
588 | int ret; | ||
589 | struct list_head prefs_delayed; | ||
590 | struct list_head prefs; | ||
591 | struct __prelim_ref *ref; | ||
592 | |||
593 | INIT_LIST_HEAD(&prefs); | ||
594 | INIT_LIST_HEAD(&prefs_delayed); | ||
595 | |||
596 | key.objectid = bytenr; | ||
597 | key.type = BTRFS_EXTENT_ITEM_KEY; | ||
598 | key.offset = (u64)-1; | ||
599 | |||
600 | path = btrfs_alloc_path(); | ||
601 | if (!path) | ||
602 | return -ENOMEM; | ||
603 | |||
604 | /* | ||
605 | * grab both a lock on the path and a lock on the delayed ref head. | ||
606 | * We need both to get a consistent picture of how the refs look | ||
607 | * at a specified point in time | ||
608 | */ | ||
609 | again: | ||
610 | ret = btrfs_search_slot(trans, fs_info->extent_root, &key, path, 0, 0); | ||
611 | if (ret < 0) | ||
612 | goto out; | ||
613 | BUG_ON(ret == 0); | ||
614 | |||
615 | /* | ||
616 | * look if there are updates for this ref queued and lock the head | ||
617 | */ | ||
618 | delayed_refs = &trans->transaction->delayed_refs; | ||
619 | spin_lock(&delayed_refs->lock); | ||
620 | head = btrfs_find_delayed_ref_head(trans, bytenr); | ||
621 | if (head) { | ||
622 | if (!mutex_trylock(&head->mutex)) { | ||
623 | atomic_inc(&head->node.refs); | ||
624 | spin_unlock(&delayed_refs->lock); | ||
625 | |||
626 | btrfs_release_path(path); | ||
627 | |||
628 | /* | ||
629 | * Mutex was contended, block until it's | ||
630 | * released and try again | ||
631 | */ | ||
632 | mutex_lock(&head->mutex); | ||
633 | mutex_unlock(&head->mutex); | ||
634 | btrfs_put_delayed_ref(&head->node); | ||
635 | goto again; | ||
636 | } | ||
637 | ret = __add_delayed_refs(head, seq, &info_key, &prefs_delayed); | ||
638 | if (ret) | ||
639 | goto out; | ||
640 | } | ||
641 | spin_unlock(&delayed_refs->lock); | ||
642 | |||
643 | if (path->slots[0]) { | ||
644 | struct extent_buffer *leaf; | ||
645 | int slot; | ||
646 | |||
647 | leaf = path->nodes[0]; | ||
648 | slot = path->slots[0] - 1; | ||
649 | btrfs_item_key_to_cpu(leaf, &key, slot); | ||
650 | if (key.objectid == bytenr && | ||
651 | key.type == BTRFS_EXTENT_ITEM_KEY) { | ||
652 | ret = __add_inline_refs(fs_info, path, bytenr, | ||
653 | &info_key, &info_level, &prefs); | ||
654 | if (ret) | ||
655 | goto out; | ||
656 | ret = __add_keyed_refs(fs_info, path, bytenr, &info_key, | ||
657 | info_level, &prefs); | ||
658 | if (ret) | ||
659 | goto out; | ||
660 | } | ||
661 | } | ||
662 | btrfs_release_path(path); | ||
663 | |||
664 | /* | ||
665 | * when adding the delayed refs above, the info_key might not have | ||
666 | * been known yet. Go over the list and replace the missing keys | ||
667 | */ | ||
668 | list_for_each_entry(ref, &prefs_delayed, list) { | ||
669 | if ((ref->key.offset | ref->key.type | ref->key.objectid) == 0) | ||
670 | memcpy(&ref->key, &info_key, sizeof(ref->key)); | ||
671 | } | ||
672 | list_splice_init(&prefs_delayed, &prefs); | ||
673 | |||
674 | ret = __merge_refs(&prefs, 1); | ||
675 | if (ret) | ||
676 | goto out; | ||
677 | |||
678 | ret = __resolve_indirect_refs(fs_info, &prefs); | ||
679 | if (ret) | ||
680 | goto out; | ||
681 | |||
682 | ret = __merge_refs(&prefs, 2); | ||
683 | if (ret) | ||
684 | goto out; | ||
685 | |||
686 | while (!list_empty(&prefs)) { | ||
687 | ref = list_first_entry(&prefs, struct __prelim_ref, list); | ||
688 | list_del(&ref->list); | ||
689 | if (ref->count < 0) | ||
690 | WARN_ON(1); | ||
691 | if (ref->count && ref->root_id && ref->parent == 0) { | ||
692 | /* no parent == root of tree */ | ||
693 | ret = ulist_add(roots, ref->root_id, 0, GFP_NOFS); | ||
694 | BUG_ON(ret < 0); | ||
695 | } | ||
696 | if (ref->count && ref->parent) { | ||
697 | ret = ulist_add(refs, ref->parent, 0, GFP_NOFS); | ||
698 | BUG_ON(ret < 0); | ||
699 | } | ||
700 | kfree(ref); | ||
701 | } | ||
702 | |||
703 | out: | ||
704 | if (head) | ||
705 | mutex_unlock(&head->mutex); | ||
706 | btrfs_free_path(path); | ||
707 | while (!list_empty(&prefs)) { | ||
708 | ref = list_first_entry(&prefs, struct __prelim_ref, list); | ||
709 | list_del(&ref->list); | ||
710 | kfree(ref); | ||
711 | } | ||
712 | while (!list_empty(&prefs_delayed)) { | ||
713 | ref = list_first_entry(&prefs_delayed, struct __prelim_ref, | ||
714 | list); | ||
715 | list_del(&ref->list); | ||
716 | kfree(ref); | ||
717 | } | ||
718 | |||
719 | return ret; | ||
720 | } | ||
721 | |||
722 | /* | ||
723 | * Finds all leafs with a reference to the specified combination of bytenr and | ||
724 | * offset. key_list_head will point to a list of corresponding keys (caller must | ||
725 | * free each list element). The leafs will be stored in the leafs ulist, which | ||
726 | * must be freed with ulist_free. | ||
727 | * | ||
728 | * returns 0 on success, <0 on error | ||
729 | */ | ||
730 | static int btrfs_find_all_leafs(struct btrfs_trans_handle *trans, | ||
731 | struct btrfs_fs_info *fs_info, u64 bytenr, | ||
732 | u64 num_bytes, u64 seq, struct ulist **leafs) | ||
733 | { | ||
734 | struct ulist *tmp; | ||
735 | int ret; | ||
736 | |||
737 | tmp = ulist_alloc(GFP_NOFS); | ||
738 | if (!tmp) | ||
739 | return -ENOMEM; | ||
740 | *leafs = ulist_alloc(GFP_NOFS); | ||
741 | if (!*leafs) { | ||
742 | ulist_free(tmp); | ||
743 | return -ENOMEM; | ||
744 | } | ||
745 | |||
746 | ret = find_parent_nodes(trans, fs_info, bytenr, seq, *leafs, tmp); | ||
747 | ulist_free(tmp); | ||
748 | |||
749 | if (ret < 0 && ret != -ENOENT) { | ||
750 | ulist_free(*leafs); | ||
751 | return ret; | ||
752 | } | ||
753 | |||
754 | return 0; | ||
755 | } | ||
756 | |||
757 | /* | ||
758 | * walk all backrefs for a given extent to find all roots that reference this | ||
759 | * extent. Walking a backref means finding all extents that reference this | ||
760 | * extent and in turn walk the backrefs of those, too. Naturally this is a | ||
761 | * recursive process, but here it is implemented in an iterative fashion: We | ||
762 | * find all referencing extents for the extent in question and put them on a | ||
763 | * list. In turn, we find all referencing extents for those, further appending | ||
764 | * to the list. The way we iterate the list allows adding more elements after | ||
765 | * the current while iterating. The process stops when we reach the end of the | ||
766 | * list. Found roots are added to the roots list. | ||
767 | * | ||
768 | * returns 0 on success, < 0 on error. | ||
769 | */ | ||
770 | int btrfs_find_all_roots(struct btrfs_trans_handle *trans, | ||
771 | struct btrfs_fs_info *fs_info, u64 bytenr, | ||
772 | u64 num_bytes, u64 seq, struct ulist **roots) | ||
773 | { | ||
774 | struct ulist *tmp; | ||
775 | struct ulist_node *node = NULL; | ||
776 | int ret; | ||
777 | |||
778 | tmp = ulist_alloc(GFP_NOFS); | ||
779 | if (!tmp) | ||
780 | return -ENOMEM; | ||
781 | *roots = ulist_alloc(GFP_NOFS); | ||
782 | if (!*roots) { | ||
783 | ulist_free(tmp); | ||
784 | return -ENOMEM; | ||
785 | } | ||
786 | |||
787 | while (1) { | ||
788 | ret = find_parent_nodes(trans, fs_info, bytenr, seq, | ||
789 | tmp, *roots); | ||
790 | if (ret < 0 && ret != -ENOENT) { | ||
791 | ulist_free(tmp); | ||
792 | ulist_free(*roots); | ||
793 | return ret; | ||
794 | } | ||
795 | node = ulist_next(tmp, node); | ||
796 | if (!node) | ||
797 | break; | ||
798 | bytenr = node->val; | ||
799 | } | ||
800 | |||
801 | ulist_free(tmp); | ||
802 | return 0; | ||
803 | } | ||
804 | |||
34 | 805 | ||
35 | static int __inode_info(u64 inum, u64 ioff, u8 key_type, | 806 | static int __inode_info(u64 inum, u64 ioff, u8 key_type, |
36 | struct btrfs_root *fs_root, struct btrfs_path *path, | 807 | struct btrfs_root *fs_root, struct btrfs_path *path, |
@@ -181,8 +952,11 @@ int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical, | |||
181 | btrfs_item_key_to_cpu(path->nodes[0], found_key, path->slots[0]); | 952 | btrfs_item_key_to_cpu(path->nodes[0], found_key, path->slots[0]); |
182 | if (found_key->type != BTRFS_EXTENT_ITEM_KEY || | 953 | if (found_key->type != BTRFS_EXTENT_ITEM_KEY || |
183 | found_key->objectid > logical || | 954 | found_key->objectid > logical || |
184 | found_key->objectid + found_key->offset <= logical) | 955 | found_key->objectid + found_key->offset <= logical) { |
956 | pr_debug("logical %llu is not within any extent\n", | ||
957 | (unsigned long long)logical); | ||
185 | return -ENOENT; | 958 | return -ENOENT; |
959 | } | ||
186 | 960 | ||
187 | eb = path->nodes[0]; | 961 | eb = path->nodes[0]; |
188 | item_size = btrfs_item_size_nr(eb, path->slots[0]); | 962 | item_size = btrfs_item_size_nr(eb, path->slots[0]); |
@@ -191,6 +965,13 @@ int extent_from_logical(struct btrfs_fs_info *fs_info, u64 logical, | |||
191 | ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item); | 965 | ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item); |
192 | flags = btrfs_extent_flags(eb, ei); | 966 | flags = btrfs_extent_flags(eb, ei); |
193 | 967 | ||
968 | pr_debug("logical %llu is at position %llu within the extent (%llu " | ||
969 | "EXTENT_ITEM %llu) flags %#llx size %u\n", | ||
970 | (unsigned long long)logical, | ||
971 | (unsigned long long)(logical - found_key->objectid), | ||
972 | (unsigned long long)found_key->objectid, | ||
973 | (unsigned long long)found_key->offset, | ||
974 | (unsigned long long)flags, item_size); | ||
194 | if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) | 975 | if (flags & BTRFS_EXTENT_FLAG_TREE_BLOCK) |
195 | return BTRFS_EXTENT_FLAG_TREE_BLOCK; | 976 | return BTRFS_EXTENT_FLAG_TREE_BLOCK; |
196 | if (flags & BTRFS_EXTENT_FLAG_DATA) | 977 | if (flags & BTRFS_EXTENT_FLAG_DATA) |
@@ -287,128 +1068,11 @@ int tree_backref_for_extent(unsigned long *ptr, struct extent_buffer *eb, | |||
287 | return 0; | 1068 | return 0; |
288 | } | 1069 | } |
289 | 1070 | ||
290 | static int __data_list_add(struct list_head *head, u64 inum, | 1071 | static int iterate_leaf_refs(struct btrfs_fs_info *fs_info, |
291 | u64 extent_data_item_offset, u64 root) | 1072 | struct btrfs_path *path, u64 logical, |
292 | { | 1073 | u64 orig_extent_item_objectid, |
293 | struct __data_ref *ref; | 1074 | u64 extent_item_pos, u64 root, |
294 | 1075 | iterate_extent_inodes_t *iterate, void *ctx) | |
295 | ref = kmalloc(sizeof(*ref), GFP_NOFS); | ||
296 | if (!ref) | ||
297 | return -ENOMEM; | ||
298 | |||
299 | ref->inum = inum; | ||
300 | ref->extent_data_item_offset = extent_data_item_offset; | ||
301 | ref->root = root; | ||
302 | list_add_tail(&ref->list, head); | ||
303 | |||
304 | return 0; | ||
305 | } | ||
306 | |||
307 | static int __data_list_add_eb(struct list_head *head, struct extent_buffer *eb, | ||
308 | struct btrfs_extent_data_ref *dref) | ||
309 | { | ||
310 | return __data_list_add(head, btrfs_extent_data_ref_objectid(eb, dref), | ||
311 | btrfs_extent_data_ref_offset(eb, dref), | ||
312 | btrfs_extent_data_ref_root(eb, dref)); | ||
313 | } | ||
314 | |||
315 | static int __shared_list_add(struct list_head *head, u64 disk_byte) | ||
316 | { | ||
317 | struct __shared_ref *ref; | ||
318 | |||
319 | ref = kmalloc(sizeof(*ref), GFP_NOFS); | ||
320 | if (!ref) | ||
321 | return -ENOMEM; | ||
322 | |||
323 | ref->disk_byte = disk_byte; | ||
324 | list_add_tail(&ref->list, head); | ||
325 | |||
326 | return 0; | ||
327 | } | ||
328 | |||
329 | static int __iter_shared_inline_ref_inodes(struct btrfs_fs_info *fs_info, | ||
330 | u64 logical, u64 inum, | ||
331 | u64 extent_data_item_offset, | ||
332 | u64 extent_offset, | ||
333 | struct btrfs_path *path, | ||
334 | struct list_head *data_refs, | ||
335 | iterate_extent_inodes_t *iterate, | ||
336 | void *ctx) | ||
337 | { | ||
338 | u64 ref_root; | ||
339 | u32 item_size; | ||
340 | struct btrfs_key key; | ||
341 | struct extent_buffer *eb; | ||
342 | struct btrfs_extent_item *ei; | ||
343 | struct btrfs_extent_inline_ref *eiref; | ||
344 | struct __data_ref *ref; | ||
345 | int ret; | ||
346 | int type; | ||
347 | int last; | ||
348 | unsigned long ptr = 0; | ||
349 | |||
350 | WARN_ON(!list_empty(data_refs)); | ||
351 | ret = extent_from_logical(fs_info, logical, path, &key); | ||
352 | if (ret & BTRFS_EXTENT_FLAG_DATA) | ||
353 | ret = -EIO; | ||
354 | if (ret < 0) | ||
355 | goto out; | ||
356 | |||
357 | eb = path->nodes[0]; | ||
358 | ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item); | ||
359 | item_size = btrfs_item_size_nr(eb, path->slots[0]); | ||
360 | |||
361 | ret = 0; | ||
362 | ref_root = 0; | ||
363 | /* | ||
364 | * as done in iterate_extent_inodes, we first build a list of refs to | ||
365 | * iterate, then free the path and then iterate them to avoid deadlocks. | ||
366 | */ | ||
367 | do { | ||
368 | last = __get_extent_inline_ref(&ptr, eb, ei, item_size, | ||
369 | &eiref, &type); | ||
370 | if (last < 0) { | ||
371 | ret = last; | ||
372 | goto out; | ||
373 | } | ||
374 | if (type == BTRFS_TREE_BLOCK_REF_KEY || | ||
375 | type == BTRFS_SHARED_BLOCK_REF_KEY) { | ||
376 | ref_root = btrfs_extent_inline_ref_offset(eb, eiref); | ||
377 | ret = __data_list_add(data_refs, inum, | ||
378 | extent_data_item_offset, | ||
379 | ref_root); | ||
380 | } | ||
381 | } while (!ret && !last); | ||
382 | |||
383 | btrfs_release_path(path); | ||
384 | |||
385 | if (ref_root == 0) { | ||
386 | printk(KERN_ERR "btrfs: failed to find tree block ref " | ||
387 | "for shared data backref %llu\n", logical); | ||
388 | WARN_ON(1); | ||
389 | ret = -EIO; | ||
390 | } | ||
391 | |||
392 | out: | ||
393 | while (!list_empty(data_refs)) { | ||
394 | ref = list_first_entry(data_refs, struct __data_ref, list); | ||
395 | list_del(&ref->list); | ||
396 | if (!ret) | ||
397 | ret = iterate(ref->inum, extent_offset + | ||
398 | ref->extent_data_item_offset, | ||
399 | ref->root, ctx); | ||
400 | kfree(ref); | ||
401 | } | ||
402 | |||
403 | return ret; | ||
404 | } | ||
405 | |||
406 | static int __iter_shared_inline_ref(struct btrfs_fs_info *fs_info, | ||
407 | u64 logical, u64 orig_extent_item_objectid, | ||
408 | u64 extent_offset, struct btrfs_path *path, | ||
409 | struct list_head *data_refs, | ||
410 | iterate_extent_inodes_t *iterate, | ||
411 | void *ctx) | ||
412 | { | 1076 | { |
413 | u64 disk_byte; | 1077 | u64 disk_byte; |
414 | struct btrfs_key key; | 1078 | struct btrfs_key key; |
@@ -416,8 +1080,10 @@ static int __iter_shared_inline_ref(struct btrfs_fs_info *fs_info, | |||
416 | struct extent_buffer *eb; | 1080 | struct extent_buffer *eb; |
417 | int slot; | 1081 | int slot; |
418 | int nritems; | 1082 | int nritems; |
419 | int ret; | 1083 | int ret = 0; |
420 | int found = 0; | 1084 | int extent_type; |
1085 | u64 data_offset; | ||
1086 | u64 data_len; | ||
421 | 1087 | ||
422 | eb = read_tree_block(fs_info->tree_root, logical, | 1088 | eb = read_tree_block(fs_info->tree_root, logical, |
423 | fs_info->tree_root->leafsize, 0); | 1089 | fs_info->tree_root->leafsize, 0); |
@@ -435,149 +1101,99 @@ static int __iter_shared_inline_ref(struct btrfs_fs_info *fs_info, | |||
435 | if (key.type != BTRFS_EXTENT_DATA_KEY) | 1101 | if (key.type != BTRFS_EXTENT_DATA_KEY) |
436 | continue; | 1102 | continue; |
437 | fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item); | 1103 | fi = btrfs_item_ptr(eb, slot, struct btrfs_file_extent_item); |
438 | if (!fi) { | 1104 | extent_type = btrfs_file_extent_type(eb, fi); |
439 | free_extent_buffer(eb); | 1105 | if (extent_type == BTRFS_FILE_EXTENT_INLINE) |
440 | return -EIO; | 1106 | continue; |
441 | } | 1107 | /* don't skip BTRFS_FILE_EXTENT_PREALLOC, we can handle that */ |
442 | disk_byte = btrfs_file_extent_disk_bytenr(eb, fi); | 1108 | disk_byte = btrfs_file_extent_disk_bytenr(eb, fi); |
443 | if (disk_byte != orig_extent_item_objectid) { | 1109 | if (disk_byte != orig_extent_item_objectid) |
444 | if (found) | 1110 | continue; |
445 | break; | ||
446 | else | ||
447 | continue; | ||
448 | } | ||
449 | ++found; | ||
450 | ret = __iter_shared_inline_ref_inodes(fs_info, logical, | ||
451 | key.objectid, | ||
452 | key.offset, | ||
453 | extent_offset, path, | ||
454 | data_refs, | ||
455 | iterate, ctx); | ||
456 | if (ret) | ||
457 | break; | ||
458 | } | ||
459 | 1111 | ||
460 | if (!found) { | 1112 | data_offset = btrfs_file_extent_offset(eb, fi); |
461 | printk(KERN_ERR "btrfs: failed to follow shared data backref " | 1113 | data_len = btrfs_file_extent_num_bytes(eb, fi); |
462 | "to parent %llu\n", logical); | 1114 | |
463 | WARN_ON(1); | 1115 | if (extent_item_pos < data_offset || |
464 | ret = -EIO; | 1116 | extent_item_pos >= data_offset + data_len) |
1117 | continue; | ||
1118 | |||
1119 | pr_debug("ref for %llu resolved, key (%llu EXTEND_DATA %llu), " | ||
1120 | "root %llu\n", orig_extent_item_objectid, | ||
1121 | key.objectid, key.offset, root); | ||
1122 | ret = iterate(key.objectid, | ||
1123 | key.offset + (extent_item_pos - data_offset), | ||
1124 | root, ctx); | ||
1125 | if (ret) { | ||
1126 | pr_debug("stopping iteration because ret=%d\n", ret); | ||
1127 | break; | ||
1128 | } | ||
465 | } | 1129 | } |
466 | 1130 | ||
467 | free_extent_buffer(eb); | 1131 | free_extent_buffer(eb); |
1132 | |||
468 | return ret; | 1133 | return ret; |
469 | } | 1134 | } |
470 | 1135 | ||
471 | /* | 1136 | /* |
472 | * calls iterate() for every inode that references the extent identified by | 1137 | * calls iterate() for every inode that references the extent identified by |
473 | * the given parameters. will use the path given as a parameter and return it | 1138 | * the given parameters. |
474 | * released. | ||
475 | * when the iterator function returns a non-zero value, iteration stops. | 1139 | * when the iterator function returns a non-zero value, iteration stops. |
1140 | * path is guaranteed to be in released state when iterate() is called. | ||
476 | */ | 1141 | */ |
477 | int iterate_extent_inodes(struct btrfs_fs_info *fs_info, | 1142 | int iterate_extent_inodes(struct btrfs_fs_info *fs_info, |
478 | struct btrfs_path *path, | 1143 | struct btrfs_path *path, |
479 | u64 extent_item_objectid, | 1144 | u64 extent_item_objectid, u64 extent_item_pos, |
480 | u64 extent_offset, | ||
481 | iterate_extent_inodes_t *iterate, void *ctx) | 1145 | iterate_extent_inodes_t *iterate, void *ctx) |
482 | { | 1146 | { |
483 | unsigned long ptr = 0; | ||
484 | int last; | ||
485 | int ret; | 1147 | int ret; |
486 | int type; | ||
487 | u64 logical; | ||
488 | u32 item_size; | ||
489 | struct btrfs_extent_inline_ref *eiref; | ||
490 | struct btrfs_extent_data_ref *dref; | ||
491 | struct extent_buffer *eb; | ||
492 | struct btrfs_extent_item *ei; | ||
493 | struct btrfs_key key; | ||
494 | struct list_head data_refs = LIST_HEAD_INIT(data_refs); | 1148 | struct list_head data_refs = LIST_HEAD_INIT(data_refs); |
495 | struct list_head shared_refs = LIST_HEAD_INIT(shared_refs); | 1149 | struct list_head shared_refs = LIST_HEAD_INIT(shared_refs); |
496 | struct __data_ref *ref_d; | 1150 | struct btrfs_trans_handle *trans; |
497 | struct __shared_ref *ref_s; | 1151 | struct ulist *refs; |
498 | 1152 | struct ulist *roots; | |
499 | eb = path->nodes[0]; | 1153 | struct ulist_node *ref_node = NULL; |
500 | ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item); | 1154 | struct ulist_node *root_node = NULL; |
501 | item_size = btrfs_item_size_nr(eb, path->slots[0]); | 1155 | struct seq_list seq_elem; |
502 | 1156 | struct btrfs_delayed_ref_root *delayed_refs; | |
503 | /* first we iterate the inline refs, ... */ | 1157 | |
504 | do { | 1158 | trans = btrfs_join_transaction(fs_info->extent_root); |
505 | last = __get_extent_inline_ref(&ptr, eb, ei, item_size, | 1159 | if (IS_ERR(trans)) |
506 | &eiref, &type); | 1160 | return PTR_ERR(trans); |
507 | if (last == -ENOENT) { | 1161 | |
508 | ret = 0; | 1162 | pr_debug("resolving all inodes for extent %llu\n", |
509 | break; | 1163 | extent_item_objectid); |
510 | } | 1164 | |
511 | if (last < 0) { | 1165 | delayed_refs = &trans->transaction->delayed_refs; |
512 | ret = last; | 1166 | spin_lock(&delayed_refs->lock); |
513 | break; | 1167 | btrfs_get_delayed_seq(delayed_refs, &seq_elem); |
514 | } | 1168 | spin_unlock(&delayed_refs->lock); |
1169 | |||
1170 | ret = btrfs_find_all_leafs(trans, fs_info, extent_item_objectid, | ||
1171 | extent_item_pos, seq_elem.seq, | ||
1172 | &refs); | ||
515 | 1173 | ||
516 | if (type == BTRFS_EXTENT_DATA_REF_KEY) { | 1174 | if (ret) |
517 | dref = (struct btrfs_extent_data_ref *)(&eiref->offset); | 1175 | goto out; |
518 | ret = __data_list_add_eb(&data_refs, eb, dref); | ||
519 | } else if (type == BTRFS_SHARED_DATA_REF_KEY) { | ||
520 | logical = btrfs_extent_inline_ref_offset(eb, eiref); | ||
521 | ret = __shared_list_add(&shared_refs, logical); | ||
522 | } | ||
523 | } while (!ret && !last); | ||
524 | 1176 | ||
525 | /* ... then we proceed to in-tree references and ... */ | 1177 | while (!ret && (ref_node = ulist_next(refs, ref_node))) { |
526 | while (!ret) { | 1178 | ret = btrfs_find_all_roots(trans, fs_info, ref_node->val, -1, |
527 | ++path->slots[0]; | 1179 | seq_elem.seq, &roots); |
528 | if (path->slots[0] > btrfs_header_nritems(eb)) { | 1180 | if (ret) |
529 | ret = btrfs_next_leaf(fs_info->extent_root, path); | ||
530 | if (ret) { | ||
531 | if (ret == 1) | ||
532 | ret = 0; /* we're done */ | ||
533 | break; | ||
534 | } | ||
535 | eb = path->nodes[0]; | ||
536 | } | ||
537 | btrfs_item_key_to_cpu(eb, &key, path->slots[0]); | ||
538 | if (key.objectid != extent_item_objectid) | ||
539 | break; | 1181 | break; |
540 | if (key.type == BTRFS_EXTENT_DATA_REF_KEY) { | 1182 | while (!ret && (root_node = ulist_next(roots, root_node))) { |
541 | dref = btrfs_item_ptr(eb, path->slots[0], | 1183 | pr_debug("root %llu references leaf %llu\n", |
542 | struct btrfs_extent_data_ref); | 1184 | root_node->val, ref_node->val); |
543 | ret = __data_list_add_eb(&data_refs, eb, dref); | 1185 | ret = iterate_leaf_refs(fs_info, path, ref_node->val, |
544 | } else if (key.type == BTRFS_SHARED_DATA_REF_KEY) { | 1186 | extent_item_objectid, |
545 | ret = __shared_list_add(&shared_refs, key.offset); | 1187 | extent_item_pos, root_node->val, |
1188 | iterate, ctx); | ||
546 | } | 1189 | } |
547 | } | 1190 | } |
548 | 1191 | ||
549 | btrfs_release_path(path); | 1192 | ulist_free(refs); |
550 | 1193 | ulist_free(roots); | |
551 | /* | 1194 | out: |
552 | * ... only at the very end we can process the refs we found. this is | 1195 | btrfs_put_delayed_seq(delayed_refs, &seq_elem); |
553 | * because the iterator function we call is allowed to make tree lookups | 1196 | btrfs_end_transaction(trans, fs_info->extent_root); |
554 | * and we have to avoid deadlocks. additionally, we need more tree | ||
555 | * lookups ourselves for shared data refs. | ||
556 | */ | ||
557 | while (!list_empty(&data_refs)) { | ||
558 | ref_d = list_first_entry(&data_refs, struct __data_ref, list); | ||
559 | list_del(&ref_d->list); | ||
560 | if (!ret) | ||
561 | ret = iterate(ref_d->inum, extent_offset + | ||
562 | ref_d->extent_data_item_offset, | ||
563 | ref_d->root, ctx); | ||
564 | kfree(ref_d); | ||
565 | } | ||
566 | |||
567 | while (!list_empty(&shared_refs)) { | ||
568 | ref_s = list_first_entry(&shared_refs, struct __shared_ref, | ||
569 | list); | ||
570 | list_del(&ref_s->list); | ||
571 | if (!ret) | ||
572 | ret = __iter_shared_inline_ref(fs_info, | ||
573 | ref_s->disk_byte, | ||
574 | extent_item_objectid, | ||
575 | extent_offset, path, | ||
576 | &data_refs, | ||
577 | iterate, ctx); | ||
578 | kfree(ref_s); | ||
579 | } | ||
580 | |||
581 | return ret; | 1197 | return ret; |
582 | } | 1198 | } |
583 | 1199 | ||
@@ -586,19 +1202,20 @@ int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info, | |||
586 | iterate_extent_inodes_t *iterate, void *ctx) | 1202 | iterate_extent_inodes_t *iterate, void *ctx) |
587 | { | 1203 | { |
588 | int ret; | 1204 | int ret; |
589 | u64 offset; | 1205 | u64 extent_item_pos; |
590 | struct btrfs_key found_key; | 1206 | struct btrfs_key found_key; |
591 | 1207 | ||
592 | ret = extent_from_logical(fs_info, logical, path, | 1208 | ret = extent_from_logical(fs_info, logical, path, |
593 | &found_key); | 1209 | &found_key); |
1210 | btrfs_release_path(path); | ||
594 | if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) | 1211 | if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) |
595 | ret = -EINVAL; | 1212 | ret = -EINVAL; |
596 | if (ret < 0) | 1213 | if (ret < 0) |
597 | return ret; | 1214 | return ret; |
598 | 1215 | ||
599 | offset = logical - found_key.objectid; | 1216 | extent_item_pos = logical - found_key.objectid; |
600 | ret = iterate_extent_inodes(fs_info, path, found_key.objectid, | 1217 | ret = iterate_extent_inodes(fs_info, path, found_key.objectid, |
601 | offset, iterate, ctx); | 1218 | extent_item_pos, iterate, ctx); |
602 | 1219 | ||
603 | return ret; | 1220 | return ret; |
604 | } | 1221 | } |
@@ -643,6 +1260,10 @@ static int iterate_irefs(u64 inum, struct btrfs_root *fs_root, | |||
643 | for (cur = 0; cur < btrfs_item_size(eb, item); cur += len) { | 1260 | for (cur = 0; cur < btrfs_item_size(eb, item); cur += len) { |
644 | name_len = btrfs_inode_ref_name_len(eb, iref); | 1261 | name_len = btrfs_inode_ref_name_len(eb, iref); |
645 | /* path must be released before calling iterate()! */ | 1262 | /* path must be released before calling iterate()! */ |
1263 | pr_debug("following ref at offset %u for inode %llu in " | ||
1264 | "tree %llu\n", cur, | ||
1265 | (unsigned long long)found_key.objectid, | ||
1266 | (unsigned long long)fs_root->objectid); | ||
646 | ret = iterate(parent, iref, eb, ctx); | 1267 | ret = iterate(parent, iref, eb, ctx); |
647 | if (ret) { | 1268 | if (ret) { |
648 | free_extent_buffer(eb); | 1269 | free_extent_buffer(eb); |
@@ -683,10 +1304,14 @@ static int inode_to_path(u64 inum, struct btrfs_inode_ref *iref, | |||
683 | return PTR_ERR(fspath); | 1304 | return PTR_ERR(fspath); |
684 | 1305 | ||
685 | if (fspath > fspath_min) { | 1306 | if (fspath > fspath_min) { |
1307 | pr_debug("path resolved: %s\n", fspath); | ||
686 | ipath->fspath->val[i] = (u64)(unsigned long)fspath; | 1308 | ipath->fspath->val[i] = (u64)(unsigned long)fspath; |
687 | ++ipath->fspath->elem_cnt; | 1309 | ++ipath->fspath->elem_cnt; |
688 | ipath->fspath->bytes_left = fspath - fspath_min; | 1310 | ipath->fspath->bytes_left = fspath - fspath_min; |
689 | } else { | 1311 | } else { |
1312 | pr_debug("missed path, not enough space. missing bytes: %lu, " | ||
1313 | "constructed so far: %s\n", | ||
1314 | (unsigned long)(fspath_min - fspath), fspath_min); | ||
690 | ++ipath->fspath->elem_missed; | 1315 | ++ipath->fspath->elem_missed; |
691 | ipath->fspath->bytes_missing += fspath_min - fspath; | 1316 | ipath->fspath->bytes_missing += fspath_min - fspath; |
692 | ipath->fspath->bytes_left = 0; | 1317 | ipath->fspath->bytes_left = 0; |
diff --git a/fs/btrfs/backref.h b/fs/btrfs/backref.h index 92618837cb8f..d00dfa9ca934 100644 --- a/fs/btrfs/backref.h +++ b/fs/btrfs/backref.h | |||
@@ -20,6 +20,7 @@ | |||
20 | #define __BTRFS_BACKREF__ | 20 | #define __BTRFS_BACKREF__ |
21 | 21 | ||
22 | #include "ioctl.h" | 22 | #include "ioctl.h" |
23 | #include "ulist.h" | ||
23 | 24 | ||
24 | struct inode_fs_paths { | 25 | struct inode_fs_paths { |
25 | struct btrfs_path *btrfs_path; | 26 | struct btrfs_path *btrfs_path; |
@@ -54,6 +55,10 @@ int iterate_inodes_from_logical(u64 logical, struct btrfs_fs_info *fs_info, | |||
54 | 55 | ||
55 | int paths_from_inode(u64 inum, struct inode_fs_paths *ipath); | 56 | int paths_from_inode(u64 inum, struct inode_fs_paths *ipath); |
56 | 57 | ||
58 | int btrfs_find_all_roots(struct btrfs_trans_handle *trans, | ||
59 | struct btrfs_fs_info *fs_info, u64 bytenr, | ||
60 | u64 num_bytes, u64 seq, struct ulist **roots); | ||
61 | |||
57 | struct btrfs_data_container *init_data_container(u32 total_bytes); | 62 | struct btrfs_data_container *init_data_container(u32 total_bytes); |
58 | struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root, | 63 | struct inode_fs_paths *init_ipath(s32 total_bytes, struct btrfs_root *fs_root, |
59 | struct btrfs_path *path); | 64 | struct btrfs_path *path); |
diff --git a/fs/btrfs/ctree.c b/fs/btrfs/ctree.c index dede441bdeee..0639a555e16e 100644 --- a/fs/btrfs/ctree.c +++ b/fs/btrfs/ctree.c | |||
@@ -240,7 +240,7 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, | |||
240 | 240 | ||
241 | cow = btrfs_alloc_free_block(trans, root, buf->len, 0, | 241 | cow = btrfs_alloc_free_block(trans, root, buf->len, 0, |
242 | new_root_objectid, &disk_key, level, | 242 | new_root_objectid, &disk_key, level, |
243 | buf->start, 0); | 243 | buf->start, 0, 1); |
244 | if (IS_ERR(cow)) | 244 | if (IS_ERR(cow)) |
245 | return PTR_ERR(cow); | 245 | return PTR_ERR(cow); |
246 | 246 | ||
@@ -261,9 +261,9 @@ int btrfs_copy_root(struct btrfs_trans_handle *trans, | |||
261 | 261 | ||
262 | WARN_ON(btrfs_header_generation(buf) > trans->transid); | 262 | WARN_ON(btrfs_header_generation(buf) > trans->transid); |
263 | if (new_root_objectid == BTRFS_TREE_RELOC_OBJECTID) | 263 | if (new_root_objectid == BTRFS_TREE_RELOC_OBJECTID) |
264 | ret = btrfs_inc_ref(trans, root, cow, 1); | 264 | ret = btrfs_inc_ref(trans, root, cow, 1, 1); |
265 | else | 265 | else |
266 | ret = btrfs_inc_ref(trans, root, cow, 0); | 266 | ret = btrfs_inc_ref(trans, root, cow, 0, 1); |
267 | 267 | ||
268 | if (ret) | 268 | if (ret) |
269 | return ret; | 269 | return ret; |
@@ -350,14 +350,14 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, | |||
350 | if ((owner == root->root_key.objectid || | 350 | if ((owner == root->root_key.objectid || |
351 | root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && | 351 | root->root_key.objectid == BTRFS_TREE_RELOC_OBJECTID) && |
352 | !(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) { | 352 | !(flags & BTRFS_BLOCK_FLAG_FULL_BACKREF)) { |
353 | ret = btrfs_inc_ref(trans, root, buf, 1); | 353 | ret = btrfs_inc_ref(trans, root, buf, 1, 1); |
354 | BUG_ON(ret); | 354 | BUG_ON(ret); |
355 | 355 | ||
356 | if (root->root_key.objectid == | 356 | if (root->root_key.objectid == |
357 | BTRFS_TREE_RELOC_OBJECTID) { | 357 | BTRFS_TREE_RELOC_OBJECTID) { |
358 | ret = btrfs_dec_ref(trans, root, buf, 0); | 358 | ret = btrfs_dec_ref(trans, root, buf, 0, 1); |
359 | BUG_ON(ret); | 359 | BUG_ON(ret); |
360 | ret = btrfs_inc_ref(trans, root, cow, 1); | 360 | ret = btrfs_inc_ref(trans, root, cow, 1, 1); |
361 | BUG_ON(ret); | 361 | BUG_ON(ret); |
362 | } | 362 | } |
363 | new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF; | 363 | new_flags |= BTRFS_BLOCK_FLAG_FULL_BACKREF; |
@@ -365,9 +365,9 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, | |||
365 | 365 | ||
366 | if (root->root_key.objectid == | 366 | if (root->root_key.objectid == |
367 | BTRFS_TREE_RELOC_OBJECTID) | 367 | BTRFS_TREE_RELOC_OBJECTID) |
368 | ret = btrfs_inc_ref(trans, root, cow, 1); | 368 | ret = btrfs_inc_ref(trans, root, cow, 1, 1); |
369 | else | 369 | else |
370 | ret = btrfs_inc_ref(trans, root, cow, 0); | 370 | ret = btrfs_inc_ref(trans, root, cow, 0, 1); |
371 | BUG_ON(ret); | 371 | BUG_ON(ret); |
372 | } | 372 | } |
373 | if (new_flags != 0) { | 373 | if (new_flags != 0) { |
@@ -381,11 +381,11 @@ static noinline int update_ref_for_cow(struct btrfs_trans_handle *trans, | |||
381 | if (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF) { | 381 | if (flags & BTRFS_BLOCK_FLAG_FULL_BACKREF) { |
382 | if (root->root_key.objectid == | 382 | if (root->root_key.objectid == |
383 | BTRFS_TREE_RELOC_OBJECTID) | 383 | BTRFS_TREE_RELOC_OBJECTID) |
384 | ret = btrfs_inc_ref(trans, root, cow, 1); | 384 | ret = btrfs_inc_ref(trans, root, cow, 1, 1); |
385 | else | 385 | else |
386 | ret = btrfs_inc_ref(trans, root, cow, 0); | 386 | ret = btrfs_inc_ref(trans, root, cow, 0, 1); |
387 | BUG_ON(ret); | 387 | BUG_ON(ret); |
388 | ret = btrfs_dec_ref(trans, root, buf, 1); | 388 | ret = btrfs_dec_ref(trans, root, buf, 1, 1); |
389 | BUG_ON(ret); | 389 | BUG_ON(ret); |
390 | } | 390 | } |
391 | clean_tree_block(trans, root, buf); | 391 | clean_tree_block(trans, root, buf); |
@@ -446,7 +446,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
446 | 446 | ||
447 | cow = btrfs_alloc_free_block(trans, root, buf->len, parent_start, | 447 | cow = btrfs_alloc_free_block(trans, root, buf->len, parent_start, |
448 | root->root_key.objectid, &disk_key, | 448 | root->root_key.objectid, &disk_key, |
449 | level, search_start, empty_size); | 449 | level, search_start, empty_size, 1); |
450 | if (IS_ERR(cow)) | 450 | if (IS_ERR(cow)) |
451 | return PTR_ERR(cow); | 451 | return PTR_ERR(cow); |
452 | 452 | ||
@@ -484,7 +484,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
484 | rcu_assign_pointer(root->node, cow); | 484 | rcu_assign_pointer(root->node, cow); |
485 | 485 | ||
486 | btrfs_free_tree_block(trans, root, buf, parent_start, | 486 | btrfs_free_tree_block(trans, root, buf, parent_start, |
487 | last_ref); | 487 | last_ref, 1); |
488 | free_extent_buffer(buf); | 488 | free_extent_buffer(buf); |
489 | add_root_to_dirty_list(root); | 489 | add_root_to_dirty_list(root); |
490 | } else { | 490 | } else { |
@@ -500,7 +500,7 @@ static noinline int __btrfs_cow_block(struct btrfs_trans_handle *trans, | |||
500 | trans->transid); | 500 | trans->transid); |
501 | btrfs_mark_buffer_dirty(parent); | 501 | btrfs_mark_buffer_dirty(parent); |
502 | btrfs_free_tree_block(trans, root, buf, parent_start, | 502 | btrfs_free_tree_block(trans, root, buf, parent_start, |
503 | last_ref); | 503 | last_ref, 1); |
504 | } | 504 | } |
505 | if (unlock_orig) | 505 | if (unlock_orig) |
506 | btrfs_tree_unlock(buf); | 506 | btrfs_tree_unlock(buf); |
@@ -957,7 +957,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
957 | free_extent_buffer(mid); | 957 | free_extent_buffer(mid); |
958 | 958 | ||
959 | root_sub_used(root, mid->len); | 959 | root_sub_used(root, mid->len); |
960 | btrfs_free_tree_block(trans, root, mid, 0, 1); | 960 | btrfs_free_tree_block(trans, root, mid, 0, 1, 0); |
961 | /* once for the root ptr */ | 961 | /* once for the root ptr */ |
962 | free_extent_buffer(mid); | 962 | free_extent_buffer(mid); |
963 | return 0; | 963 | return 0; |
@@ -1015,7 +1015,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
1015 | if (wret) | 1015 | if (wret) |
1016 | ret = wret; | 1016 | ret = wret; |
1017 | root_sub_used(root, right->len); | 1017 | root_sub_used(root, right->len); |
1018 | btrfs_free_tree_block(trans, root, right, 0, 1); | 1018 | btrfs_free_tree_block(trans, root, right, 0, 1, 0); |
1019 | free_extent_buffer(right); | 1019 | free_extent_buffer(right); |
1020 | right = NULL; | 1020 | right = NULL; |
1021 | } else { | 1021 | } else { |
@@ -1055,7 +1055,7 @@ static noinline int balance_level(struct btrfs_trans_handle *trans, | |||
1055 | if (wret) | 1055 | if (wret) |
1056 | ret = wret; | 1056 | ret = wret; |
1057 | root_sub_used(root, mid->len); | 1057 | root_sub_used(root, mid->len); |
1058 | btrfs_free_tree_block(trans, root, mid, 0, 1); | 1058 | btrfs_free_tree_block(trans, root, mid, 0, 1, 0); |
1059 | free_extent_buffer(mid); | 1059 | free_extent_buffer(mid); |
1060 | mid = NULL; | 1060 | mid = NULL; |
1061 | } else { | 1061 | } else { |
@@ -2089,7 +2089,7 @@ static noinline int insert_new_root(struct btrfs_trans_handle *trans, | |||
2089 | 2089 | ||
2090 | c = btrfs_alloc_free_block(trans, root, root->nodesize, 0, | 2090 | c = btrfs_alloc_free_block(trans, root, root->nodesize, 0, |
2091 | root->root_key.objectid, &lower_key, | 2091 | root->root_key.objectid, &lower_key, |
2092 | level, root->node->start, 0); | 2092 | level, root->node->start, 0, 0); |
2093 | if (IS_ERR(c)) | 2093 | if (IS_ERR(c)) |
2094 | return PTR_ERR(c); | 2094 | return PTR_ERR(c); |
2095 | 2095 | ||
@@ -2216,7 +2216,7 @@ static noinline int split_node(struct btrfs_trans_handle *trans, | |||
2216 | 2216 | ||
2217 | split = btrfs_alloc_free_block(trans, root, root->nodesize, 0, | 2217 | split = btrfs_alloc_free_block(trans, root, root->nodesize, 0, |
2218 | root->root_key.objectid, | 2218 | root->root_key.objectid, |
2219 | &disk_key, level, c->start, 0); | 2219 | &disk_key, level, c->start, 0, 0); |
2220 | if (IS_ERR(split)) | 2220 | if (IS_ERR(split)) |
2221 | return PTR_ERR(split); | 2221 | return PTR_ERR(split); |
2222 | 2222 | ||
@@ -2970,7 +2970,7 @@ again: | |||
2970 | 2970 | ||
2971 | right = btrfs_alloc_free_block(trans, root, root->leafsize, 0, | 2971 | right = btrfs_alloc_free_block(trans, root, root->leafsize, 0, |
2972 | root->root_key.objectid, | 2972 | root->root_key.objectid, |
2973 | &disk_key, 0, l->start, 0); | 2973 | &disk_key, 0, l->start, 0, 0); |
2974 | if (IS_ERR(right)) | 2974 | if (IS_ERR(right)) |
2975 | return PTR_ERR(right); | 2975 | return PTR_ERR(right); |
2976 | 2976 | ||
@@ -3781,7 +3781,7 @@ static noinline int btrfs_del_leaf(struct btrfs_trans_handle *trans, | |||
3781 | 3781 | ||
3782 | root_sub_used(root, leaf->len); | 3782 | root_sub_used(root, leaf->len); |
3783 | 3783 | ||
3784 | btrfs_free_tree_block(trans, root, leaf, 0, 1); | 3784 | btrfs_free_tree_block(trans, root, leaf, 0, 1, 0); |
3785 | return 0; | 3785 | return 0; |
3786 | } | 3786 | } |
3787 | /* | 3787 | /* |
diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index dfc136cc07d7..b6d1020c4571 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h | |||
@@ -2439,11 +2439,11 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
2439 | struct btrfs_root *root, u32 blocksize, | 2439 | struct btrfs_root *root, u32 blocksize, |
2440 | u64 parent, u64 root_objectid, | 2440 | u64 parent, u64 root_objectid, |
2441 | struct btrfs_disk_key *key, int level, | 2441 | struct btrfs_disk_key *key, int level, |
2442 | u64 hint, u64 empty_size); | 2442 | u64 hint, u64 empty_size, int for_cow); |
2443 | void btrfs_free_tree_block(struct btrfs_trans_handle *trans, | 2443 | void btrfs_free_tree_block(struct btrfs_trans_handle *trans, |
2444 | struct btrfs_root *root, | 2444 | struct btrfs_root *root, |
2445 | struct extent_buffer *buf, | 2445 | struct extent_buffer *buf, |
2446 | u64 parent, int last_ref); | 2446 | u64 parent, int last_ref, int for_cow); |
2447 | struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, | 2447 | struct extent_buffer *btrfs_init_new_buffer(struct btrfs_trans_handle *trans, |
2448 | struct btrfs_root *root, | 2448 | struct btrfs_root *root, |
2449 | u64 bytenr, u32 blocksize, | 2449 | u64 bytenr, u32 blocksize, |
@@ -2463,17 +2463,17 @@ int btrfs_reserve_extent(struct btrfs_trans_handle *trans, | |||
2463 | u64 search_end, struct btrfs_key *ins, | 2463 | u64 search_end, struct btrfs_key *ins, |
2464 | u64 data); | 2464 | u64 data); |
2465 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 2465 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
2466 | struct extent_buffer *buf, int full_backref); | 2466 | struct extent_buffer *buf, int full_backref, int for_cow); |
2467 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 2467 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
2468 | struct extent_buffer *buf, int full_backref); | 2468 | struct extent_buffer *buf, int full_backref, int for_cow); |
2469 | int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, | 2469 | int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, |
2470 | struct btrfs_root *root, | 2470 | struct btrfs_root *root, |
2471 | u64 bytenr, u64 num_bytes, u64 flags, | 2471 | u64 bytenr, u64 num_bytes, u64 flags, |
2472 | int is_data); | 2472 | int is_data); |
2473 | int btrfs_free_extent(struct btrfs_trans_handle *trans, | 2473 | int btrfs_free_extent(struct btrfs_trans_handle *trans, |
2474 | struct btrfs_root *root, | 2474 | struct btrfs_root *root, |
2475 | u64 bytenr, u64 num_bytes, u64 parent, | 2475 | u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, |
2476 | u64 root_objectid, u64 owner, u64 offset); | 2476 | u64 owner, u64 offset, int for_cow); |
2477 | 2477 | ||
2478 | int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len); | 2478 | int btrfs_free_reserved_extent(struct btrfs_root *root, u64 start, u64 len); |
2479 | int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root, | 2479 | int btrfs_free_and_pin_reserved_extent(struct btrfs_root *root, |
@@ -2485,7 +2485,7 @@ int btrfs_finish_extent_commit(struct btrfs_trans_handle *trans, | |||
2485 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | 2485 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, |
2486 | struct btrfs_root *root, | 2486 | struct btrfs_root *root, |
2487 | u64 bytenr, u64 num_bytes, u64 parent, | 2487 | u64 bytenr, u64 num_bytes, u64 parent, |
2488 | u64 root_objectid, u64 owner, u64 offset); | 2488 | u64 root_objectid, u64 owner, u64 offset, int for_cow); |
2489 | 2489 | ||
2490 | int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, | 2490 | int btrfs_write_dirty_block_groups(struct btrfs_trans_handle *trans, |
2491 | struct btrfs_root *root); | 2491 | struct btrfs_root *root); |
@@ -2644,10 +2644,18 @@ static inline int btrfs_insert_empty_item(struct btrfs_trans_handle *trans, | |||
2644 | } | 2644 | } |
2645 | 2645 | ||
2646 | int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); | 2646 | int btrfs_next_leaf(struct btrfs_root *root, struct btrfs_path *path); |
2647 | static inline int btrfs_next_item(struct btrfs_root *root, struct btrfs_path *p) | ||
2648 | { | ||
2649 | ++p->slots[0]; | ||
2650 | if (p->slots[0] >= btrfs_header_nritems(p->nodes[0])) | ||
2651 | return btrfs_next_leaf(root, p); | ||
2652 | return 0; | ||
2653 | } | ||
2647 | int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); | 2654 | int btrfs_prev_leaf(struct btrfs_root *root, struct btrfs_path *path); |
2648 | int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf); | 2655 | int btrfs_leaf_free_space(struct btrfs_root *root, struct extent_buffer *leaf); |
2649 | void btrfs_drop_snapshot(struct btrfs_root *root, | 2656 | void btrfs_drop_snapshot(struct btrfs_root *root, |
2650 | struct btrfs_block_rsv *block_rsv, int update_ref); | 2657 | struct btrfs_block_rsv *block_rsv, int update_ref, |
2658 | int for_reloc); | ||
2651 | int btrfs_drop_subtree(struct btrfs_trans_handle *trans, | 2659 | int btrfs_drop_subtree(struct btrfs_trans_handle *trans, |
2652 | struct btrfs_root *root, | 2660 | struct btrfs_root *root, |
2653 | struct extent_buffer *node, | 2661 | struct extent_buffer *node, |
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c index 125cf76fcd08..66e4f29505a3 100644 --- a/fs/btrfs/delayed-ref.c +++ b/fs/btrfs/delayed-ref.c | |||
@@ -101,6 +101,11 @@ static int comp_entry(struct btrfs_delayed_ref_node *ref2, | |||
101 | return -1; | 101 | return -1; |
102 | if (ref1->type > ref2->type) | 102 | if (ref1->type > ref2->type) |
103 | return 1; | 103 | return 1; |
104 | /* merging of sequenced refs is not allowed */ | ||
105 | if (ref1->seq < ref2->seq) | ||
106 | return -1; | ||
107 | if (ref1->seq > ref2->seq) | ||
108 | return 1; | ||
104 | if (ref1->type == BTRFS_TREE_BLOCK_REF_KEY || | 109 | if (ref1->type == BTRFS_TREE_BLOCK_REF_KEY || |
105 | ref1->type == BTRFS_SHARED_BLOCK_REF_KEY) { | 110 | ref1->type == BTRFS_SHARED_BLOCK_REF_KEY) { |
106 | return comp_tree_refs(btrfs_delayed_node_to_tree_ref(ref2), | 111 | return comp_tree_refs(btrfs_delayed_node_to_tree_ref(ref2), |
@@ -150,16 +155,22 @@ static struct btrfs_delayed_ref_node *tree_insert(struct rb_root *root, | |||
150 | 155 | ||
151 | /* | 156 | /* |
152 | * find an head entry based on bytenr. This returns the delayed ref | 157 | * find an head entry based on bytenr. This returns the delayed ref |
153 | * head if it was able to find one, or NULL if nothing was in that spot | 158 | * head if it was able to find one, or NULL if nothing was in that spot. |
159 | * If return_bigger is given, the next bigger entry is returned if no exact | ||
160 | * match is found. | ||
154 | */ | 161 | */ |
155 | static struct btrfs_delayed_ref_node *find_ref_head(struct rb_root *root, | 162 | static struct btrfs_delayed_ref_node *find_ref_head(struct rb_root *root, |
156 | u64 bytenr, | 163 | u64 bytenr, |
157 | struct btrfs_delayed_ref_node **last) | 164 | struct btrfs_delayed_ref_node **last, |
165 | int return_bigger) | ||
158 | { | 166 | { |
159 | struct rb_node *n = root->rb_node; | 167 | struct rb_node *n; |
160 | struct btrfs_delayed_ref_node *entry; | 168 | struct btrfs_delayed_ref_node *entry; |
161 | int cmp; | 169 | int cmp = 0; |
162 | 170 | ||
171 | again: | ||
172 | n = root->rb_node; | ||
173 | entry = NULL; | ||
163 | while (n) { | 174 | while (n) { |
164 | entry = rb_entry(n, struct btrfs_delayed_ref_node, rb_node); | 175 | entry = rb_entry(n, struct btrfs_delayed_ref_node, rb_node); |
165 | WARN_ON(!entry->in_tree); | 176 | WARN_ON(!entry->in_tree); |
@@ -182,6 +193,19 @@ static struct btrfs_delayed_ref_node *find_ref_head(struct rb_root *root, | |||
182 | else | 193 | else |
183 | return entry; | 194 | return entry; |
184 | } | 195 | } |
196 | if (entry && return_bigger) { | ||
197 | if (cmp > 0) { | ||
198 | n = rb_next(&entry->rb_node); | ||
199 | if (!n) | ||
200 | n = rb_first(root); | ||
201 | entry = rb_entry(n, struct btrfs_delayed_ref_node, | ||
202 | rb_node); | ||
203 | bytenr = entry->bytenr; | ||
204 | return_bigger = 0; | ||
205 | goto again; | ||
206 | } | ||
207 | return entry; | ||
208 | } | ||
185 | return NULL; | 209 | return NULL; |
186 | } | 210 | } |
187 | 211 | ||
@@ -209,6 +233,24 @@ int btrfs_delayed_ref_lock(struct btrfs_trans_handle *trans, | |||
209 | return 0; | 233 | return 0; |
210 | } | 234 | } |
211 | 235 | ||
236 | int btrfs_check_delayed_seq(struct btrfs_delayed_ref_root *delayed_refs, | ||
237 | u64 seq) | ||
238 | { | ||
239 | struct seq_list *elem; | ||
240 | |||
241 | assert_spin_locked(&delayed_refs->lock); | ||
242 | if (list_empty(&delayed_refs->seq_head)) | ||
243 | return 0; | ||
244 | |||
245 | elem = list_first_entry(&delayed_refs->seq_head, struct seq_list, list); | ||
246 | if (seq >= elem->seq) { | ||
247 | pr_debug("holding back delayed_ref %llu, lowest is %llu (%p)\n", | ||
248 | seq, elem->seq, delayed_refs); | ||
249 | return 1; | ||
250 | } | ||
251 | return 0; | ||
252 | } | ||
253 | |||
212 | int btrfs_find_ref_cluster(struct btrfs_trans_handle *trans, | 254 | int btrfs_find_ref_cluster(struct btrfs_trans_handle *trans, |
213 | struct list_head *cluster, u64 start) | 255 | struct list_head *cluster, u64 start) |
214 | { | 256 | { |
@@ -223,20 +265,8 @@ int btrfs_find_ref_cluster(struct btrfs_trans_handle *trans, | |||
223 | node = rb_first(&delayed_refs->root); | 265 | node = rb_first(&delayed_refs->root); |
224 | } else { | 266 | } else { |
225 | ref = NULL; | 267 | ref = NULL; |
226 | find_ref_head(&delayed_refs->root, start, &ref); | 268 | find_ref_head(&delayed_refs->root, start + 1, &ref, 1); |
227 | if (ref) { | 269 | if (ref) { |
228 | struct btrfs_delayed_ref_node *tmp; | ||
229 | |||
230 | node = rb_prev(&ref->rb_node); | ||
231 | while (node) { | ||
232 | tmp = rb_entry(node, | ||
233 | struct btrfs_delayed_ref_node, | ||
234 | rb_node); | ||
235 | if (tmp->bytenr < start) | ||
236 | break; | ||
237 | ref = tmp; | ||
238 | node = rb_prev(&ref->rb_node); | ||
239 | } | ||
240 | node = &ref->rb_node; | 270 | node = &ref->rb_node; |
241 | } else | 271 | } else |
242 | node = rb_first(&delayed_refs->root); | 272 | node = rb_first(&delayed_refs->root); |
@@ -390,7 +420,8 @@ update_existing_head_ref(struct btrfs_delayed_ref_node *existing, | |||
390 | * this does all the dirty work in terms of maintaining the correct | 420 | * this does all the dirty work in terms of maintaining the correct |
391 | * overall modification count. | 421 | * overall modification count. |
392 | */ | 422 | */ |
393 | static noinline int add_delayed_ref_head(struct btrfs_trans_handle *trans, | 423 | static noinline int add_delayed_ref_head(struct btrfs_fs_info *fs_info, |
424 | struct btrfs_trans_handle *trans, | ||
394 | struct btrfs_delayed_ref_node *ref, | 425 | struct btrfs_delayed_ref_node *ref, |
395 | u64 bytenr, u64 num_bytes, | 426 | u64 bytenr, u64 num_bytes, |
396 | int action, int is_data) | 427 | int action, int is_data) |
@@ -437,6 +468,7 @@ static noinline int add_delayed_ref_head(struct btrfs_trans_handle *trans, | |||
437 | ref->action = 0; | 468 | ref->action = 0; |
438 | ref->is_head = 1; | 469 | ref->is_head = 1; |
439 | ref->in_tree = 1; | 470 | ref->in_tree = 1; |
471 | ref->seq = 0; | ||
440 | 472 | ||
441 | head_ref = btrfs_delayed_node_to_head(ref); | 473 | head_ref = btrfs_delayed_node_to_head(ref); |
442 | head_ref->must_insert_reserved = must_insert_reserved; | 474 | head_ref->must_insert_reserved = must_insert_reserved; |
@@ -468,14 +500,17 @@ static noinline int add_delayed_ref_head(struct btrfs_trans_handle *trans, | |||
468 | /* | 500 | /* |
469 | * helper to insert a delayed tree ref into the rbtree. | 501 | * helper to insert a delayed tree ref into the rbtree. |
470 | */ | 502 | */ |
471 | static noinline int add_delayed_tree_ref(struct btrfs_trans_handle *trans, | 503 | static noinline int add_delayed_tree_ref(struct btrfs_fs_info *fs_info, |
504 | struct btrfs_trans_handle *trans, | ||
472 | struct btrfs_delayed_ref_node *ref, | 505 | struct btrfs_delayed_ref_node *ref, |
473 | u64 bytenr, u64 num_bytes, u64 parent, | 506 | u64 bytenr, u64 num_bytes, u64 parent, |
474 | u64 ref_root, int level, int action) | 507 | u64 ref_root, int level, int action, |
508 | int for_cow) | ||
475 | { | 509 | { |
476 | struct btrfs_delayed_ref_node *existing; | 510 | struct btrfs_delayed_ref_node *existing; |
477 | struct btrfs_delayed_tree_ref *full_ref; | 511 | struct btrfs_delayed_tree_ref *full_ref; |
478 | struct btrfs_delayed_ref_root *delayed_refs; | 512 | struct btrfs_delayed_ref_root *delayed_refs; |
513 | u64 seq = 0; | ||
479 | 514 | ||
480 | if (action == BTRFS_ADD_DELAYED_EXTENT) | 515 | if (action == BTRFS_ADD_DELAYED_EXTENT) |
481 | action = BTRFS_ADD_DELAYED_REF; | 516 | action = BTRFS_ADD_DELAYED_REF; |
@@ -491,14 +526,17 @@ static noinline int add_delayed_tree_ref(struct btrfs_trans_handle *trans, | |||
491 | ref->is_head = 0; | 526 | ref->is_head = 0; |
492 | ref->in_tree = 1; | 527 | ref->in_tree = 1; |
493 | 528 | ||
529 | if (need_ref_seq(for_cow, ref_root)) | ||
530 | seq = inc_delayed_seq(delayed_refs); | ||
531 | ref->seq = seq; | ||
532 | |||
494 | full_ref = btrfs_delayed_node_to_tree_ref(ref); | 533 | full_ref = btrfs_delayed_node_to_tree_ref(ref); |
495 | if (parent) { | 534 | full_ref->parent = parent; |
496 | full_ref->parent = parent; | 535 | full_ref->root = ref_root; |
536 | if (parent) | ||
497 | ref->type = BTRFS_SHARED_BLOCK_REF_KEY; | 537 | ref->type = BTRFS_SHARED_BLOCK_REF_KEY; |
498 | } else { | 538 | else |
499 | full_ref->root = ref_root; | ||
500 | ref->type = BTRFS_TREE_BLOCK_REF_KEY; | 539 | ref->type = BTRFS_TREE_BLOCK_REF_KEY; |
501 | } | ||
502 | full_ref->level = level; | 540 | full_ref->level = level; |
503 | 541 | ||
504 | trace_btrfs_delayed_tree_ref(ref, full_ref, action); | 542 | trace_btrfs_delayed_tree_ref(ref, full_ref, action); |
@@ -522,15 +560,17 @@ static noinline int add_delayed_tree_ref(struct btrfs_trans_handle *trans, | |||
522 | /* | 560 | /* |
523 | * helper to insert a delayed data ref into the rbtree. | 561 | * helper to insert a delayed data ref into the rbtree. |
524 | */ | 562 | */ |
525 | static noinline int add_delayed_data_ref(struct btrfs_trans_handle *trans, | 563 | static noinline int add_delayed_data_ref(struct btrfs_fs_info *fs_info, |
564 | struct btrfs_trans_handle *trans, | ||
526 | struct btrfs_delayed_ref_node *ref, | 565 | struct btrfs_delayed_ref_node *ref, |
527 | u64 bytenr, u64 num_bytes, u64 parent, | 566 | u64 bytenr, u64 num_bytes, u64 parent, |
528 | u64 ref_root, u64 owner, u64 offset, | 567 | u64 ref_root, u64 owner, u64 offset, |
529 | int action) | 568 | int action, int for_cow) |
530 | { | 569 | { |
531 | struct btrfs_delayed_ref_node *existing; | 570 | struct btrfs_delayed_ref_node *existing; |
532 | struct btrfs_delayed_data_ref *full_ref; | 571 | struct btrfs_delayed_data_ref *full_ref; |
533 | struct btrfs_delayed_ref_root *delayed_refs; | 572 | struct btrfs_delayed_ref_root *delayed_refs; |
573 | u64 seq = 0; | ||
534 | 574 | ||
535 | if (action == BTRFS_ADD_DELAYED_EXTENT) | 575 | if (action == BTRFS_ADD_DELAYED_EXTENT) |
536 | action = BTRFS_ADD_DELAYED_REF; | 576 | action = BTRFS_ADD_DELAYED_REF; |
@@ -546,14 +586,18 @@ static noinline int add_delayed_data_ref(struct btrfs_trans_handle *trans, | |||
546 | ref->is_head = 0; | 586 | ref->is_head = 0; |
547 | ref->in_tree = 1; | 587 | ref->in_tree = 1; |
548 | 588 | ||
589 | if (need_ref_seq(for_cow, ref_root)) | ||
590 | seq = inc_delayed_seq(delayed_refs); | ||
591 | ref->seq = seq; | ||
592 | |||
549 | full_ref = btrfs_delayed_node_to_data_ref(ref); | 593 | full_ref = btrfs_delayed_node_to_data_ref(ref); |
550 | if (parent) { | 594 | full_ref->parent = parent; |
551 | full_ref->parent = parent; | 595 | full_ref->root = ref_root; |
596 | if (parent) | ||
552 | ref->type = BTRFS_SHARED_DATA_REF_KEY; | 597 | ref->type = BTRFS_SHARED_DATA_REF_KEY; |
553 | } else { | 598 | else |
554 | full_ref->root = ref_root; | ||
555 | ref->type = BTRFS_EXTENT_DATA_REF_KEY; | 599 | ref->type = BTRFS_EXTENT_DATA_REF_KEY; |
556 | } | 600 | |
557 | full_ref->objectid = owner; | 601 | full_ref->objectid = owner; |
558 | full_ref->offset = offset; | 602 | full_ref->offset = offset; |
559 | 603 | ||
@@ -580,10 +624,12 @@ static noinline int add_delayed_data_ref(struct btrfs_trans_handle *trans, | |||
580 | * to make sure the delayed ref is eventually processed before this | 624 | * to make sure the delayed ref is eventually processed before this |
581 | * transaction commits. | 625 | * transaction commits. |
582 | */ | 626 | */ |
583 | int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans, | 627 | int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info, |
628 | struct btrfs_trans_handle *trans, | ||
584 | u64 bytenr, u64 num_bytes, u64 parent, | 629 | u64 bytenr, u64 num_bytes, u64 parent, |
585 | u64 ref_root, int level, int action, | 630 | u64 ref_root, int level, int action, |
586 | struct btrfs_delayed_extent_op *extent_op) | 631 | struct btrfs_delayed_extent_op *extent_op, |
632 | int for_cow) | ||
587 | { | 633 | { |
588 | struct btrfs_delayed_tree_ref *ref; | 634 | struct btrfs_delayed_tree_ref *ref; |
589 | struct btrfs_delayed_ref_head *head_ref; | 635 | struct btrfs_delayed_ref_head *head_ref; |
@@ -610,13 +656,17 @@ int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans, | |||
610 | * insert both the head node and the new ref without dropping | 656 | * insert both the head node and the new ref without dropping |
611 | * the spin lock | 657 | * the spin lock |
612 | */ | 658 | */ |
613 | ret = add_delayed_ref_head(trans, &head_ref->node, bytenr, num_bytes, | 659 | ret = add_delayed_ref_head(fs_info, trans, &head_ref->node, bytenr, |
614 | action, 0); | 660 | num_bytes, action, 0); |
615 | BUG_ON(ret); | 661 | BUG_ON(ret); |
616 | 662 | ||
617 | ret = add_delayed_tree_ref(trans, &ref->node, bytenr, num_bytes, | 663 | ret = add_delayed_tree_ref(fs_info, trans, &ref->node, bytenr, |
618 | parent, ref_root, level, action); | 664 | num_bytes, parent, ref_root, level, action, |
665 | for_cow); | ||
619 | BUG_ON(ret); | 666 | BUG_ON(ret); |
667 | if (!need_ref_seq(for_cow, ref_root) && | ||
668 | waitqueue_active(&delayed_refs->seq_wait)) | ||
669 | wake_up(&delayed_refs->seq_wait); | ||
620 | spin_unlock(&delayed_refs->lock); | 670 | spin_unlock(&delayed_refs->lock); |
621 | return 0; | 671 | return 0; |
622 | } | 672 | } |
@@ -624,11 +674,13 @@ int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans, | |||
624 | /* | 674 | /* |
625 | * add a delayed data ref. it's similar to btrfs_add_delayed_tree_ref. | 675 | * add a delayed data ref. it's similar to btrfs_add_delayed_tree_ref. |
626 | */ | 676 | */ |
627 | int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans, | 677 | int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, |
678 | struct btrfs_trans_handle *trans, | ||
628 | u64 bytenr, u64 num_bytes, | 679 | u64 bytenr, u64 num_bytes, |
629 | u64 parent, u64 ref_root, | 680 | u64 parent, u64 ref_root, |
630 | u64 owner, u64 offset, int action, | 681 | u64 owner, u64 offset, int action, |
631 | struct btrfs_delayed_extent_op *extent_op) | 682 | struct btrfs_delayed_extent_op *extent_op, |
683 | int for_cow) | ||
632 | { | 684 | { |
633 | struct btrfs_delayed_data_ref *ref; | 685 | struct btrfs_delayed_data_ref *ref; |
634 | struct btrfs_delayed_ref_head *head_ref; | 686 | struct btrfs_delayed_ref_head *head_ref; |
@@ -655,18 +707,23 @@ int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans, | |||
655 | * insert both the head node and the new ref without dropping | 707 | * insert both the head node and the new ref without dropping |
656 | * the spin lock | 708 | * the spin lock |
657 | */ | 709 | */ |
658 | ret = add_delayed_ref_head(trans, &head_ref->node, bytenr, num_bytes, | 710 | ret = add_delayed_ref_head(fs_info, trans, &head_ref->node, bytenr, |
659 | action, 1); | 711 | num_bytes, action, 1); |
660 | BUG_ON(ret); | 712 | BUG_ON(ret); |
661 | 713 | ||
662 | ret = add_delayed_data_ref(trans, &ref->node, bytenr, num_bytes, | 714 | ret = add_delayed_data_ref(fs_info, trans, &ref->node, bytenr, |
663 | parent, ref_root, owner, offset, action); | 715 | num_bytes, parent, ref_root, owner, offset, |
716 | action, for_cow); | ||
664 | BUG_ON(ret); | 717 | BUG_ON(ret); |
718 | if (!need_ref_seq(for_cow, ref_root) && | ||
719 | waitqueue_active(&delayed_refs->seq_wait)) | ||
720 | wake_up(&delayed_refs->seq_wait); | ||
665 | spin_unlock(&delayed_refs->lock); | 721 | spin_unlock(&delayed_refs->lock); |
666 | return 0; | 722 | return 0; |
667 | } | 723 | } |
668 | 724 | ||
669 | int btrfs_add_delayed_extent_op(struct btrfs_trans_handle *trans, | 725 | int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, |
726 | struct btrfs_trans_handle *trans, | ||
670 | u64 bytenr, u64 num_bytes, | 727 | u64 bytenr, u64 num_bytes, |
671 | struct btrfs_delayed_extent_op *extent_op) | 728 | struct btrfs_delayed_extent_op *extent_op) |
672 | { | 729 | { |
@@ -683,11 +740,13 @@ int btrfs_add_delayed_extent_op(struct btrfs_trans_handle *trans, | |||
683 | delayed_refs = &trans->transaction->delayed_refs; | 740 | delayed_refs = &trans->transaction->delayed_refs; |
684 | spin_lock(&delayed_refs->lock); | 741 | spin_lock(&delayed_refs->lock); |
685 | 742 | ||
686 | ret = add_delayed_ref_head(trans, &head_ref->node, bytenr, | 743 | ret = add_delayed_ref_head(fs_info, trans, &head_ref->node, bytenr, |
687 | num_bytes, BTRFS_UPDATE_DELAYED_HEAD, | 744 | num_bytes, BTRFS_UPDATE_DELAYED_HEAD, |
688 | extent_op->is_data); | 745 | extent_op->is_data); |
689 | BUG_ON(ret); | 746 | BUG_ON(ret); |
690 | 747 | ||
748 | if (waitqueue_active(&delayed_refs->seq_wait)) | ||
749 | wake_up(&delayed_refs->seq_wait); | ||
691 | spin_unlock(&delayed_refs->lock); | 750 | spin_unlock(&delayed_refs->lock); |
692 | return 0; | 751 | return 0; |
693 | } | 752 | } |
@@ -704,7 +763,7 @@ btrfs_find_delayed_ref_head(struct btrfs_trans_handle *trans, u64 bytenr) | |||
704 | struct btrfs_delayed_ref_root *delayed_refs; | 763 | struct btrfs_delayed_ref_root *delayed_refs; |
705 | 764 | ||
706 | delayed_refs = &trans->transaction->delayed_refs; | 765 | delayed_refs = &trans->transaction->delayed_refs; |
707 | ref = find_ref_head(&delayed_refs->root, bytenr, NULL); | 766 | ref = find_ref_head(&delayed_refs->root, bytenr, NULL, 0); |
708 | if (ref) | 767 | if (ref) |
709 | return btrfs_delayed_node_to_head(ref); | 768 | return btrfs_delayed_node_to_head(ref); |
710 | return NULL; | 769 | return NULL; |
diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h index e287e3b0eab0..d8f244d94925 100644 --- a/fs/btrfs/delayed-ref.h +++ b/fs/btrfs/delayed-ref.h | |||
@@ -33,6 +33,9 @@ struct btrfs_delayed_ref_node { | |||
33 | /* the size of the extent */ | 33 | /* the size of the extent */ |
34 | u64 num_bytes; | 34 | u64 num_bytes; |
35 | 35 | ||
36 | /* seq number to keep track of insertion order */ | ||
37 | u64 seq; | ||
38 | |||
36 | /* ref count on this data structure */ | 39 | /* ref count on this data structure */ |
37 | atomic_t refs; | 40 | atomic_t refs; |
38 | 41 | ||
@@ -98,19 +101,15 @@ struct btrfs_delayed_ref_head { | |||
98 | 101 | ||
99 | struct btrfs_delayed_tree_ref { | 102 | struct btrfs_delayed_tree_ref { |
100 | struct btrfs_delayed_ref_node node; | 103 | struct btrfs_delayed_ref_node node; |
101 | union { | 104 | u64 root; |
102 | u64 root; | 105 | u64 parent; |
103 | u64 parent; | ||
104 | }; | ||
105 | int level; | 106 | int level; |
106 | }; | 107 | }; |
107 | 108 | ||
108 | struct btrfs_delayed_data_ref { | 109 | struct btrfs_delayed_data_ref { |
109 | struct btrfs_delayed_ref_node node; | 110 | struct btrfs_delayed_ref_node node; |
110 | union { | 111 | u64 root; |
111 | u64 root; | 112 | u64 parent; |
112 | u64 parent; | ||
113 | }; | ||
114 | u64 objectid; | 113 | u64 objectid; |
115 | u64 offset; | 114 | u64 offset; |
116 | }; | 115 | }; |
@@ -140,6 +139,26 @@ struct btrfs_delayed_ref_root { | |||
140 | int flushing; | 139 | int flushing; |
141 | 140 | ||
142 | u64 run_delayed_start; | 141 | u64 run_delayed_start; |
142 | |||
143 | /* | ||
144 | * seq number of delayed refs. We need to know if a backref was being | ||
145 | * added before the currently processed ref or afterwards. | ||
146 | */ | ||
147 | u64 seq; | ||
148 | |||
149 | /* | ||
150 | * seq_list holds a list of all seq numbers that are currently being | ||
151 | * added to the list. While walking backrefs (btrfs_find_all_roots, | ||
152 | * qgroups), which might take some time, no newer ref must be processed, | ||
153 | * as it might influence the outcome of the walk. | ||
154 | */ | ||
155 | struct list_head seq_head; | ||
156 | |||
157 | /* | ||
158 | * when the only refs we have in the list must not be processed, we want | ||
159 | * to wait for more refs to show up or for the end of backref walking. | ||
160 | */ | ||
161 | wait_queue_head_t seq_wait; | ||
143 | }; | 162 | }; |
144 | 163 | ||
145 | static inline void btrfs_put_delayed_ref(struct btrfs_delayed_ref_node *ref) | 164 | static inline void btrfs_put_delayed_ref(struct btrfs_delayed_ref_node *ref) |
@@ -151,16 +170,21 @@ static inline void btrfs_put_delayed_ref(struct btrfs_delayed_ref_node *ref) | |||
151 | } | 170 | } |
152 | } | 171 | } |
153 | 172 | ||
154 | int btrfs_add_delayed_tree_ref(struct btrfs_trans_handle *trans, | 173 | int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info, |
174 | struct btrfs_trans_handle *trans, | ||
155 | u64 bytenr, u64 num_bytes, u64 parent, | 175 | u64 bytenr, u64 num_bytes, u64 parent, |
156 | u64 ref_root, int level, int action, | 176 | u64 ref_root, int level, int action, |
157 | struct btrfs_delayed_extent_op *extent_op); | 177 | struct btrfs_delayed_extent_op *extent_op, |
158 | int btrfs_add_delayed_data_ref(struct btrfs_trans_handle *trans, | 178 | int for_cow); |
179 | int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info, | ||
180 | struct btrfs_trans_handle *trans, | ||
159 | u64 bytenr, u64 num_bytes, | 181 | u64 bytenr, u64 num_bytes, |
160 | u64 parent, u64 ref_root, | 182 | u64 parent, u64 ref_root, |
161 | u64 owner, u64 offset, int action, | 183 | u64 owner, u64 offset, int action, |
162 | struct btrfs_delayed_extent_op *extent_op); | 184 | struct btrfs_delayed_extent_op *extent_op, |
163 | int btrfs_add_delayed_extent_op(struct btrfs_trans_handle *trans, | 185 | int for_cow); |
186 | int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info, | ||
187 | struct btrfs_trans_handle *trans, | ||
164 | u64 bytenr, u64 num_bytes, | 188 | u64 bytenr, u64 num_bytes, |
165 | struct btrfs_delayed_extent_op *extent_op); | 189 | struct btrfs_delayed_extent_op *extent_op); |
166 | 190 | ||
@@ -170,6 +194,60 @@ int btrfs_delayed_ref_lock(struct btrfs_trans_handle *trans, | |||
170 | struct btrfs_delayed_ref_head *head); | 194 | struct btrfs_delayed_ref_head *head); |
171 | int btrfs_find_ref_cluster(struct btrfs_trans_handle *trans, | 195 | int btrfs_find_ref_cluster(struct btrfs_trans_handle *trans, |
172 | struct list_head *cluster, u64 search_start); | 196 | struct list_head *cluster, u64 search_start); |
197 | |||
198 | struct seq_list { | ||
199 | struct list_head list; | ||
200 | u64 seq; | ||
201 | }; | ||
202 | |||
203 | static inline u64 inc_delayed_seq(struct btrfs_delayed_ref_root *delayed_refs) | ||
204 | { | ||
205 | assert_spin_locked(&delayed_refs->lock); | ||
206 | ++delayed_refs->seq; | ||
207 | return delayed_refs->seq; | ||
208 | } | ||
209 | |||
210 | static inline void | ||
211 | btrfs_get_delayed_seq(struct btrfs_delayed_ref_root *delayed_refs, | ||
212 | struct seq_list *elem) | ||
213 | { | ||
214 | assert_spin_locked(&delayed_refs->lock); | ||
215 | elem->seq = delayed_refs->seq; | ||
216 | list_add_tail(&elem->list, &delayed_refs->seq_head); | ||
217 | } | ||
218 | |||
219 | static inline void | ||
220 | btrfs_put_delayed_seq(struct btrfs_delayed_ref_root *delayed_refs, | ||
221 | struct seq_list *elem) | ||
222 | { | ||
223 | spin_lock(&delayed_refs->lock); | ||
224 | list_del(&elem->list); | ||
225 | wake_up(&delayed_refs->seq_wait); | ||
226 | spin_unlock(&delayed_refs->lock); | ||
227 | } | ||
228 | |||
229 | int btrfs_check_delayed_seq(struct btrfs_delayed_ref_root *delayed_refs, | ||
230 | u64 seq); | ||
231 | |||
232 | /* | ||
233 | * delayed refs with a ref_seq > 0 must be held back during backref walking. | ||
234 | * this only applies to items in one of the fs-trees. for_cow items never need | ||
235 | * to be held back, so they won't get a ref_seq number. | ||
236 | */ | ||
237 | static inline int need_ref_seq(int for_cow, u64 rootid) | ||
238 | { | ||
239 | if (for_cow) | ||
240 | return 0; | ||
241 | |||
242 | if (rootid == BTRFS_FS_TREE_OBJECTID) | ||
243 | return 1; | ||
244 | |||
245 | if ((s64)rootid >= (s64)BTRFS_FIRST_FREE_OBJECTID) | ||
246 | return 1; | ||
247 | |||
248 | return 0; | ||
249 | } | ||
250 | |||
173 | /* | 251 | /* |
174 | * a node might live in a head or a regular ref, this lets you | 252 | * a node might live in a head or a regular ref, this lets you |
175 | * test for the proper type to use. | 253 | * test for the proper type to use. |
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index e5167219c266..9be97716c5e0 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c | |||
@@ -1243,7 +1243,8 @@ static struct btrfs_root *alloc_log_tree(struct btrfs_trans_handle *trans, | |||
1243 | root->ref_cows = 0; | 1243 | root->ref_cows = 0; |
1244 | 1244 | ||
1245 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0, | 1245 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, 0, |
1246 | BTRFS_TREE_LOG_OBJECTID, NULL, 0, 0, 0); | 1246 | BTRFS_TREE_LOG_OBJECTID, NULL, |
1247 | 0, 0, 0, 0); | ||
1247 | if (IS_ERR(leaf)) { | 1248 | if (IS_ERR(leaf)) { |
1248 | kfree(root); | 1249 | kfree(root); |
1249 | return ERR_CAST(leaf); | 1250 | return ERR_CAST(leaf); |
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c index 1c1cf216be80..a44072a692ab 100644 --- a/fs/btrfs/extent-tree.c +++ b/fs/btrfs/extent-tree.c | |||
@@ -1871,20 +1871,24 @@ static int btrfs_discard_extent(struct btrfs_root *root, u64 bytenr, | |||
1871 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, | 1871 | int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans, |
1872 | struct btrfs_root *root, | 1872 | struct btrfs_root *root, |
1873 | u64 bytenr, u64 num_bytes, u64 parent, | 1873 | u64 bytenr, u64 num_bytes, u64 parent, |
1874 | u64 root_objectid, u64 owner, u64 offset) | 1874 | u64 root_objectid, u64 owner, u64 offset, int for_cow) |
1875 | { | 1875 | { |
1876 | int ret; | 1876 | int ret; |
1877 | struct btrfs_fs_info *fs_info = root->fs_info; | ||
1878 | |||
1877 | BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID && | 1879 | BUG_ON(owner < BTRFS_FIRST_FREE_OBJECTID && |
1878 | root_objectid == BTRFS_TREE_LOG_OBJECTID); | 1880 | root_objectid == BTRFS_TREE_LOG_OBJECTID); |
1879 | 1881 | ||
1880 | if (owner < BTRFS_FIRST_FREE_OBJECTID) { | 1882 | if (owner < BTRFS_FIRST_FREE_OBJECTID) { |
1881 | ret = btrfs_add_delayed_tree_ref(trans, bytenr, num_bytes, | 1883 | ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr, |
1884 | num_bytes, | ||
1882 | parent, root_objectid, (int)owner, | 1885 | parent, root_objectid, (int)owner, |
1883 | BTRFS_ADD_DELAYED_REF, NULL); | 1886 | BTRFS_ADD_DELAYED_REF, NULL, for_cow); |
1884 | } else { | 1887 | } else { |
1885 | ret = btrfs_add_delayed_data_ref(trans, bytenr, num_bytes, | 1888 | ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr, |
1889 | num_bytes, | ||
1886 | parent, root_objectid, owner, offset, | 1890 | parent, root_objectid, owner, offset, |
1887 | BTRFS_ADD_DELAYED_REF, NULL); | 1891 | BTRFS_ADD_DELAYED_REF, NULL, for_cow); |
1888 | } | 1892 | } |
1889 | return ret; | 1893 | return ret; |
1890 | } | 1894 | } |
@@ -2232,6 +2236,28 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans, | |||
2232 | } | 2236 | } |
2233 | 2237 | ||
2234 | /* | 2238 | /* |
2239 | * locked_ref is the head node, so we have to go one | ||
2240 | * node back for any delayed ref updates | ||
2241 | */ | ||
2242 | ref = select_delayed_ref(locked_ref); | ||
2243 | |||
2244 | if (ref && ref->seq && | ||
2245 | btrfs_check_delayed_seq(delayed_refs, ref->seq)) { | ||
2246 | /* | ||
2247 | * there are still refs with lower seq numbers in the | ||
2248 | * process of being added. Don't run this ref yet. | ||
2249 | */ | ||
2250 | list_del_init(&locked_ref->cluster); | ||
2251 | mutex_unlock(&locked_ref->mutex); | ||
2252 | locked_ref = NULL; | ||
2253 | delayed_refs->num_heads_ready++; | ||
2254 | spin_unlock(&delayed_refs->lock); | ||
2255 | cond_resched(); | ||
2256 | spin_lock(&delayed_refs->lock); | ||
2257 | continue; | ||
2258 | } | ||
2259 | |||
2260 | /* | ||
2235 | * record the must insert reserved flag before we | 2261 | * record the must insert reserved flag before we |
2236 | * drop the spin lock. | 2262 | * drop the spin lock. |
2237 | */ | 2263 | */ |
@@ -2241,11 +2267,6 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans, | |||
2241 | extent_op = locked_ref->extent_op; | 2267 | extent_op = locked_ref->extent_op; |
2242 | locked_ref->extent_op = NULL; | 2268 | locked_ref->extent_op = NULL; |
2243 | 2269 | ||
2244 | /* | ||
2245 | * locked_ref is the head node, so we have to go one | ||
2246 | * node back for any delayed ref updates | ||
2247 | */ | ||
2248 | ref = select_delayed_ref(locked_ref); | ||
2249 | if (!ref) { | 2270 | if (!ref) { |
2250 | /* All delayed refs have been processed, Go ahead | 2271 | /* All delayed refs have been processed, Go ahead |
2251 | * and send the head node to run_one_delayed_ref, | 2272 | * and send the head node to run_one_delayed_ref, |
@@ -2276,7 +2297,12 @@ static noinline int run_clustered_refs(struct btrfs_trans_handle *trans, | |||
2276 | ref->in_tree = 0; | 2297 | ref->in_tree = 0; |
2277 | rb_erase(&ref->rb_node, &delayed_refs->root); | 2298 | rb_erase(&ref->rb_node, &delayed_refs->root); |
2278 | delayed_refs->num_entries--; | 2299 | delayed_refs->num_entries--; |
2279 | 2300 | /* | |
2301 | * we modified num_entries, but as we're currently running | ||
2302 | * delayed refs, skip | ||
2303 | * wake_up(&delayed_refs->seq_wait); | ||
2304 | * here. | ||
2305 | */ | ||
2280 | spin_unlock(&delayed_refs->lock); | 2306 | spin_unlock(&delayed_refs->lock); |
2281 | 2307 | ||
2282 | ret = run_one_delayed_ref(trans, root, ref, extent_op, | 2308 | ret = run_one_delayed_ref(trans, root, ref, extent_op, |
@@ -2297,6 +2323,23 @@ next: | |||
2297 | return count; | 2323 | return count; |
2298 | } | 2324 | } |
2299 | 2325 | ||
2326 | |||
2327 | static void wait_for_more_refs(struct btrfs_delayed_ref_root *delayed_refs, | ||
2328 | unsigned long num_refs) | ||
2329 | { | ||
2330 | struct list_head *first_seq = delayed_refs->seq_head.next; | ||
2331 | |||
2332 | spin_unlock(&delayed_refs->lock); | ||
2333 | pr_debug("waiting for more refs (num %ld, first %p)\n", | ||
2334 | num_refs, first_seq); | ||
2335 | wait_event(delayed_refs->seq_wait, | ||
2336 | num_refs != delayed_refs->num_entries || | ||
2337 | delayed_refs->seq_head.next != first_seq); | ||
2338 | pr_debug("done waiting for more refs (num %ld, first %p)\n", | ||
2339 | delayed_refs->num_entries, delayed_refs->seq_head.next); | ||
2340 | spin_lock(&delayed_refs->lock); | ||
2341 | } | ||
2342 | |||
2300 | /* | 2343 | /* |
2301 | * this starts processing the delayed reference count updates and | 2344 | * this starts processing the delayed reference count updates and |
2302 | * extent insertions we have queued up so far. count can be | 2345 | * extent insertions we have queued up so far. count can be |
@@ -2312,8 +2355,11 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, | |||
2312 | struct btrfs_delayed_ref_node *ref; | 2355 | struct btrfs_delayed_ref_node *ref; |
2313 | struct list_head cluster; | 2356 | struct list_head cluster; |
2314 | int ret; | 2357 | int ret; |
2358 | u64 delayed_start; | ||
2315 | int run_all = count == (unsigned long)-1; | 2359 | int run_all = count == (unsigned long)-1; |
2316 | int run_most = 0; | 2360 | int run_most = 0; |
2361 | unsigned long num_refs = 0; | ||
2362 | int consider_waiting; | ||
2317 | 2363 | ||
2318 | if (root == root->fs_info->extent_root) | 2364 | if (root == root->fs_info->extent_root) |
2319 | root = root->fs_info->tree_root; | 2365 | root = root->fs_info->tree_root; |
@@ -2325,6 +2371,7 @@ int btrfs_run_delayed_refs(struct btrfs_trans_handle *trans, | |||
2325 | delayed_refs = &trans->transaction->delayed_refs; | 2371 | delayed_refs = &trans->transaction->delayed_refs; |
2326 | INIT_LIST_HEAD(&cluster); | 2372 | INIT_LIST_HEAD(&cluster); |
2327 | again: | 2373 | again: |
2374 | consider_waiting = 0; | ||
2328 | spin_lock(&delayed_refs->lock); | 2375 | spin_lock(&delayed_refs->lock); |
2329 | if (count == 0) { | 2376 | if (count == 0) { |
2330 | count = delayed_refs->num_entries * 2; | 2377 | count = delayed_refs->num_entries * 2; |
@@ -2341,11 +2388,35 @@ again: | |||
2341 | * of refs to process starting at the first one we are able to | 2388 | * of refs to process starting at the first one we are able to |
2342 | * lock | 2389 | * lock |
2343 | */ | 2390 | */ |
2391 | delayed_start = delayed_refs->run_delayed_start; | ||
2344 | ret = btrfs_find_ref_cluster(trans, &cluster, | 2392 | ret = btrfs_find_ref_cluster(trans, &cluster, |
2345 | delayed_refs->run_delayed_start); | 2393 | delayed_refs->run_delayed_start); |
2346 | if (ret) | 2394 | if (ret) |
2347 | break; | 2395 | break; |
2348 | 2396 | ||
2397 | if (delayed_start >= delayed_refs->run_delayed_start) { | ||
2398 | if (consider_waiting == 0) { | ||
2399 | /* | ||
2400 | * btrfs_find_ref_cluster looped. let's do one | ||
2401 | * more cycle. if we don't run any delayed ref | ||
2402 | * during that cycle (because we can't because | ||
2403 | * all of them are blocked) and if the number of | ||
2404 | * refs doesn't change, we avoid busy waiting. | ||
2405 | */ | ||
2406 | consider_waiting = 1; | ||
2407 | num_refs = delayed_refs->num_entries; | ||
2408 | } else { | ||
2409 | wait_for_more_refs(delayed_refs, num_refs); | ||
2410 | /* | ||
2411 | * after waiting, things have changed. we | ||
2412 | * dropped the lock and someone else might have | ||
2413 | * run some refs, built new clusters and so on. | ||
2414 | * therefore, we restart staleness detection. | ||
2415 | */ | ||
2416 | consider_waiting = 0; | ||
2417 | } | ||
2418 | } | ||
2419 | |||
2349 | ret = run_clustered_refs(trans, root, &cluster); | 2420 | ret = run_clustered_refs(trans, root, &cluster); |
2350 | BUG_ON(ret < 0); | 2421 | BUG_ON(ret < 0); |
2351 | 2422 | ||
@@ -2353,6 +2424,11 @@ again: | |||
2353 | 2424 | ||
2354 | if (count == 0) | 2425 | if (count == 0) |
2355 | break; | 2426 | break; |
2427 | |||
2428 | if (ret || delayed_refs->run_delayed_start == 0) { | ||
2429 | /* refs were run, let's reset staleness detection */ | ||
2430 | consider_waiting = 0; | ||
2431 | } | ||
2356 | } | 2432 | } |
2357 | 2433 | ||
2358 | if (run_all) { | 2434 | if (run_all) { |
@@ -2410,7 +2486,8 @@ int btrfs_set_disk_extent_flags(struct btrfs_trans_handle *trans, | |||
2410 | extent_op->update_key = 0; | 2486 | extent_op->update_key = 0; |
2411 | extent_op->is_data = is_data ? 1 : 0; | 2487 | extent_op->is_data = is_data ? 1 : 0; |
2412 | 2488 | ||
2413 | ret = btrfs_add_delayed_extent_op(trans, bytenr, num_bytes, extent_op); | 2489 | ret = btrfs_add_delayed_extent_op(root->fs_info, trans, bytenr, |
2490 | num_bytes, extent_op); | ||
2414 | if (ret) | 2491 | if (ret) |
2415 | kfree(extent_op); | 2492 | kfree(extent_op); |
2416 | return ret; | 2493 | return ret; |
@@ -2595,7 +2672,7 @@ out: | |||
2595 | static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, | 2672 | static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, |
2596 | struct btrfs_root *root, | 2673 | struct btrfs_root *root, |
2597 | struct extent_buffer *buf, | 2674 | struct extent_buffer *buf, |
2598 | int full_backref, int inc) | 2675 | int full_backref, int inc, int for_cow) |
2599 | { | 2676 | { |
2600 | u64 bytenr; | 2677 | u64 bytenr; |
2601 | u64 num_bytes; | 2678 | u64 num_bytes; |
@@ -2608,7 +2685,7 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, | |||
2608 | int level; | 2685 | int level; |
2609 | int ret = 0; | 2686 | int ret = 0; |
2610 | int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *, | 2687 | int (*process_func)(struct btrfs_trans_handle *, struct btrfs_root *, |
2611 | u64, u64, u64, u64, u64, u64); | 2688 | u64, u64, u64, u64, u64, u64, int); |
2612 | 2689 | ||
2613 | ref_root = btrfs_header_owner(buf); | 2690 | ref_root = btrfs_header_owner(buf); |
2614 | nritems = btrfs_header_nritems(buf); | 2691 | nritems = btrfs_header_nritems(buf); |
@@ -2645,14 +2722,15 @@ static int __btrfs_mod_ref(struct btrfs_trans_handle *trans, | |||
2645 | key.offset -= btrfs_file_extent_offset(buf, fi); | 2722 | key.offset -= btrfs_file_extent_offset(buf, fi); |
2646 | ret = process_func(trans, root, bytenr, num_bytes, | 2723 | ret = process_func(trans, root, bytenr, num_bytes, |
2647 | parent, ref_root, key.objectid, | 2724 | parent, ref_root, key.objectid, |
2648 | key.offset); | 2725 | key.offset, for_cow); |
2649 | if (ret) | 2726 | if (ret) |
2650 | goto fail; | 2727 | goto fail; |
2651 | } else { | 2728 | } else { |
2652 | bytenr = btrfs_node_blockptr(buf, i); | 2729 | bytenr = btrfs_node_blockptr(buf, i); |
2653 | num_bytes = btrfs_level_size(root, level - 1); | 2730 | num_bytes = btrfs_level_size(root, level - 1); |
2654 | ret = process_func(trans, root, bytenr, num_bytes, | 2731 | ret = process_func(trans, root, bytenr, num_bytes, |
2655 | parent, ref_root, level - 1, 0); | 2732 | parent, ref_root, level - 1, 0, |
2733 | for_cow); | ||
2656 | if (ret) | 2734 | if (ret) |
2657 | goto fail; | 2735 | goto fail; |
2658 | } | 2736 | } |
@@ -2664,15 +2742,15 @@ fail: | |||
2664 | } | 2742 | } |
2665 | 2743 | ||
2666 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 2744 | int btrfs_inc_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
2667 | struct extent_buffer *buf, int full_backref) | 2745 | struct extent_buffer *buf, int full_backref, int for_cow) |
2668 | { | 2746 | { |
2669 | return __btrfs_mod_ref(trans, root, buf, full_backref, 1); | 2747 | return __btrfs_mod_ref(trans, root, buf, full_backref, 1, for_cow); |
2670 | } | 2748 | } |
2671 | 2749 | ||
2672 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, | 2750 | int btrfs_dec_ref(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
2673 | struct extent_buffer *buf, int full_backref) | 2751 | struct extent_buffer *buf, int full_backref, int for_cow) |
2674 | { | 2752 | { |
2675 | return __btrfs_mod_ref(trans, root, buf, full_backref, 0); | 2753 | return __btrfs_mod_ref(trans, root, buf, full_backref, 0, for_cow); |
2676 | } | 2754 | } |
2677 | 2755 | ||
2678 | static int write_one_cache_group(struct btrfs_trans_handle *trans, | 2756 | static int write_one_cache_group(struct btrfs_trans_handle *trans, |
@@ -4954,6 +5032,8 @@ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans, | |||
4954 | rb_erase(&head->node.rb_node, &delayed_refs->root); | 5032 | rb_erase(&head->node.rb_node, &delayed_refs->root); |
4955 | 5033 | ||
4956 | delayed_refs->num_entries--; | 5034 | delayed_refs->num_entries--; |
5035 | if (waitqueue_active(&delayed_refs->seq_wait)) | ||
5036 | wake_up(&delayed_refs->seq_wait); | ||
4957 | 5037 | ||
4958 | /* | 5038 | /* |
4959 | * we don't take a ref on the node because we're removing it from the | 5039 | * we don't take a ref on the node because we're removing it from the |
@@ -4981,16 +5061,17 @@ out: | |||
4981 | void btrfs_free_tree_block(struct btrfs_trans_handle *trans, | 5061 | void btrfs_free_tree_block(struct btrfs_trans_handle *trans, |
4982 | struct btrfs_root *root, | 5062 | struct btrfs_root *root, |
4983 | struct extent_buffer *buf, | 5063 | struct extent_buffer *buf, |
4984 | u64 parent, int last_ref) | 5064 | u64 parent, int last_ref, int for_cow) |
4985 | { | 5065 | { |
4986 | struct btrfs_block_group_cache *cache = NULL; | 5066 | struct btrfs_block_group_cache *cache = NULL; |
4987 | int ret; | 5067 | int ret; |
4988 | 5068 | ||
4989 | if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { | 5069 | if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) { |
4990 | ret = btrfs_add_delayed_tree_ref(trans, buf->start, buf->len, | 5070 | ret = btrfs_add_delayed_tree_ref(root->fs_info, trans, |
4991 | parent, root->root_key.objectid, | 5071 | buf->start, buf->len, |
4992 | btrfs_header_level(buf), | 5072 | parent, root->root_key.objectid, |
4993 | BTRFS_DROP_DELAYED_REF, NULL); | 5073 | btrfs_header_level(buf), |
5074 | BTRFS_DROP_DELAYED_REF, NULL, for_cow); | ||
4994 | BUG_ON(ret); | 5075 | BUG_ON(ret); |
4995 | } | 5076 | } |
4996 | 5077 | ||
@@ -5025,12 +5106,12 @@ out: | |||
5025 | btrfs_put_block_group(cache); | 5106 | btrfs_put_block_group(cache); |
5026 | } | 5107 | } |
5027 | 5108 | ||
5028 | int btrfs_free_extent(struct btrfs_trans_handle *trans, | 5109 | int btrfs_free_extent(struct btrfs_trans_handle *trans, struct btrfs_root *root, |
5029 | struct btrfs_root *root, | 5110 | u64 bytenr, u64 num_bytes, u64 parent, u64 root_objectid, |
5030 | u64 bytenr, u64 num_bytes, u64 parent, | 5111 | u64 owner, u64 offset, int for_cow) |
5031 | u64 root_objectid, u64 owner, u64 offset) | ||
5032 | { | 5112 | { |
5033 | int ret; | 5113 | int ret; |
5114 | struct btrfs_fs_info *fs_info = root->fs_info; | ||
5034 | 5115 | ||
5035 | /* | 5116 | /* |
5036 | * tree log blocks never actually go into the extent allocation | 5117 | * tree log blocks never actually go into the extent allocation |
@@ -5042,14 +5123,17 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, | |||
5042 | btrfs_pin_extent(root, bytenr, num_bytes, 1); | 5123 | btrfs_pin_extent(root, bytenr, num_bytes, 1); |
5043 | ret = 0; | 5124 | ret = 0; |
5044 | } else if (owner < BTRFS_FIRST_FREE_OBJECTID) { | 5125 | } else if (owner < BTRFS_FIRST_FREE_OBJECTID) { |
5045 | ret = btrfs_add_delayed_tree_ref(trans, bytenr, num_bytes, | 5126 | ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr, |
5127 | num_bytes, | ||
5046 | parent, root_objectid, (int)owner, | 5128 | parent, root_objectid, (int)owner, |
5047 | BTRFS_DROP_DELAYED_REF, NULL); | 5129 | BTRFS_DROP_DELAYED_REF, NULL, for_cow); |
5048 | BUG_ON(ret); | 5130 | BUG_ON(ret); |
5049 | } else { | 5131 | } else { |
5050 | ret = btrfs_add_delayed_data_ref(trans, bytenr, num_bytes, | 5132 | ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr, |
5051 | parent, root_objectid, owner, | 5133 | num_bytes, |
5052 | offset, BTRFS_DROP_DELAYED_REF, NULL); | 5134 | parent, root_objectid, owner, |
5135 | offset, BTRFS_DROP_DELAYED_REF, | ||
5136 | NULL, for_cow); | ||
5053 | BUG_ON(ret); | 5137 | BUG_ON(ret); |
5054 | } | 5138 | } |
5055 | return ret; | 5139 | return ret; |
@@ -5877,9 +5961,10 @@ int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans, | |||
5877 | 5961 | ||
5878 | BUG_ON(root_objectid == BTRFS_TREE_LOG_OBJECTID); | 5962 | BUG_ON(root_objectid == BTRFS_TREE_LOG_OBJECTID); |
5879 | 5963 | ||
5880 | ret = btrfs_add_delayed_data_ref(trans, ins->objectid, ins->offset, | 5964 | ret = btrfs_add_delayed_data_ref(root->fs_info, trans, ins->objectid, |
5881 | 0, root_objectid, owner, offset, | 5965 | ins->offset, 0, |
5882 | BTRFS_ADD_DELAYED_EXTENT, NULL); | 5966 | root_objectid, owner, offset, |
5967 | BTRFS_ADD_DELAYED_EXTENT, NULL, 0); | ||
5883 | return ret; | 5968 | return ret; |
5884 | } | 5969 | } |
5885 | 5970 | ||
@@ -6049,7 +6134,7 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
6049 | struct btrfs_root *root, u32 blocksize, | 6134 | struct btrfs_root *root, u32 blocksize, |
6050 | u64 parent, u64 root_objectid, | 6135 | u64 parent, u64 root_objectid, |
6051 | struct btrfs_disk_key *key, int level, | 6136 | struct btrfs_disk_key *key, int level, |
6052 | u64 hint, u64 empty_size) | 6137 | u64 hint, u64 empty_size, int for_cow) |
6053 | { | 6138 | { |
6054 | struct btrfs_key ins; | 6139 | struct btrfs_key ins; |
6055 | struct btrfs_block_rsv *block_rsv; | 6140 | struct btrfs_block_rsv *block_rsv; |
@@ -6093,10 +6178,11 @@ struct extent_buffer *btrfs_alloc_free_block(struct btrfs_trans_handle *trans, | |||
6093 | extent_op->update_flags = 1; | 6178 | extent_op->update_flags = 1; |
6094 | extent_op->is_data = 0; | 6179 | extent_op->is_data = 0; |
6095 | 6180 | ||
6096 | ret = btrfs_add_delayed_tree_ref(trans, ins.objectid, | 6181 | ret = btrfs_add_delayed_tree_ref(root->fs_info, trans, |
6182 | ins.objectid, | ||
6097 | ins.offset, parent, root_objectid, | 6183 | ins.offset, parent, root_objectid, |
6098 | level, BTRFS_ADD_DELAYED_EXTENT, | 6184 | level, BTRFS_ADD_DELAYED_EXTENT, |
6099 | extent_op); | 6185 | extent_op, for_cow); |
6100 | BUG_ON(ret); | 6186 | BUG_ON(ret); |
6101 | } | 6187 | } |
6102 | return buf; | 6188 | return buf; |
@@ -6113,6 +6199,7 @@ struct walk_control { | |||
6113 | int keep_locks; | 6199 | int keep_locks; |
6114 | int reada_slot; | 6200 | int reada_slot; |
6115 | int reada_count; | 6201 | int reada_count; |
6202 | int for_reloc; | ||
6116 | }; | 6203 | }; |
6117 | 6204 | ||
6118 | #define DROP_REFERENCE 1 | 6205 | #define DROP_REFERENCE 1 |
@@ -6251,9 +6338,9 @@ static noinline int walk_down_proc(struct btrfs_trans_handle *trans, | |||
6251 | /* wc->stage == UPDATE_BACKREF */ | 6338 | /* wc->stage == UPDATE_BACKREF */ |
6252 | if (!(wc->flags[level] & flag)) { | 6339 | if (!(wc->flags[level] & flag)) { |
6253 | BUG_ON(!path->locks[level]); | 6340 | BUG_ON(!path->locks[level]); |
6254 | ret = btrfs_inc_ref(trans, root, eb, 1); | 6341 | ret = btrfs_inc_ref(trans, root, eb, 1, wc->for_reloc); |
6255 | BUG_ON(ret); | 6342 | BUG_ON(ret); |
6256 | ret = btrfs_dec_ref(trans, root, eb, 0); | 6343 | ret = btrfs_dec_ref(trans, root, eb, 0, wc->for_reloc); |
6257 | BUG_ON(ret); | 6344 | BUG_ON(ret); |
6258 | ret = btrfs_set_disk_extent_flags(trans, root, eb->start, | 6345 | ret = btrfs_set_disk_extent_flags(trans, root, eb->start, |
6259 | eb->len, flag, 0); | 6346 | eb->len, flag, 0); |
@@ -6397,7 +6484,7 @@ skip: | |||
6397 | } | 6484 | } |
6398 | 6485 | ||
6399 | ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent, | 6486 | ret = btrfs_free_extent(trans, root, bytenr, blocksize, parent, |
6400 | root->root_key.objectid, level - 1, 0); | 6487 | root->root_key.objectid, level - 1, 0, 0); |
6401 | BUG_ON(ret); | 6488 | BUG_ON(ret); |
6402 | } | 6489 | } |
6403 | btrfs_tree_unlock(next); | 6490 | btrfs_tree_unlock(next); |
@@ -6471,9 +6558,11 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, | |||
6471 | if (wc->refs[level] == 1) { | 6558 | if (wc->refs[level] == 1) { |
6472 | if (level == 0) { | 6559 | if (level == 0) { |
6473 | if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) | 6560 | if (wc->flags[level] & BTRFS_BLOCK_FLAG_FULL_BACKREF) |
6474 | ret = btrfs_dec_ref(trans, root, eb, 1); | 6561 | ret = btrfs_dec_ref(trans, root, eb, 1, |
6562 | wc->for_reloc); | ||
6475 | else | 6563 | else |
6476 | ret = btrfs_dec_ref(trans, root, eb, 0); | 6564 | ret = btrfs_dec_ref(trans, root, eb, 0, |
6565 | wc->for_reloc); | ||
6477 | BUG_ON(ret); | 6566 | BUG_ON(ret); |
6478 | } | 6567 | } |
6479 | /* make block locked assertion in clean_tree_block happy */ | 6568 | /* make block locked assertion in clean_tree_block happy */ |
@@ -6500,7 +6589,7 @@ static noinline int walk_up_proc(struct btrfs_trans_handle *trans, | |||
6500 | btrfs_header_owner(path->nodes[level + 1])); | 6589 | btrfs_header_owner(path->nodes[level + 1])); |
6501 | } | 6590 | } |
6502 | 6591 | ||
6503 | btrfs_free_tree_block(trans, root, eb, parent, wc->refs[level] == 1); | 6592 | btrfs_free_tree_block(trans, root, eb, parent, wc->refs[level] == 1, 0); |
6504 | out: | 6593 | out: |
6505 | wc->refs[level] = 0; | 6594 | wc->refs[level] = 0; |
6506 | wc->flags[level] = 0; | 6595 | wc->flags[level] = 0; |
@@ -6584,7 +6673,8 @@ static noinline int walk_up_tree(struct btrfs_trans_handle *trans, | |||
6584 | * blocks are properly updated. | 6673 | * blocks are properly updated. |
6585 | */ | 6674 | */ |
6586 | void btrfs_drop_snapshot(struct btrfs_root *root, | 6675 | void btrfs_drop_snapshot(struct btrfs_root *root, |
6587 | struct btrfs_block_rsv *block_rsv, int update_ref) | 6676 | struct btrfs_block_rsv *block_rsv, int update_ref, |
6677 | int for_reloc) | ||
6588 | { | 6678 | { |
6589 | struct btrfs_path *path; | 6679 | struct btrfs_path *path; |
6590 | struct btrfs_trans_handle *trans; | 6680 | struct btrfs_trans_handle *trans; |
@@ -6672,6 +6762,7 @@ void btrfs_drop_snapshot(struct btrfs_root *root, | |||
6672 | wc->stage = DROP_REFERENCE; | 6762 | wc->stage = DROP_REFERENCE; |
6673 | wc->update_ref = update_ref; | 6763 | wc->update_ref = update_ref; |
6674 | wc->keep_locks = 0; | 6764 | wc->keep_locks = 0; |
6765 | wc->for_reloc = for_reloc; | ||
6675 | wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root); | 6766 | wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root); |
6676 | 6767 | ||
6677 | while (1) { | 6768 | while (1) { |
@@ -6756,6 +6847,7 @@ out: | |||
6756 | * drop subtree rooted at tree block 'node'. | 6847 | * drop subtree rooted at tree block 'node'. |
6757 | * | 6848 | * |
6758 | * NOTE: this function will unlock and release tree block 'node' | 6849 | * NOTE: this function will unlock and release tree block 'node' |
6850 | * only used by relocation code | ||
6759 | */ | 6851 | */ |
6760 | int btrfs_drop_subtree(struct btrfs_trans_handle *trans, | 6852 | int btrfs_drop_subtree(struct btrfs_trans_handle *trans, |
6761 | struct btrfs_root *root, | 6853 | struct btrfs_root *root, |
@@ -6800,6 +6892,7 @@ int btrfs_drop_subtree(struct btrfs_trans_handle *trans, | |||
6800 | wc->stage = DROP_REFERENCE; | 6892 | wc->stage = DROP_REFERENCE; |
6801 | wc->update_ref = 0; | 6893 | wc->update_ref = 0; |
6802 | wc->keep_locks = 1; | 6894 | wc->keep_locks = 1; |
6895 | wc->for_reloc = 1; | ||
6803 | wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root); | 6896 | wc->reada_count = BTRFS_NODEPTRS_PER_BLOCK(root); |
6804 | 6897 | ||
6805 | while (1) { | 6898 | while (1) { |
diff --git a/fs/btrfs/extent_io.c b/fs/btrfs/extent_io.c index 49f3c9dc09f4..3622cc22ff91 100644 --- a/fs/btrfs/extent_io.c +++ b/fs/btrfs/extent_io.c | |||
@@ -3579,6 +3579,7 @@ static struct extent_buffer *__alloc_extent_buffer(struct extent_io_tree *tree, | |||
3579 | atomic_set(&eb->blocking_writers, 0); | 3579 | atomic_set(&eb->blocking_writers, 0); |
3580 | atomic_set(&eb->spinning_readers, 0); | 3580 | atomic_set(&eb->spinning_readers, 0); |
3581 | atomic_set(&eb->spinning_writers, 0); | 3581 | atomic_set(&eb->spinning_writers, 0); |
3582 | eb->lock_nested = 0; | ||
3582 | init_waitqueue_head(&eb->write_lock_wq); | 3583 | init_waitqueue_head(&eb->write_lock_wq); |
3583 | init_waitqueue_head(&eb->read_lock_wq); | 3584 | init_waitqueue_head(&eb->read_lock_wq); |
3584 | 3585 | ||
diff --git a/fs/btrfs/extent_io.h b/fs/btrfs/extent_io.h index 7604c3001322..bc6a042cb6fc 100644 --- a/fs/btrfs/extent_io.h +++ b/fs/btrfs/extent_io.h | |||
@@ -129,6 +129,7 @@ struct extent_buffer { | |||
129 | struct list_head leak_list; | 129 | struct list_head leak_list; |
130 | struct rcu_head rcu_head; | 130 | struct rcu_head rcu_head; |
131 | atomic_t refs; | 131 | atomic_t refs; |
132 | pid_t lock_owner; | ||
132 | 133 | ||
133 | /* count of read lock holders on the extent buffer */ | 134 | /* count of read lock holders on the extent buffer */ |
134 | atomic_t write_locks; | 135 | atomic_t write_locks; |
@@ -137,6 +138,7 @@ struct extent_buffer { | |||
137 | atomic_t blocking_readers; | 138 | atomic_t blocking_readers; |
138 | atomic_t spinning_readers; | 139 | atomic_t spinning_readers; |
139 | atomic_t spinning_writers; | 140 | atomic_t spinning_writers; |
141 | int lock_nested; | ||
140 | 142 | ||
141 | /* protects write locks */ | 143 | /* protects write locks */ |
142 | rwlock_t lock; | 144 | rwlock_t lock; |
diff --git a/fs/btrfs/file.c b/fs/btrfs/file.c index 97fbe939c050..fc97b00bd871 100644 --- a/fs/btrfs/file.c +++ b/fs/btrfs/file.c | |||
@@ -678,7 +678,7 @@ next_slot: | |||
678 | disk_bytenr, num_bytes, 0, | 678 | disk_bytenr, num_bytes, 0, |
679 | root->root_key.objectid, | 679 | root->root_key.objectid, |
680 | new_key.objectid, | 680 | new_key.objectid, |
681 | start - extent_offset); | 681 | start - extent_offset, 0); |
682 | BUG_ON(ret); | 682 | BUG_ON(ret); |
683 | *hint_byte = disk_bytenr; | 683 | *hint_byte = disk_bytenr; |
684 | } | 684 | } |
@@ -753,7 +753,7 @@ next_slot: | |||
753 | disk_bytenr, num_bytes, 0, | 753 | disk_bytenr, num_bytes, 0, |
754 | root->root_key.objectid, | 754 | root->root_key.objectid, |
755 | key.objectid, key.offset - | 755 | key.objectid, key.offset - |
756 | extent_offset); | 756 | extent_offset, 0); |
757 | BUG_ON(ret); | 757 | BUG_ON(ret); |
758 | inode_sub_bytes(inode, | 758 | inode_sub_bytes(inode, |
759 | extent_end - key.offset); | 759 | extent_end - key.offset); |
@@ -962,7 +962,7 @@ again: | |||
962 | 962 | ||
963 | ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, 0, | 963 | ret = btrfs_inc_extent_ref(trans, root, bytenr, num_bytes, 0, |
964 | root->root_key.objectid, | 964 | root->root_key.objectid, |
965 | ino, orig_offset); | 965 | ino, orig_offset, 0); |
966 | BUG_ON(ret); | 966 | BUG_ON(ret); |
967 | 967 | ||
968 | if (split == start) { | 968 | if (split == start) { |
@@ -989,7 +989,7 @@ again: | |||
989 | del_nr++; | 989 | del_nr++; |
990 | ret = btrfs_free_extent(trans, root, bytenr, num_bytes, | 990 | ret = btrfs_free_extent(trans, root, bytenr, num_bytes, |
991 | 0, root->root_key.objectid, | 991 | 0, root->root_key.objectid, |
992 | ino, orig_offset); | 992 | ino, orig_offset, 0); |
993 | BUG_ON(ret); | 993 | BUG_ON(ret); |
994 | } | 994 | } |
995 | other_start = 0; | 995 | other_start = 0; |
@@ -1006,7 +1006,7 @@ again: | |||
1006 | del_nr++; | 1006 | del_nr++; |
1007 | ret = btrfs_free_extent(trans, root, bytenr, num_bytes, | 1007 | ret = btrfs_free_extent(trans, root, bytenr, num_bytes, |
1008 | 0, root->root_key.objectid, | 1008 | 0, root->root_key.objectid, |
1009 | ino, orig_offset); | 1009 | ino, orig_offset, 0); |
1010 | BUG_ON(ret); | 1010 | BUG_ON(ret); |
1011 | } | 1011 | } |
1012 | if (del_nr == 0) { | 1012 | if (del_nr == 0) { |
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c index fd1a06df5bc6..acc4ff39ca4e 100644 --- a/fs/btrfs/inode.c +++ b/fs/btrfs/inode.c | |||
@@ -3179,7 +3179,7 @@ delete: | |||
3179 | ret = btrfs_free_extent(trans, root, extent_start, | 3179 | ret = btrfs_free_extent(trans, root, extent_start, |
3180 | extent_num_bytes, 0, | 3180 | extent_num_bytes, 0, |
3181 | btrfs_header_owner(leaf), | 3181 | btrfs_header_owner(leaf), |
3182 | ino, extent_offset); | 3182 | ino, extent_offset, 0); |
3183 | BUG_ON(ret); | 3183 | BUG_ON(ret); |
3184 | } | 3184 | } |
3185 | 3185 | ||
@@ -5121,7 +5121,7 @@ again: | |||
5121 | } | 5121 | } |
5122 | flush_dcache_page(page); | 5122 | flush_dcache_page(page); |
5123 | } else if (create && PageUptodate(page)) { | 5123 | } else if (create && PageUptodate(page)) { |
5124 | WARN_ON(1); | 5124 | BUG(); |
5125 | if (!trans) { | 5125 | if (!trans) { |
5126 | kunmap(page); | 5126 | kunmap(page); |
5127 | free_extent_map(em); | 5127 | free_extent_map(em); |
diff --git a/fs/btrfs/ioctl.c b/fs/btrfs/ioctl.c index ef909b5d3d2e..7fdf22c2dc0d 100644 --- a/fs/btrfs/ioctl.c +++ b/fs/btrfs/ioctl.c | |||
@@ -368,7 +368,7 @@ static noinline int create_subvol(struct btrfs_root *root, | |||
368 | return PTR_ERR(trans); | 368 | return PTR_ERR(trans); |
369 | 369 | ||
370 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, | 370 | leaf = btrfs_alloc_free_block(trans, root, root->leafsize, |
371 | 0, objectid, NULL, 0, 0, 0); | 371 | 0, objectid, NULL, 0, 0, 0, 0); |
372 | if (IS_ERR(leaf)) { | 372 | if (IS_ERR(leaf)) { |
373 | ret = PTR_ERR(leaf); | 373 | ret = PTR_ERR(leaf); |
374 | goto fail; | 374 | goto fail; |
@@ -2468,7 +2468,8 @@ static noinline long btrfs_ioctl_clone(struct file *file, unsigned long srcfd, | |||
2468 | disko, diskl, 0, | 2468 | disko, diskl, 0, |
2469 | root->root_key.objectid, | 2469 | root->root_key.objectid, |
2470 | btrfs_ino(inode), | 2470 | btrfs_ino(inode), |
2471 | new_key.offset - datao); | 2471 | new_key.offset - datao, |
2472 | 0); | ||
2472 | BUG_ON(ret); | 2473 | BUG_ON(ret); |
2473 | } | 2474 | } |
2474 | } else if (type == BTRFS_FILE_EXTENT_INLINE) { | 2475 | } else if (type == BTRFS_FILE_EXTENT_INLINE) { |
@@ -3018,7 +3019,7 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root, | |||
3018 | { | 3019 | { |
3019 | int ret = 0; | 3020 | int ret = 0; |
3020 | int size; | 3021 | int size; |
3021 | u64 extent_offset; | 3022 | u64 extent_item_pos; |
3022 | struct btrfs_ioctl_logical_ino_args *loi; | 3023 | struct btrfs_ioctl_logical_ino_args *loi; |
3023 | struct btrfs_data_container *inodes = NULL; | 3024 | struct btrfs_data_container *inodes = NULL; |
3024 | struct btrfs_path *path = NULL; | 3025 | struct btrfs_path *path = NULL; |
@@ -3049,15 +3050,17 @@ static long btrfs_ioctl_logical_to_ino(struct btrfs_root *root, | |||
3049 | } | 3050 | } |
3050 | 3051 | ||
3051 | ret = extent_from_logical(root->fs_info, loi->logical, path, &key); | 3052 | ret = extent_from_logical(root->fs_info, loi->logical, path, &key); |
3053 | btrfs_release_path(path); | ||
3052 | 3054 | ||
3053 | if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) | 3055 | if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) |
3054 | ret = -ENOENT; | 3056 | ret = -ENOENT; |
3055 | if (ret < 0) | 3057 | if (ret < 0) |
3056 | goto out; | 3058 | goto out; |
3057 | 3059 | ||
3058 | extent_offset = loi->logical - key.objectid; | 3060 | extent_item_pos = loi->logical - key.objectid; |
3059 | ret = iterate_extent_inodes(root->fs_info, path, key.objectid, | 3061 | ret = iterate_extent_inodes(root->fs_info, path, key.objectid, |
3060 | extent_offset, build_ino_list, inodes); | 3062 | extent_item_pos, build_ino_list, |
3063 | inodes); | ||
3061 | 3064 | ||
3062 | if (ret < 0) | 3065 | if (ret < 0) |
3063 | goto out; | 3066 | goto out; |
diff --git a/fs/btrfs/locking.c b/fs/btrfs/locking.c index d77b67c4b275..5e178d8f7167 100644 --- a/fs/btrfs/locking.c +++ b/fs/btrfs/locking.c | |||
@@ -33,6 +33,14 @@ void btrfs_assert_tree_read_locked(struct extent_buffer *eb); | |||
33 | */ | 33 | */ |
34 | void btrfs_set_lock_blocking_rw(struct extent_buffer *eb, int rw) | 34 | void btrfs_set_lock_blocking_rw(struct extent_buffer *eb, int rw) |
35 | { | 35 | { |
36 | if (eb->lock_nested) { | ||
37 | read_lock(&eb->lock); | ||
38 | if (eb->lock_nested && current->pid == eb->lock_owner) { | ||
39 | read_unlock(&eb->lock); | ||
40 | return; | ||
41 | } | ||
42 | read_unlock(&eb->lock); | ||
43 | } | ||
36 | if (rw == BTRFS_WRITE_LOCK) { | 44 | if (rw == BTRFS_WRITE_LOCK) { |
37 | if (atomic_read(&eb->blocking_writers) == 0) { | 45 | if (atomic_read(&eb->blocking_writers) == 0) { |
38 | WARN_ON(atomic_read(&eb->spinning_writers) != 1); | 46 | WARN_ON(atomic_read(&eb->spinning_writers) != 1); |
@@ -57,6 +65,14 @@ void btrfs_set_lock_blocking_rw(struct extent_buffer *eb, int rw) | |||
57 | */ | 65 | */ |
58 | void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw) | 66 | void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw) |
59 | { | 67 | { |
68 | if (eb->lock_nested) { | ||
69 | read_lock(&eb->lock); | ||
70 | if (&eb->lock_nested && current->pid == eb->lock_owner) { | ||
71 | read_unlock(&eb->lock); | ||
72 | return; | ||
73 | } | ||
74 | read_unlock(&eb->lock); | ||
75 | } | ||
60 | if (rw == BTRFS_WRITE_LOCK_BLOCKING) { | 76 | if (rw == BTRFS_WRITE_LOCK_BLOCKING) { |
61 | BUG_ON(atomic_read(&eb->blocking_writers) != 1); | 77 | BUG_ON(atomic_read(&eb->blocking_writers) != 1); |
62 | write_lock(&eb->lock); | 78 | write_lock(&eb->lock); |
@@ -81,12 +97,25 @@ void btrfs_clear_lock_blocking_rw(struct extent_buffer *eb, int rw) | |||
81 | void btrfs_tree_read_lock(struct extent_buffer *eb) | 97 | void btrfs_tree_read_lock(struct extent_buffer *eb) |
82 | { | 98 | { |
83 | again: | 99 | again: |
100 | read_lock(&eb->lock); | ||
101 | if (atomic_read(&eb->blocking_writers) && | ||
102 | current->pid == eb->lock_owner) { | ||
103 | /* | ||
104 | * This extent is already write-locked by our thread. We allow | ||
105 | * an additional read lock to be added because it's for the same | ||
106 | * thread. btrfs_find_all_roots() depends on this as it may be | ||
107 | * called on a partly (write-)locked tree. | ||
108 | */ | ||
109 | BUG_ON(eb->lock_nested); | ||
110 | eb->lock_nested = 1; | ||
111 | read_unlock(&eb->lock); | ||
112 | return; | ||
113 | } | ||
114 | read_unlock(&eb->lock); | ||
84 | wait_event(eb->write_lock_wq, atomic_read(&eb->blocking_writers) == 0); | 115 | wait_event(eb->write_lock_wq, atomic_read(&eb->blocking_writers) == 0); |
85 | read_lock(&eb->lock); | 116 | read_lock(&eb->lock); |
86 | if (atomic_read(&eb->blocking_writers)) { | 117 | if (atomic_read(&eb->blocking_writers)) { |
87 | read_unlock(&eb->lock); | 118 | read_unlock(&eb->lock); |
88 | wait_event(eb->write_lock_wq, | ||
89 | atomic_read(&eb->blocking_writers) == 0); | ||
90 | goto again; | 119 | goto again; |
91 | } | 120 | } |
92 | atomic_inc(&eb->read_locks); | 121 | atomic_inc(&eb->read_locks); |
@@ -129,6 +158,7 @@ int btrfs_try_tree_write_lock(struct extent_buffer *eb) | |||
129 | } | 158 | } |
130 | atomic_inc(&eb->write_locks); | 159 | atomic_inc(&eb->write_locks); |
131 | atomic_inc(&eb->spinning_writers); | 160 | atomic_inc(&eb->spinning_writers); |
161 | eb->lock_owner = current->pid; | ||
132 | return 1; | 162 | return 1; |
133 | } | 163 | } |
134 | 164 | ||
@@ -137,6 +167,15 @@ int btrfs_try_tree_write_lock(struct extent_buffer *eb) | |||
137 | */ | 167 | */ |
138 | void btrfs_tree_read_unlock(struct extent_buffer *eb) | 168 | void btrfs_tree_read_unlock(struct extent_buffer *eb) |
139 | { | 169 | { |
170 | if (eb->lock_nested) { | ||
171 | read_lock(&eb->lock); | ||
172 | if (eb->lock_nested && current->pid == eb->lock_owner) { | ||
173 | eb->lock_nested = 0; | ||
174 | read_unlock(&eb->lock); | ||
175 | return; | ||
176 | } | ||
177 | read_unlock(&eb->lock); | ||
178 | } | ||
140 | btrfs_assert_tree_read_locked(eb); | 179 | btrfs_assert_tree_read_locked(eb); |
141 | WARN_ON(atomic_read(&eb->spinning_readers) == 0); | 180 | WARN_ON(atomic_read(&eb->spinning_readers) == 0); |
142 | atomic_dec(&eb->spinning_readers); | 181 | atomic_dec(&eb->spinning_readers); |
@@ -149,6 +188,15 @@ void btrfs_tree_read_unlock(struct extent_buffer *eb) | |||
149 | */ | 188 | */ |
150 | void btrfs_tree_read_unlock_blocking(struct extent_buffer *eb) | 189 | void btrfs_tree_read_unlock_blocking(struct extent_buffer *eb) |
151 | { | 190 | { |
191 | if (eb->lock_nested) { | ||
192 | read_lock(&eb->lock); | ||
193 | if (eb->lock_nested && current->pid == eb->lock_owner) { | ||
194 | eb->lock_nested = 0; | ||
195 | read_unlock(&eb->lock); | ||
196 | return; | ||
197 | } | ||
198 | read_unlock(&eb->lock); | ||
199 | } | ||
152 | btrfs_assert_tree_read_locked(eb); | 200 | btrfs_assert_tree_read_locked(eb); |
153 | WARN_ON(atomic_read(&eb->blocking_readers) == 0); | 201 | WARN_ON(atomic_read(&eb->blocking_readers) == 0); |
154 | if (atomic_dec_and_test(&eb->blocking_readers)) | 202 | if (atomic_dec_and_test(&eb->blocking_readers)) |
@@ -181,6 +229,7 @@ again: | |||
181 | WARN_ON(atomic_read(&eb->spinning_writers)); | 229 | WARN_ON(atomic_read(&eb->spinning_writers)); |
182 | atomic_inc(&eb->spinning_writers); | 230 | atomic_inc(&eb->spinning_writers); |
183 | atomic_inc(&eb->write_locks); | 231 | atomic_inc(&eb->write_locks); |
232 | eb->lock_owner = current->pid; | ||
184 | return 0; | 233 | return 0; |
185 | } | 234 | } |
186 | 235 | ||
diff --git a/fs/btrfs/relocation.c b/fs/btrfs/relocation.c index cfb55434a469..efe9f792544d 100644 --- a/fs/btrfs/relocation.c +++ b/fs/btrfs/relocation.c | |||
@@ -1604,12 +1604,12 @@ int replace_file_extents(struct btrfs_trans_handle *trans, | |||
1604 | ret = btrfs_inc_extent_ref(trans, root, new_bytenr, | 1604 | ret = btrfs_inc_extent_ref(trans, root, new_bytenr, |
1605 | num_bytes, parent, | 1605 | num_bytes, parent, |
1606 | btrfs_header_owner(leaf), | 1606 | btrfs_header_owner(leaf), |
1607 | key.objectid, key.offset); | 1607 | key.objectid, key.offset, 1); |
1608 | BUG_ON(ret); | 1608 | BUG_ON(ret); |
1609 | 1609 | ||
1610 | ret = btrfs_free_extent(trans, root, bytenr, num_bytes, | 1610 | ret = btrfs_free_extent(trans, root, bytenr, num_bytes, |
1611 | parent, btrfs_header_owner(leaf), | 1611 | parent, btrfs_header_owner(leaf), |
1612 | key.objectid, key.offset); | 1612 | key.objectid, key.offset, 1); |
1613 | BUG_ON(ret); | 1613 | BUG_ON(ret); |
1614 | } | 1614 | } |
1615 | if (dirty) | 1615 | if (dirty) |
@@ -1778,21 +1778,23 @@ again: | |||
1778 | 1778 | ||
1779 | ret = btrfs_inc_extent_ref(trans, src, old_bytenr, blocksize, | 1779 | ret = btrfs_inc_extent_ref(trans, src, old_bytenr, blocksize, |
1780 | path->nodes[level]->start, | 1780 | path->nodes[level]->start, |
1781 | src->root_key.objectid, level - 1, 0); | 1781 | src->root_key.objectid, level - 1, 0, |
1782 | 1); | ||
1782 | BUG_ON(ret); | 1783 | BUG_ON(ret); |
1783 | ret = btrfs_inc_extent_ref(trans, dest, new_bytenr, blocksize, | 1784 | ret = btrfs_inc_extent_ref(trans, dest, new_bytenr, blocksize, |
1784 | 0, dest->root_key.objectid, level - 1, | 1785 | 0, dest->root_key.objectid, level - 1, |
1785 | 0); | 1786 | 0, 1); |
1786 | BUG_ON(ret); | 1787 | BUG_ON(ret); |
1787 | 1788 | ||
1788 | ret = btrfs_free_extent(trans, src, new_bytenr, blocksize, | 1789 | ret = btrfs_free_extent(trans, src, new_bytenr, blocksize, |
1789 | path->nodes[level]->start, | 1790 | path->nodes[level]->start, |
1790 | src->root_key.objectid, level - 1, 0); | 1791 | src->root_key.objectid, level - 1, 0, |
1792 | 1); | ||
1791 | BUG_ON(ret); | 1793 | BUG_ON(ret); |
1792 | 1794 | ||
1793 | ret = btrfs_free_extent(trans, dest, old_bytenr, blocksize, | 1795 | ret = btrfs_free_extent(trans, dest, old_bytenr, blocksize, |
1794 | 0, dest->root_key.objectid, level - 1, | 1796 | 0, dest->root_key.objectid, level - 1, |
1795 | 0); | 1797 | 0, 1); |
1796 | BUG_ON(ret); | 1798 | BUG_ON(ret); |
1797 | 1799 | ||
1798 | btrfs_unlock_up_safe(path, 0); | 1800 | btrfs_unlock_up_safe(path, 0); |
@@ -2244,7 +2246,7 @@ again: | |||
2244 | } else { | 2246 | } else { |
2245 | list_del_init(&reloc_root->root_list); | 2247 | list_del_init(&reloc_root->root_list); |
2246 | } | 2248 | } |
2247 | btrfs_drop_snapshot(reloc_root, rc->block_rsv, 0); | 2249 | btrfs_drop_snapshot(reloc_root, rc->block_rsv, 0, 1); |
2248 | } | 2250 | } |
2249 | 2251 | ||
2250 | if (found) { | 2252 | if (found) { |
@@ -2558,7 +2560,7 @@ static int do_relocation(struct btrfs_trans_handle *trans, | |||
2558 | node->eb->start, blocksize, | 2560 | node->eb->start, blocksize, |
2559 | upper->eb->start, | 2561 | upper->eb->start, |
2560 | btrfs_header_owner(upper->eb), | 2562 | btrfs_header_owner(upper->eb), |
2561 | node->level, 0); | 2563 | node->level, 0, 1); |
2562 | BUG_ON(ret); | 2564 | BUG_ON(ret); |
2563 | 2565 | ||
2564 | ret = btrfs_drop_subtree(trans, root, eb, upper->eb); | 2566 | ret = btrfs_drop_subtree(trans, root, eb, upper->eb); |
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c index ddf2c90d3fc0..6a6a51a809ba 100644 --- a/fs/btrfs/scrub.c +++ b/fs/btrfs/scrub.c | |||
@@ -309,7 +309,7 @@ static void scrub_print_warning(const char *errstr, struct scrub_bio *sbio, | |||
309 | u8 ref_level; | 309 | u8 ref_level; |
310 | unsigned long ptr = 0; | 310 | unsigned long ptr = 0; |
311 | const int bufsize = 4096; | 311 | const int bufsize = 4096; |
312 | u64 extent_offset; | 312 | u64 extent_item_pos; |
313 | 313 | ||
314 | path = btrfs_alloc_path(); | 314 | path = btrfs_alloc_path(); |
315 | 315 | ||
@@ -329,12 +329,13 @@ static void scrub_print_warning(const char *errstr, struct scrub_bio *sbio, | |||
329 | if (ret < 0) | 329 | if (ret < 0) |
330 | goto out; | 330 | goto out; |
331 | 331 | ||
332 | extent_offset = swarn.logical - found_key.objectid; | 332 | extent_item_pos = swarn.logical - found_key.objectid; |
333 | swarn.extent_item_size = found_key.offset; | 333 | swarn.extent_item_size = found_key.offset; |
334 | 334 | ||
335 | eb = path->nodes[0]; | 335 | eb = path->nodes[0]; |
336 | ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item); | 336 | ei = btrfs_item_ptr(eb, path->slots[0], struct btrfs_extent_item); |
337 | item_size = btrfs_item_size_nr(eb, path->slots[0]); | 337 | item_size = btrfs_item_size_nr(eb, path->slots[0]); |
338 | btrfs_release_path(path); | ||
338 | 339 | ||
339 | if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) { | 340 | if (ret & BTRFS_EXTENT_FLAG_TREE_BLOCK) { |
340 | do { | 341 | do { |
@@ -351,7 +352,7 @@ static void scrub_print_warning(const char *errstr, struct scrub_bio *sbio, | |||
351 | } else { | 352 | } else { |
352 | swarn.path = path; | 353 | swarn.path = path; |
353 | iterate_extent_inodes(fs_info, path, found_key.objectid, | 354 | iterate_extent_inodes(fs_info, path, found_key.objectid, |
354 | extent_offset, | 355 | extent_item_pos, |
355 | scrub_print_warning_inode, &swarn); | 356 | scrub_print_warning_inode, &swarn); |
356 | } | 357 | } |
357 | 358 | ||
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c index 360c2dfd1ee6..d5f987b49d70 100644 --- a/fs/btrfs/transaction.c +++ b/fs/btrfs/transaction.c | |||
@@ -36,6 +36,8 @@ static noinline void put_transaction(struct btrfs_transaction *transaction) | |||
36 | WARN_ON(atomic_read(&transaction->use_count) == 0); | 36 | WARN_ON(atomic_read(&transaction->use_count) == 0); |
37 | if (atomic_dec_and_test(&transaction->use_count)) { | 37 | if (atomic_dec_and_test(&transaction->use_count)) { |
38 | BUG_ON(!list_empty(&transaction->list)); | 38 | BUG_ON(!list_empty(&transaction->list)); |
39 | WARN_ON(transaction->delayed_refs.root.rb_node); | ||
40 | WARN_ON(!list_empty(&transaction->delayed_refs.seq_head)); | ||
39 | memset(transaction, 0, sizeof(*transaction)); | 41 | memset(transaction, 0, sizeof(*transaction)); |
40 | kmem_cache_free(btrfs_transaction_cachep, transaction); | 42 | kmem_cache_free(btrfs_transaction_cachep, transaction); |
41 | } | 43 | } |
@@ -108,8 +110,11 @@ loop: | |||
108 | cur_trans->delayed_refs.num_heads = 0; | 110 | cur_trans->delayed_refs.num_heads = 0; |
109 | cur_trans->delayed_refs.flushing = 0; | 111 | cur_trans->delayed_refs.flushing = 0; |
110 | cur_trans->delayed_refs.run_delayed_start = 0; | 112 | cur_trans->delayed_refs.run_delayed_start = 0; |
113 | cur_trans->delayed_refs.seq = 1; | ||
114 | init_waitqueue_head(&cur_trans->delayed_refs.seq_wait); | ||
111 | spin_lock_init(&cur_trans->commit_lock); | 115 | spin_lock_init(&cur_trans->commit_lock); |
112 | spin_lock_init(&cur_trans->delayed_refs.lock); | 116 | spin_lock_init(&cur_trans->delayed_refs.lock); |
117 | INIT_LIST_HEAD(&cur_trans->delayed_refs.seq_head); | ||
113 | 118 | ||
114 | INIT_LIST_HEAD(&cur_trans->pending_snapshots); | 119 | INIT_LIST_HEAD(&cur_trans->pending_snapshots); |
115 | list_add_tail(&cur_trans->list, &root->fs_info->trans_list); | 120 | list_add_tail(&cur_trans->list, &root->fs_info->trans_list); |
@@ -1386,9 +1391,9 @@ int btrfs_clean_old_snapshots(struct btrfs_root *root) | |||
1386 | 1391 | ||
1387 | if (btrfs_header_backref_rev(root->node) < | 1392 | if (btrfs_header_backref_rev(root->node) < |
1388 | BTRFS_MIXED_BACKREF_REV) | 1393 | BTRFS_MIXED_BACKREF_REV) |
1389 | btrfs_drop_snapshot(root, NULL, 0); | 1394 | btrfs_drop_snapshot(root, NULL, 0, 0); |
1390 | else | 1395 | else |
1391 | btrfs_drop_snapshot(root, NULL, 1); | 1396 | btrfs_drop_snapshot(root, NULL, 1, 0); |
1392 | } | 1397 | } |
1393 | return 0; | 1398 | return 0; |
1394 | } | 1399 | } |
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c index 3568374d419d..cb877e0886a7 100644 --- a/fs/btrfs/tree-log.c +++ b/fs/btrfs/tree-log.c | |||
@@ -589,7 +589,7 @@ static noinline int replay_one_extent(struct btrfs_trans_handle *trans, | |||
589 | ret = btrfs_inc_extent_ref(trans, root, | 589 | ret = btrfs_inc_extent_ref(trans, root, |
590 | ins.objectid, ins.offset, | 590 | ins.objectid, ins.offset, |
591 | 0, root->root_key.objectid, | 591 | 0, root->root_key.objectid, |
592 | key->objectid, offset); | 592 | key->objectid, offset, 0); |
593 | BUG_ON(ret); | 593 | BUG_ON(ret); |
594 | } else { | 594 | } else { |
595 | /* | 595 | /* |
diff --git a/fs/btrfs/ulist.c b/fs/btrfs/ulist.c new file mode 100644 index 000000000000..12f5147bd2b1 --- /dev/null +++ b/fs/btrfs/ulist.c | |||
@@ -0,0 +1,220 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 STRATO AG | ||
3 | * written by Arne Jansen <sensille@gmx.net> | ||
4 | * Distributed under the GNU GPL license version 2. | ||
5 | */ | ||
6 | |||
7 | #include <linux/slab.h> | ||
8 | #include <linux/module.h> | ||
9 | #include "ulist.h" | ||
10 | |||
11 | /* | ||
12 | * ulist is a generic data structure to hold a collection of unique u64 | ||
13 | * values. The only operations it supports is adding to the list and | ||
14 | * enumerating it. | ||
15 | * It is possible to store an auxiliary value along with the key. | ||
16 | * | ||
17 | * The implementation is preliminary and can probably be sped up | ||
18 | * significantly. A first step would be to store the values in an rbtree | ||
19 | * as soon as ULIST_SIZE is exceeded. | ||
20 | * | ||
21 | * A sample usage for ulists is the enumeration of directed graphs without | ||
22 | * visiting a node twice. The pseudo-code could look like this: | ||
23 | * | ||
24 | * ulist = ulist_alloc(); | ||
25 | * ulist_add(ulist, root); | ||
26 | * elem = NULL; | ||
27 | * | ||
28 | * while ((elem = ulist_next(ulist, elem)) { | ||
29 | * for (all child nodes n in elem) | ||
30 | * ulist_add(ulist, n); | ||
31 | * do something useful with the node; | ||
32 | * } | ||
33 | * ulist_free(ulist); | ||
34 | * | ||
35 | * This assumes the graph nodes are adressable by u64. This stems from the | ||
36 | * usage for tree enumeration in btrfs, where the logical addresses are | ||
37 | * 64 bit. | ||
38 | * | ||
39 | * It is also useful for tree enumeration which could be done elegantly | ||
40 | * recursively, but is not possible due to kernel stack limitations. The | ||
41 | * loop would be similar to the above. | ||
42 | */ | ||
43 | |||
44 | /** | ||
45 | * ulist_init - freshly initialize a ulist | ||
46 | * @ulist: the ulist to initialize | ||
47 | * | ||
48 | * Note: don't use this function to init an already used ulist, use | ||
49 | * ulist_reinit instead. | ||
50 | */ | ||
51 | void ulist_init(struct ulist *ulist) | ||
52 | { | ||
53 | ulist->nnodes = 0; | ||
54 | ulist->nodes = ulist->int_nodes; | ||
55 | ulist->nodes_alloced = ULIST_SIZE; | ||
56 | } | ||
57 | EXPORT_SYMBOL(ulist_init); | ||
58 | |||
59 | /** | ||
60 | * ulist_fini - free up additionally allocated memory for the ulist | ||
61 | * @ulist: the ulist from which to free the additional memory | ||
62 | * | ||
63 | * This is useful in cases where the base 'struct ulist' has been statically | ||
64 | * allocated. | ||
65 | */ | ||
66 | void ulist_fini(struct ulist *ulist) | ||
67 | { | ||
68 | /* | ||
69 | * The first ULIST_SIZE elements are stored inline in struct ulist. | ||
70 | * Only if more elements are alocated they need to be freed. | ||
71 | */ | ||
72 | if (ulist->nodes_alloced > ULIST_SIZE) | ||
73 | kfree(ulist->nodes); | ||
74 | ulist->nodes_alloced = 0; /* in case ulist_fini is called twice */ | ||
75 | } | ||
76 | EXPORT_SYMBOL(ulist_fini); | ||
77 | |||
78 | /** | ||
79 | * ulist_reinit - prepare a ulist for reuse | ||
80 | * @ulist: ulist to be reused | ||
81 | * | ||
82 | * Free up all additional memory allocated for the list elements and reinit | ||
83 | * the ulist. | ||
84 | */ | ||
85 | void ulist_reinit(struct ulist *ulist) | ||
86 | { | ||
87 | ulist_fini(ulist); | ||
88 | ulist_init(ulist); | ||
89 | } | ||
90 | EXPORT_SYMBOL(ulist_reinit); | ||
91 | |||
92 | /** | ||
93 | * ulist_alloc - dynamically allocate a ulist | ||
94 | * @gfp_mask: allocation flags to for base allocation | ||
95 | * | ||
96 | * The allocated ulist will be returned in an initialized state. | ||
97 | */ | ||
98 | struct ulist *ulist_alloc(unsigned long gfp_mask) | ||
99 | { | ||
100 | struct ulist *ulist = kmalloc(sizeof(*ulist), gfp_mask); | ||
101 | |||
102 | if (!ulist) | ||
103 | return NULL; | ||
104 | |||
105 | ulist_init(ulist); | ||
106 | |||
107 | return ulist; | ||
108 | } | ||
109 | EXPORT_SYMBOL(ulist_alloc); | ||
110 | |||
111 | /** | ||
112 | * ulist_free - free dynamically allocated ulist | ||
113 | * @ulist: ulist to free | ||
114 | * | ||
115 | * It is not necessary to call ulist_fini before. | ||
116 | */ | ||
117 | void ulist_free(struct ulist *ulist) | ||
118 | { | ||
119 | if (!ulist) | ||
120 | return; | ||
121 | ulist_fini(ulist); | ||
122 | kfree(ulist); | ||
123 | } | ||
124 | EXPORT_SYMBOL(ulist_free); | ||
125 | |||
126 | /** | ||
127 | * ulist_add - add an element to the ulist | ||
128 | * @ulist: ulist to add the element to | ||
129 | * @val: value to add to ulist | ||
130 | * @aux: auxiliary value to store along with val | ||
131 | * @gfp_mask: flags to use for allocation | ||
132 | * | ||
133 | * Note: locking must be provided by the caller. In case of rwlocks write | ||
134 | * locking is needed | ||
135 | * | ||
136 | * Add an element to a ulist. The @val will only be added if it doesn't | ||
137 | * already exist. If it is added, the auxiliary value @aux is stored along with | ||
138 | * it. In case @val already exists in the ulist, @aux is ignored, even if | ||
139 | * it differs from the already stored value. | ||
140 | * | ||
141 | * ulist_add returns 0 if @val already exists in ulist and 1 if @val has been | ||
142 | * inserted. | ||
143 | * In case of allocation failure -ENOMEM is returned and the ulist stays | ||
144 | * unaltered. | ||
145 | */ | ||
146 | int ulist_add(struct ulist *ulist, u64 val, unsigned long aux, | ||
147 | unsigned long gfp_mask) | ||
148 | { | ||
149 | int i; | ||
150 | |||
151 | for (i = 0; i < ulist->nnodes; ++i) { | ||
152 | if (ulist->nodes[i].val == val) | ||
153 | return 0; | ||
154 | } | ||
155 | |||
156 | if (ulist->nnodes >= ulist->nodes_alloced) { | ||
157 | u64 new_alloced = ulist->nodes_alloced + 128; | ||
158 | struct ulist_node *new_nodes; | ||
159 | void *old = NULL; | ||
160 | |||
161 | /* | ||
162 | * if nodes_alloced == ULIST_SIZE no memory has been allocated | ||
163 | * yet, so pass NULL to krealloc | ||
164 | */ | ||
165 | if (ulist->nodes_alloced > ULIST_SIZE) | ||
166 | old = ulist->nodes; | ||
167 | |||
168 | new_nodes = krealloc(old, sizeof(*new_nodes) * new_alloced, | ||
169 | gfp_mask); | ||
170 | if (!new_nodes) | ||
171 | return -ENOMEM; | ||
172 | |||
173 | if (!old) | ||
174 | memcpy(new_nodes, ulist->int_nodes, | ||
175 | sizeof(ulist->int_nodes)); | ||
176 | |||
177 | ulist->nodes = new_nodes; | ||
178 | ulist->nodes_alloced = new_alloced; | ||
179 | } | ||
180 | ulist->nodes[ulist->nnodes].val = val; | ||
181 | ulist->nodes[ulist->nnodes].aux = aux; | ||
182 | ++ulist->nnodes; | ||
183 | |||
184 | return 1; | ||
185 | } | ||
186 | EXPORT_SYMBOL(ulist_add); | ||
187 | |||
188 | /** | ||
189 | * ulist_next - iterate ulist | ||
190 | * @ulist: ulist to iterate | ||
191 | * @prev: previously returned element or %NULL to start iteration | ||
192 | * | ||
193 | * Note: locking must be provided by the caller. In case of rwlocks only read | ||
194 | * locking is needed | ||
195 | * | ||
196 | * This function is used to iterate an ulist. The iteration is started with | ||
197 | * @prev = %NULL. It returns the next element from the ulist or %NULL when the | ||
198 | * end is reached. No guarantee is made with respect to the order in which | ||
199 | * the elements are returned. They might neither be returned in order of | ||
200 | * addition nor in ascending order. | ||
201 | * It is allowed to call ulist_add during an enumeration. Newly added items | ||
202 | * are guaranteed to show up in the running enumeration. | ||
203 | */ | ||
204 | struct ulist_node *ulist_next(struct ulist *ulist, struct ulist_node *prev) | ||
205 | { | ||
206 | int next; | ||
207 | |||
208 | if (ulist->nnodes == 0) | ||
209 | return NULL; | ||
210 | |||
211 | if (!prev) | ||
212 | return &ulist->nodes[0]; | ||
213 | |||
214 | next = (prev - ulist->nodes) + 1; | ||
215 | if (next < 0 || next >= ulist->nnodes) | ||
216 | return NULL; | ||
217 | |||
218 | return &ulist->nodes[next]; | ||
219 | } | ||
220 | EXPORT_SYMBOL(ulist_next); | ||
diff --git a/fs/btrfs/ulist.h b/fs/btrfs/ulist.h new file mode 100644 index 000000000000..2e25dec58ec0 --- /dev/null +++ b/fs/btrfs/ulist.h | |||
@@ -0,0 +1,68 @@ | |||
1 | /* | ||
2 | * Copyright (C) 2011 STRATO AG | ||
3 | * written by Arne Jansen <sensille@gmx.net> | ||
4 | * Distributed under the GNU GPL license version 2. | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #ifndef __ULIST__ | ||
9 | #define __ULIST__ | ||
10 | |||
11 | /* | ||
12 | * ulist is a generic data structure to hold a collection of unique u64 | ||
13 | * values. The only operations it supports is adding to the list and | ||
14 | * enumerating it. | ||
15 | * It is possible to store an auxiliary value along with the key. | ||
16 | * | ||
17 | * The implementation is preliminary and can probably be sped up | ||
18 | * significantly. A first step would be to store the values in an rbtree | ||
19 | * as soon as ULIST_SIZE is exceeded. | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * number of elements statically allocated inside struct ulist | ||
24 | */ | ||
25 | #define ULIST_SIZE 16 | ||
26 | |||
27 | /* | ||
28 | * element of the list | ||
29 | */ | ||
30 | struct ulist_node { | ||
31 | u64 val; /* value to store */ | ||
32 | unsigned long aux; /* auxiliary value saved along with the val */ | ||
33 | }; | ||
34 | |||
35 | struct ulist { | ||
36 | /* | ||
37 | * number of elements stored in list | ||
38 | */ | ||
39 | unsigned long nnodes; | ||
40 | |||
41 | /* | ||
42 | * number of nodes we already have room for | ||
43 | */ | ||
44 | unsigned long nodes_alloced; | ||
45 | |||
46 | /* | ||
47 | * pointer to the array storing the elements. The first ULIST_SIZE | ||
48 | * elements are stored inline. In this case the it points to int_nodes. | ||
49 | * After exceeding ULIST_SIZE, dynamic memory is allocated. | ||
50 | */ | ||
51 | struct ulist_node *nodes; | ||
52 | |||
53 | /* | ||
54 | * inline storage space for the first ULIST_SIZE entries | ||
55 | */ | ||
56 | struct ulist_node int_nodes[ULIST_SIZE]; | ||
57 | }; | ||
58 | |||
59 | void ulist_init(struct ulist *ulist); | ||
60 | void ulist_fini(struct ulist *ulist); | ||
61 | void ulist_reinit(struct ulist *ulist); | ||
62 | struct ulist *ulist_alloc(unsigned long gfp_mask); | ||
63 | void ulist_free(struct ulist *ulist); | ||
64 | int ulist_add(struct ulist *ulist, u64 val, unsigned long aux, | ||
65 | unsigned long gfp_mask); | ||
66 | struct ulist_node *ulist_next(struct ulist *ulist, struct ulist_node *prev); | ||
67 | |||
68 | #endif | ||