aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosef Bacik <josef@toxicpanda.com>2017-10-19 14:15:59 -0400
committerDavid Sterba <dsterba@suse.com>2017-11-01 15:45:35 -0400
commit1d148e5939f55c76d06108548c7c0226e55dde8e (patch)
tree17940e2cdbdc55ae521a1cce4bae65517e94f798
parentc7ad7c843965d8691269f581e132633a4ca9ef91 (diff)
btrfs: add a comp_refs() helper
Instead of open-coding the delayed ref comparisons, add a helper to do the comparisons generically and use that everywhere. We compare sequence numbers last for following patches. Signed-off-by: Josef Bacik <jbacik@fb.com> Signed-off-by: David Sterba <dsterba@suse.com>
-rw-r--r--fs/btrfs/delayed-ref.c54
1 files changed, 30 insertions, 24 deletions
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
index bc940bb374cf..8c7d7db01f7a 100644
--- a/fs/btrfs/delayed-ref.c
+++ b/fs/btrfs/delayed-ref.c
@@ -85,6 +85,34 @@ static int comp_data_refs(struct btrfs_delayed_data_ref *ref1,
85 return 0; 85 return 0;
86} 86}
87 87
88static int comp_refs(struct btrfs_delayed_ref_node *ref1,
89 struct btrfs_delayed_ref_node *ref2,
90 bool check_seq)
91{
92 int ret = 0;
93
94 if (ref1->type < ref2->type)
95 return -1;
96 if (ref1->type > ref2->type)
97 return 1;
98 if (ref1->type == BTRFS_TREE_BLOCK_REF_KEY ||
99 ref1->type == BTRFS_SHARED_BLOCK_REF_KEY)
100 ret = comp_tree_refs(btrfs_delayed_node_to_tree_ref(ref1),
101 btrfs_delayed_node_to_tree_ref(ref2));
102 else
103 ret = comp_data_refs(btrfs_delayed_node_to_data_ref(ref1),
104 btrfs_delayed_node_to_data_ref(ref2));
105 if (ret)
106 return ret;
107 if (check_seq) {
108 if (ref1->seq < ref2->seq)
109 return -1;
110 if (ref1->seq > ref2->seq)
111 return 1;
112 }
113 return 0;
114}
115
88/* insert a new ref to head ref rbtree */ 116/* insert a new ref to head ref rbtree */
89static struct btrfs_delayed_ref_head *htree_insert(struct rb_root *root, 117static struct btrfs_delayed_ref_head *htree_insert(struct rb_root *root,
90 struct rb_node *node) 118 struct rb_node *node)
@@ -217,18 +245,7 @@ static bool merge_ref(struct btrfs_trans_handle *trans,
217 if (seq && next->seq >= seq) 245 if (seq && next->seq >= seq)
218 goto next; 246 goto next;
219 247
220 if (next->type != ref->type) 248 if (comp_refs(ref, next, false))
221 goto next;
222
223 if ((ref->type == BTRFS_TREE_BLOCK_REF_KEY ||
224 ref->type == BTRFS_SHARED_BLOCK_REF_KEY) &&
225 comp_tree_refs(btrfs_delayed_node_to_tree_ref(ref),
226 btrfs_delayed_node_to_tree_ref(next)))
227 goto next;
228 if ((ref->type == BTRFS_EXTENT_DATA_REF_KEY ||
229 ref->type == BTRFS_SHARED_DATA_REF_KEY) &&
230 comp_data_refs(btrfs_delayed_node_to_data_ref(ref),
231 btrfs_delayed_node_to_data_ref(next)))
232 goto next; 249 goto next;
233 250
234 if (ref->action == next->action) { 251 if (ref->action == next->action) {
@@ -402,18 +419,7 @@ add_delayed_ref_tail_merge(struct btrfs_trans_handle *trans,
402 exist = list_entry(href->ref_list.prev, struct btrfs_delayed_ref_node, 419 exist = list_entry(href->ref_list.prev, struct btrfs_delayed_ref_node,
403 list); 420 list);
404 /* No need to compare bytenr nor is_head */ 421 /* No need to compare bytenr nor is_head */
405 if (exist->type != ref->type || exist->seq != ref->seq) 422 if (comp_refs(exist, ref, true))
406 goto add_tail;
407
408 if ((exist->type == BTRFS_TREE_BLOCK_REF_KEY ||
409 exist->type == BTRFS_SHARED_BLOCK_REF_KEY) &&
410 comp_tree_refs(btrfs_delayed_node_to_tree_ref(exist),
411 btrfs_delayed_node_to_tree_ref(ref)))
412 goto add_tail;
413 if ((exist->type == BTRFS_EXTENT_DATA_REF_KEY ||
414 exist->type == BTRFS_SHARED_DATA_REF_KEY) &&
415 comp_data_refs(btrfs_delayed_node_to_data_ref(exist),
416 btrfs_delayed_node_to_data_ref(ref)))
417 goto add_tail; 423 goto add_tail;
418 424
419 /* Now we are sure we can merge */ 425 /* Now we are sure we can merge */