aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--fs/btrfs/backref.c9
-rw-r--r--fs/btrfs/delayed-ref.c156
-rw-r--r--fs/btrfs/delayed-ref.h18
-rw-r--r--fs/btrfs/disk-io.c8
-rw-r--r--fs/btrfs/extent-tree.c46
5 files changed, 114 insertions, 123 deletions
diff --git a/fs/btrfs/backref.c b/fs/btrfs/backref.c
index a3316f1707e6..49bc5a41c1f8 100644
--- a/fs/btrfs/backref.c
+++ b/fs/btrfs/backref.c
@@ -574,8 +574,8 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq,
574 struct list_head *prefs, u64 *total_refs, 574 struct list_head *prefs, u64 *total_refs,
575 u64 inum) 575 u64 inum)
576{ 576{
577 struct btrfs_delayed_ref_node *node;
577 struct btrfs_delayed_extent_op *extent_op = head->extent_op; 578 struct btrfs_delayed_extent_op *extent_op = head->extent_op;
578 struct rb_node *n = &head->node.rb_node;
579 struct btrfs_key key; 579 struct btrfs_key key;
580 struct btrfs_key op_key = {0}; 580 struct btrfs_key op_key = {0};
581 int sgn; 581 int sgn;
@@ -585,12 +585,7 @@ static int __add_delayed_refs(struct btrfs_delayed_ref_head *head, u64 seq,
585 btrfs_disk_key_to_cpu(&op_key, &extent_op->key); 585 btrfs_disk_key_to_cpu(&op_key, &extent_op->key);
586 586
587 spin_lock(&head->lock); 587 spin_lock(&head->lock);
588 n = rb_first(&head->ref_root); 588 list_for_each_entry(node, &head->ref_list, list) {
589 while (n) {
590 struct btrfs_delayed_ref_node *node;
591 node = rb_entry(n, struct btrfs_delayed_ref_node,
592 rb_node);
593 n = rb_next(n);
594 if (node->seq > seq) 589 if (node->seq > seq)
595 continue; 590 continue;
596 591
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
index 8f8ed7d20bac..4dbc31636d14 100644
--- a/fs/btrfs/delayed-ref.c
+++ b/fs/btrfs/delayed-ref.c
@@ -268,7 +268,7 @@ static inline void drop_delayed_ref(struct btrfs_trans_handle *trans,
268 rb_erase(&head->href_node, &delayed_refs->href_root); 268 rb_erase(&head->href_node, &delayed_refs->href_root);
269 } else { 269 } else {
270 assert_spin_locked(&head->lock); 270 assert_spin_locked(&head->lock);
271 rb_erase(&ref->rb_node, &head->ref_root); 271 list_del(&ref->list);
272 } 272 }
273 ref->in_tree = 0; 273 ref->in_tree = 0;
274 btrfs_put_delayed_ref(ref); 274 btrfs_put_delayed_ref(ref);
@@ -328,48 +328,6 @@ static int merge_ref(struct btrfs_trans_handle *trans,
328 return done; 328 return done;
329} 329}
330 330
331void btrfs_merge_delayed_refs(struct btrfs_trans_handle *trans,
332 struct btrfs_fs_info *fs_info,
333 struct btrfs_delayed_ref_root *delayed_refs,
334 struct btrfs_delayed_ref_head *head)
335{
336 struct rb_node *node;
337 u64 seq = 0;
338
339 assert_spin_locked(&head->lock);
340 /*
341 * We don't have too much refs to merge in the case of delayed data
342 * refs.
343 */
344 if (head->is_data)
345 return;
346
347 spin_lock(&fs_info->tree_mod_seq_lock);
348 if (!list_empty(&fs_info->tree_mod_seq_list)) {
349 struct seq_list *elem;
350
351 elem = list_first_entry(&fs_info->tree_mod_seq_list,
352 struct seq_list, list);
353 seq = elem->seq;
354 }
355 spin_unlock(&fs_info->tree_mod_seq_lock);
356
357 node = rb_first(&head->ref_root);
358 while (node) {
359 struct btrfs_delayed_ref_node *ref;
360
361 ref = rb_entry(node, struct btrfs_delayed_ref_node,
362 rb_node);
363 /* We can't merge refs that are outside of our seq count */
364 if (seq && ref->seq >= seq)
365 break;
366 if (merge_ref(trans, delayed_refs, head, ref, seq))
367 node = rb_first(&head->ref_root);
368 else
369 node = rb_next(&ref->rb_node);
370 }
371}
372
373int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info, 331int btrfs_check_delayed_seq(struct btrfs_fs_info *fs_info,
374 struct btrfs_delayed_ref_root *delayed_refs, 332 struct btrfs_delayed_ref_root *delayed_refs,
375 u64 seq) 333 u64 seq)
@@ -485,6 +443,74 @@ update_existing_ref(struct btrfs_trans_handle *trans,
485} 443}
486 444
487/* 445/*
446 * Helper to insert the ref_node to the tail or merge with tail.
447 *
448 * Return 0 for insert.
449 * Return >0 for merge.
450 */
451static int
452add_delayed_ref_tail_merge(struct btrfs_trans_handle *trans,
453 struct btrfs_delayed_ref_root *root,
454 struct btrfs_delayed_ref_head *href,
455 struct btrfs_delayed_ref_node *ref)
456{
457 struct btrfs_delayed_ref_node *exist;
458 int mod;
459 int ret = 0;
460
461 spin_lock(&href->lock);
462 /* Check whether we can merge the tail node with ref */
463 if (list_empty(&href->ref_list))
464 goto add_tail;
465 exist = list_entry(href->ref_list.prev, struct btrfs_delayed_ref_node,
466 list);
467 /* No need to compare bytenr nor is_head */
468 if (exist->type != ref->type || exist->no_quota != ref->no_quota ||
469 exist->seq != ref->seq)
470 goto add_tail;
471
472 if ((exist->type == BTRFS_TREE_BLOCK_REF_KEY ||
473 exist->type == BTRFS_SHARED_BLOCK_REF_KEY) &&
474 comp_tree_refs(btrfs_delayed_node_to_tree_ref(exist),
475 btrfs_delayed_node_to_tree_ref(ref),
476 ref->type))
477 goto add_tail;
478 if ((exist->type == BTRFS_EXTENT_DATA_REF_KEY ||
479 exist->type == BTRFS_SHARED_DATA_REF_KEY) &&
480 comp_data_refs(btrfs_delayed_node_to_data_ref(exist),
481 btrfs_delayed_node_to_data_ref(ref)))
482 goto add_tail;
483
484 /* Now we are sure we can merge */
485 ret = 1;
486 if (exist->action == ref->action) {
487 mod = ref->ref_mod;
488 } else {
489 /* Need to change action */
490 if (exist->ref_mod < ref->ref_mod) {
491 exist->action = ref->action;
492 mod = -exist->ref_mod;
493 exist->ref_mod = ref->ref_mod;
494 } else
495 mod = -ref->ref_mod;
496 }
497 exist->ref_mod += mod;
498
499 /* remove existing tail if its ref_mod is zero */
500 if (exist->ref_mod == 0)
501 drop_delayed_ref(trans, root, href, exist);
502 spin_unlock(&href->lock);
503 return ret;
504
505add_tail:
506 list_add_tail(&ref->list, &href->ref_list);
507 atomic_inc(&root->num_entries);
508 trans->delayed_ref_updates++;
509 spin_unlock(&href->lock);
510 return ret;
511}
512
513/*
488 * helper function to update the accounting in the head ref 514 * helper function to update the accounting in the head ref
489 * existing and update must have the same bytenr 515 * existing and update must have the same bytenr
490 */ 516 */
@@ -618,7 +644,7 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
618 head_ref = btrfs_delayed_node_to_head(ref); 644 head_ref = btrfs_delayed_node_to_head(ref);
619 head_ref->must_insert_reserved = must_insert_reserved; 645 head_ref->must_insert_reserved = must_insert_reserved;
620 head_ref->is_data = is_data; 646 head_ref->is_data = is_data;
621 head_ref->ref_root = RB_ROOT; 647 INIT_LIST_HEAD(&head_ref->ref_list);
622 head_ref->processing = 0; 648 head_ref->processing = 0;
623 head_ref->total_ref_mod = count_mod; 649 head_ref->total_ref_mod = count_mod;
624 650
@@ -659,10 +685,10 @@ add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
659 u64 num_bytes, u64 parent, u64 ref_root, int level, 685 u64 num_bytes, u64 parent, u64 ref_root, int level,
660 int action, int no_quota) 686 int action, int no_quota)
661{ 687{
662 struct btrfs_delayed_ref_node *existing;
663 struct btrfs_delayed_tree_ref *full_ref; 688 struct btrfs_delayed_tree_ref *full_ref;
664 struct btrfs_delayed_ref_root *delayed_refs; 689 struct btrfs_delayed_ref_root *delayed_refs;
665 u64 seq = 0; 690 u64 seq = 0;
691 int ret;
666 692
667 if (action == BTRFS_ADD_DELAYED_EXTENT) 693 if (action == BTRFS_ADD_DELAYED_EXTENT)
668 action = BTRFS_ADD_DELAYED_REF; 694 action = BTRFS_ADD_DELAYED_REF;
@@ -693,21 +719,14 @@ add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
693 719
694 trace_add_delayed_tree_ref(ref, full_ref, action); 720 trace_add_delayed_tree_ref(ref, full_ref, action);
695 721
696 spin_lock(&head_ref->lock); 722 ret = add_delayed_ref_tail_merge(trans, delayed_refs, head_ref, ref);
697 existing = tree_insert(&head_ref->ref_root, &ref->rb_node); 723
698 if (existing) { 724 /*
699 update_existing_ref(trans, delayed_refs, head_ref, existing, 725 * XXX: memory should be freed at the same level allocated.
700 ref); 726 * But bad practice is anywhere... Follow it now. Need cleanup.
701 /* 727 */
702 * we've updated the existing ref, free the newly 728 if (ret > 0)
703 * allocated ref
704 */
705 kmem_cache_free(btrfs_delayed_tree_ref_cachep, full_ref); 729 kmem_cache_free(btrfs_delayed_tree_ref_cachep, full_ref);
706 } else {
707 atomic_inc(&delayed_refs->num_entries);
708 trans->delayed_ref_updates++;
709 }
710 spin_unlock(&head_ref->lock);
711} 730}
712 731
713/* 732/*
@@ -721,10 +740,10 @@ add_delayed_data_ref(struct btrfs_fs_info *fs_info,
721 u64 num_bytes, u64 parent, u64 ref_root, u64 owner, 740 u64 num_bytes, u64 parent, u64 ref_root, u64 owner,
722 u64 offset, int action, int no_quota) 741 u64 offset, int action, int no_quota)
723{ 742{
724 struct btrfs_delayed_ref_node *existing;
725 struct btrfs_delayed_data_ref *full_ref; 743 struct btrfs_delayed_data_ref *full_ref;
726 struct btrfs_delayed_ref_root *delayed_refs; 744 struct btrfs_delayed_ref_root *delayed_refs;
727 u64 seq = 0; 745 u64 seq = 0;
746 int ret;
728 747
729 if (action == BTRFS_ADD_DELAYED_EXTENT) 748 if (action == BTRFS_ADD_DELAYED_EXTENT)
730 action = BTRFS_ADD_DELAYED_REF; 749 action = BTRFS_ADD_DELAYED_REF;
@@ -758,21 +777,10 @@ add_delayed_data_ref(struct btrfs_fs_info *fs_info,
758 777
759 trace_add_delayed_data_ref(ref, full_ref, action); 778 trace_add_delayed_data_ref(ref, full_ref, action);
760 779
761 spin_lock(&head_ref->lock); 780 ret = add_delayed_ref_tail_merge(trans, delayed_refs, head_ref, ref);
762 existing = tree_insert(&head_ref->ref_root, &ref->rb_node); 781
763 if (existing) { 782 if (ret > 0)
764 update_existing_ref(trans, delayed_refs, head_ref, existing,
765 ref);
766 /*
767 * we've updated the existing ref, free the newly
768 * allocated ref
769 */
770 kmem_cache_free(btrfs_delayed_data_ref_cachep, full_ref); 783 kmem_cache_free(btrfs_delayed_data_ref_cachep, full_ref);
771 } else {
772 atomic_inc(&delayed_refs->num_entries);
773 trans->delayed_ref_updates++;
774 }
775 spin_unlock(&head_ref->lock);
776} 784}
777 785
778/* 786/*
diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h
index 5eb0892396d0..362ca57cfeb7 100644
--- a/fs/btrfs/delayed-ref.h
+++ b/fs/btrfs/delayed-ref.h
@@ -24,9 +24,25 @@
24#define BTRFS_ADD_DELAYED_EXTENT 3 /* record a full extent allocation */ 24#define BTRFS_ADD_DELAYED_EXTENT 3 /* record a full extent allocation */
25#define BTRFS_UPDATE_DELAYED_HEAD 4 /* not changing ref count on head ref */ 25#define BTRFS_UPDATE_DELAYED_HEAD 4 /* not changing ref count on head ref */
26 26
27/*
28 * XXX: Qu: I really hate the design that ref_head and tree/data ref shares the
29 * same ref_node structure.
30 * Ref_head is in a higher logic level than tree/data ref, and duplicated
31 * bytenr/num_bytes in ref_node is really a waste or memory, they should be
32 * referred from ref_head.
33 * This gets more disgusting after we use list to store tree/data ref in
34 * ref_head. Must clean this mess up later.
35 */
27struct btrfs_delayed_ref_node { 36struct btrfs_delayed_ref_node {
37 /*
38 * ref_head use rb tree, stored in ref_root->href.
39 * indexed by bytenr
40 */
28 struct rb_node rb_node; 41 struct rb_node rb_node;
29 42
43 /*data/tree ref use list, stored in ref_head->ref_list. */
44 struct list_head list;
45
30 /* the starting bytenr of the extent */ 46 /* the starting bytenr of the extent */
31 u64 bytenr; 47 u64 bytenr;
32 48
@@ -83,7 +99,7 @@ struct btrfs_delayed_ref_head {
83 struct mutex mutex; 99 struct mutex mutex;
84 100
85 spinlock_t lock; 101 spinlock_t lock;
86 struct rb_root ref_root; 102 struct list_head ref_list;
87 103
88 struct rb_node href_node; 104 struct rb_node href_node;
89 105
diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c
index 7f8377871283..695363ae1c28 100644
--- a/fs/btrfs/disk-io.c
+++ b/fs/btrfs/disk-io.c
@@ -4062,6 +4062,7 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
4062 4062
4063 while ((node = rb_first(&delayed_refs->href_root)) != NULL) { 4063 while ((node = rb_first(&delayed_refs->href_root)) != NULL) {
4064 struct btrfs_delayed_ref_head *head; 4064 struct btrfs_delayed_ref_head *head;
4065 struct btrfs_delayed_ref_node *tmp;
4065 bool pin_bytes = false; 4066 bool pin_bytes = false;
4066 4067
4067 head = rb_entry(node, struct btrfs_delayed_ref_head, 4068 head = rb_entry(node, struct btrfs_delayed_ref_head,
@@ -4077,11 +4078,10 @@ static int btrfs_destroy_delayed_refs(struct btrfs_transaction *trans,
4077 continue; 4078 continue;
4078 } 4079 }
4079 spin_lock(&head->lock); 4080 spin_lock(&head->lock);
4080 while ((node = rb_first(&head->ref_root)) != NULL) { 4081 list_for_each_entry_safe_reverse(ref, tmp, &head->ref_list,
4081 ref = rb_entry(node, struct btrfs_delayed_ref_node, 4082 list) {
4082 rb_node);
4083 ref->in_tree = 0; 4083 ref->in_tree = 0;
4084 rb_erase(&ref->rb_node, &head->ref_root); 4084 list_del(&ref->list);
4085 atomic_dec(&delayed_refs->num_entries); 4085 atomic_dec(&delayed_refs->num_entries);
4086 btrfs_put_delayed_ref(ref); 4086 btrfs_put_delayed_ref(ref);
4087 } 4087 }
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index 4eefabcc838f..adf0eedde502 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -2323,28 +2323,14 @@ static int run_one_delayed_ref(struct btrfs_trans_handle *trans,
2323 return ret; 2323 return ret;
2324} 2324}
2325 2325
2326static noinline struct btrfs_delayed_ref_node * 2326static inline struct btrfs_delayed_ref_node *
2327select_delayed_ref(struct btrfs_delayed_ref_head *head) 2327select_delayed_ref(struct btrfs_delayed_ref_head *head)
2328{ 2328{
2329 struct rb_node *node; 2329 if (list_empty(&head->ref_list))
2330 struct btrfs_delayed_ref_node *ref, *last = NULL;; 2330 return NULL;
2331 2331
2332 /* 2332 return list_entry(head->ref_list.next, struct btrfs_delayed_ref_node,
2333 * select delayed ref of type BTRFS_ADD_DELAYED_REF first. 2333 list);
2334 * this prevents ref count from going down to zero when
2335 * there still are pending delayed ref.
2336 */
2337 node = rb_first(&head->ref_root);
2338 while (node) {
2339 ref = rb_entry(node, struct btrfs_delayed_ref_node,
2340 rb_node);
2341 if (ref->action == BTRFS_ADD_DELAYED_REF)
2342 return ref;
2343 else if (last == NULL)
2344 last = ref;
2345 node = rb_next(node);
2346 }
2347 return last;
2348} 2334}
2349 2335
2350/* 2336/*
@@ -2396,16 +2382,7 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
2396 } 2382 }
2397 } 2383 }
2398 2384
2399 /*
2400 * We need to try and merge add/drops of the same ref since we
2401 * can run into issues with relocate dropping the implicit ref
2402 * and then it being added back again before the drop can
2403 * finish. If we merged anything we need to re-loop so we can
2404 * get a good ref.
2405 */
2406 spin_lock(&locked_ref->lock); 2385 spin_lock(&locked_ref->lock);
2407 btrfs_merge_delayed_refs(trans, fs_info, delayed_refs,
2408 locked_ref);
2409 2386
2410 /* 2387 /*
2411 * locked_ref is the head node, so we have to go one 2388 * locked_ref is the head node, so we have to go one
@@ -2482,7 +2459,7 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
2482 spin_unlock(&locked_ref->lock); 2459 spin_unlock(&locked_ref->lock);
2483 spin_lock(&delayed_refs->lock); 2460 spin_lock(&delayed_refs->lock);
2484 spin_lock(&locked_ref->lock); 2461 spin_lock(&locked_ref->lock);
2485 if (rb_first(&locked_ref->ref_root) || 2462 if (!list_empty(&locked_ref->ref_list) ||
2486 locked_ref->extent_op) { 2463 locked_ref->extent_op) {
2487 spin_unlock(&locked_ref->lock); 2464 spin_unlock(&locked_ref->lock);
2488 spin_unlock(&delayed_refs->lock); 2465 spin_unlock(&delayed_refs->lock);
@@ -2496,7 +2473,7 @@ static noinline int __btrfs_run_delayed_refs(struct btrfs_trans_handle *trans,
2496 } else { 2473 } else {
2497 actual_count++; 2474 actual_count++;
2498 ref->in_tree = 0; 2475 ref->in_tree = 0;
2499 rb_erase(&ref->rb_node, &locked_ref->ref_root); 2476 list_del(&ref->list);
2500 } 2477 }
2501 atomic_dec(&delayed_refs->num_entries); 2478 atomic_dec(&delayed_refs->num_entries);
2502 2479
@@ -2905,7 +2882,6 @@ static noinline int check_delayed_ref(struct btrfs_trans_handle *trans,
2905 struct btrfs_delayed_ref_node *ref; 2882 struct btrfs_delayed_ref_node *ref;
2906 struct btrfs_delayed_data_ref *data_ref; 2883 struct btrfs_delayed_data_ref *data_ref;
2907 struct btrfs_delayed_ref_root *delayed_refs; 2884 struct btrfs_delayed_ref_root *delayed_refs;
2908 struct rb_node *node;
2909 int ret = 0; 2885 int ret = 0;
2910 2886
2911 delayed_refs = &trans->transaction->delayed_refs; 2887 delayed_refs = &trans->transaction->delayed_refs;
@@ -2934,11 +2910,7 @@ static noinline int check_delayed_ref(struct btrfs_trans_handle *trans,
2934 spin_unlock(&delayed_refs->lock); 2910 spin_unlock(&delayed_refs->lock);
2935 2911
2936 spin_lock(&head->lock); 2912 spin_lock(&head->lock);
2937 node = rb_first(&head->ref_root); 2913 list_for_each_entry(ref, &head->ref_list, list) {
2938 while (node) {
2939 ref = rb_entry(node, struct btrfs_delayed_ref_node, rb_node);
2940 node = rb_next(node);
2941
2942 /* If it's a shared ref we know a cross reference exists */ 2914 /* If it's a shared ref we know a cross reference exists */
2943 if (ref->type != BTRFS_EXTENT_DATA_REF_KEY) { 2915 if (ref->type != BTRFS_EXTENT_DATA_REF_KEY) {
2944 ret = 1; 2916 ret = 1;
@@ -6448,7 +6420,7 @@ static noinline int check_ref_cleanup(struct btrfs_trans_handle *trans,
6448 goto out_delayed_unlock; 6420 goto out_delayed_unlock;
6449 6421
6450 spin_lock(&head->lock); 6422 spin_lock(&head->lock);
6451 if (rb_first(&head->ref_root)) 6423 if (!list_empty(&head->ref_list))
6452 goto out; 6424 goto out;
6453 6425
6454 if (head->extent_op) { 6426 if (head->extent_op) {