aboutsummaryrefslogtreecommitdiffstats
path: root/fs/btrfs/delayed-ref.c
diff options
context:
space:
mode:
authorArne Jansen <sensille@gmx.net>2011-09-14 06:37:00 -0400
committerJan Schmidt <list.btrfs@jan-o-sch.net>2012-01-04 10:12:42 -0500
commit00f04b88791ff49dc64ada18819d40a5b0671709 (patch)
treefd85a5f4b374aac035388b0cbf8ef572578d5578 /fs/btrfs/delayed-ref.c
parent5b25f70f4200766355cdabda604e131d2fb6010d (diff)
Btrfs: add sequence numbers to delayed refs
Sequence numbers are needed to reconstruct the backrefs of a given extent to a certain point in time. The total set of backrefs consist of the set of backrefs recorded on disk plus the enqueued delayed refs for it that existed at that moment. This patch also adds a list that records all delayed refs which are currently in the process of being added. When walking all refs of an extent in btrfs_find_all_roots(), we freeze the current state of delayed refs, honor anythinh up to this point and prevent processing newer delayed refs to assert consistency. Signed-off-by: Arne Jansen <sensille@gmx.net> Signed-off-by: Jan Schmidt <list.btrfs@jan-o-sch.net>
Diffstat (limited to 'fs/btrfs/delayed-ref.c')
-rw-r--r--fs/btrfs/delayed-ref.c34
1 files changed, 34 insertions, 0 deletions
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
index babd37badb43..a405db0320e8 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),
@@ -209,6 +214,24 @@ int btrfs_delayed_ref_lock(struct btrfs_trans_handle *trans,
209 return 0; 214 return 0;
210} 215}
211 216
217int btrfs_check_delayed_seq(struct btrfs_delayed_ref_root *delayed_refs,
218 u64 seq)
219{
220 struct seq_list *elem;
221
222 assert_spin_locked(&delayed_refs->lock);
223 if (list_empty(&delayed_refs->seq_head))
224 return 0;
225
226 elem = list_first_entry(&delayed_refs->seq_head, struct seq_list, list);
227 if (seq >= elem->seq) {
228 pr_debug("holding back delayed_ref %llu, lowest is %llu (%p)\n",
229 seq, elem->seq, delayed_refs);
230 return 1;
231 }
232 return 0;
233}
234
212int btrfs_find_ref_cluster(struct btrfs_trans_handle *trans, 235int btrfs_find_ref_cluster(struct btrfs_trans_handle *trans,
213 struct list_head *cluster, u64 start) 236 struct list_head *cluster, u64 start)
214{ 237{
@@ -438,6 +461,7 @@ static noinline int add_delayed_ref_head(struct btrfs_fs_info *fs_info,
438 ref->action = 0; 461 ref->action = 0;
439 ref->is_head = 1; 462 ref->is_head = 1;
440 ref->in_tree = 1; 463 ref->in_tree = 1;
464 ref->seq = 0;
441 465
442 head_ref = btrfs_delayed_node_to_head(ref); 466 head_ref = btrfs_delayed_node_to_head(ref);
443 head_ref->must_insert_reserved = must_insert_reserved; 467 head_ref->must_insert_reserved = must_insert_reserved;
@@ -479,6 +503,7 @@ static noinline int add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
479 struct btrfs_delayed_ref_node *existing; 503 struct btrfs_delayed_ref_node *existing;
480 struct btrfs_delayed_tree_ref *full_ref; 504 struct btrfs_delayed_tree_ref *full_ref;
481 struct btrfs_delayed_ref_root *delayed_refs; 505 struct btrfs_delayed_ref_root *delayed_refs;
506 u64 seq = 0;
482 507
483 if (action == BTRFS_ADD_DELAYED_EXTENT) 508 if (action == BTRFS_ADD_DELAYED_EXTENT)
484 action = BTRFS_ADD_DELAYED_REF; 509 action = BTRFS_ADD_DELAYED_REF;
@@ -494,6 +519,10 @@ static noinline int add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
494 ref->is_head = 0; 519 ref->is_head = 0;
495 ref->in_tree = 1; 520 ref->in_tree = 1;
496 521
522 if (need_ref_seq(for_cow, ref_root))
523 seq = inc_delayed_seq(delayed_refs);
524 ref->seq = seq;
525
497 full_ref = btrfs_delayed_node_to_tree_ref(ref); 526 full_ref = btrfs_delayed_node_to_tree_ref(ref);
498 full_ref->parent = parent; 527 full_ref->parent = parent;
499 full_ref->root = ref_root; 528 full_ref->root = ref_root;
@@ -534,6 +563,7 @@ static noinline int add_delayed_data_ref(struct btrfs_fs_info *fs_info,
534 struct btrfs_delayed_ref_node *existing; 563 struct btrfs_delayed_ref_node *existing;
535 struct btrfs_delayed_data_ref *full_ref; 564 struct btrfs_delayed_data_ref *full_ref;
536 struct btrfs_delayed_ref_root *delayed_refs; 565 struct btrfs_delayed_ref_root *delayed_refs;
566 u64 seq = 0;
537 567
538 if (action == BTRFS_ADD_DELAYED_EXTENT) 568 if (action == BTRFS_ADD_DELAYED_EXTENT)
539 action = BTRFS_ADD_DELAYED_REF; 569 action = BTRFS_ADD_DELAYED_REF;
@@ -549,6 +579,10 @@ static noinline int add_delayed_data_ref(struct btrfs_fs_info *fs_info,
549 ref->is_head = 0; 579 ref->is_head = 0;
550 ref->in_tree = 1; 580 ref->in_tree = 1;
551 581
582 if (need_ref_seq(for_cow, ref_root))
583 seq = inc_delayed_seq(delayed_refs);
584 ref->seq = seq;
585
552 full_ref = btrfs_delayed_node_to_data_ref(ref); 586 full_ref = btrfs_delayed_node_to_data_ref(ref);
553 full_ref->parent = parent; 587 full_ref->parent = parent;
554 full_ref->root = ref_root; 588 full_ref->root = ref_root;