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>
This commit is contained in:
parent
c7ad7c8439
commit
1d148e5939
@ -85,6 +85,34 @@ static int comp_data_refs(struct btrfs_delayed_data_ref *ref1,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int comp_refs(struct btrfs_delayed_ref_node *ref1,
|
||||||
|
struct btrfs_delayed_ref_node *ref2,
|
||||||
|
bool check_seq)
|
||||||
|
{
|
||||||
|
int ret = 0;
|
||||||
|
|
||||||
|
if (ref1->type < ref2->type)
|
||||||
|
return -1;
|
||||||
|
if (ref1->type > ref2->type)
|
||||||
|
return 1;
|
||||||
|
if (ref1->type == BTRFS_TREE_BLOCK_REF_KEY ||
|
||||||
|
ref1->type == BTRFS_SHARED_BLOCK_REF_KEY)
|
||||||
|
ret = comp_tree_refs(btrfs_delayed_node_to_tree_ref(ref1),
|
||||||
|
btrfs_delayed_node_to_tree_ref(ref2));
|
||||||
|
else
|
||||||
|
ret = comp_data_refs(btrfs_delayed_node_to_data_ref(ref1),
|
||||||
|
btrfs_delayed_node_to_data_ref(ref2));
|
||||||
|
if (ret)
|
||||||
|
return ret;
|
||||||
|
if (check_seq) {
|
||||||
|
if (ref1->seq < ref2->seq)
|
||||||
|
return -1;
|
||||||
|
if (ref1->seq > ref2->seq)
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* insert a new ref to head ref rbtree */
|
/* insert a new ref to head ref rbtree */
|
||||||
static struct btrfs_delayed_ref_head *htree_insert(struct rb_root *root,
|
static struct btrfs_delayed_ref_head *htree_insert(struct rb_root *root,
|
||||||
struct rb_node *node)
|
struct rb_node *node)
|
||||||
@ -217,18 +245,7 @@ static bool merge_ref(struct btrfs_trans_handle *trans,
|
|||||||
if (seq && next->seq >= seq)
|
if (seq && next->seq >= seq)
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
if (next->type != ref->type)
|
if (comp_refs(ref, next, false))
|
||||||
goto next;
|
|
||||||
|
|
||||||
if ((ref->type == BTRFS_TREE_BLOCK_REF_KEY ||
|
|
||||||
ref->type == BTRFS_SHARED_BLOCK_REF_KEY) &&
|
|
||||||
comp_tree_refs(btrfs_delayed_node_to_tree_ref(ref),
|
|
||||||
btrfs_delayed_node_to_tree_ref(next)))
|
|
||||||
goto next;
|
|
||||||
if ((ref->type == BTRFS_EXTENT_DATA_REF_KEY ||
|
|
||||||
ref->type == BTRFS_SHARED_DATA_REF_KEY) &&
|
|
||||||
comp_data_refs(btrfs_delayed_node_to_data_ref(ref),
|
|
||||||
btrfs_delayed_node_to_data_ref(next)))
|
|
||||||
goto next;
|
goto next;
|
||||||
|
|
||||||
if (ref->action == next->action) {
|
if (ref->action == next->action) {
|
||||||
@ -402,18 +419,7 @@ add_delayed_ref_tail_merge(struct btrfs_trans_handle *trans,
|
|||||||
exist = list_entry(href->ref_list.prev, struct btrfs_delayed_ref_node,
|
exist = list_entry(href->ref_list.prev, struct btrfs_delayed_ref_node,
|
||||||
list);
|
list);
|
||||||
/* No need to compare bytenr nor is_head */
|
/* No need to compare bytenr nor is_head */
|
||||||
if (exist->type != ref->type || exist->seq != ref->seq)
|
if (comp_refs(exist, ref, true))
|
||||||
goto add_tail;
|
|
||||||
|
|
||||||
if ((exist->type == BTRFS_TREE_BLOCK_REF_KEY ||
|
|
||||||
exist->type == BTRFS_SHARED_BLOCK_REF_KEY) &&
|
|
||||||
comp_tree_refs(btrfs_delayed_node_to_tree_ref(exist),
|
|
||||||
btrfs_delayed_node_to_tree_ref(ref)))
|
|
||||||
goto add_tail;
|
|
||||||
if ((exist->type == BTRFS_EXTENT_DATA_REF_KEY ||
|
|
||||||
exist->type == BTRFS_SHARED_DATA_REF_KEY) &&
|
|
||||||
comp_data_refs(btrfs_delayed_node_to_data_ref(exist),
|
|
||||||
btrfs_delayed_node_to_data_ref(ref)))
|
|
||||||
goto add_tail;
|
goto add_tail;
|
||||||
|
|
||||||
/* Now we are sure we can merge */
|
/* Now we are sure we can merge */
|
||||||
|
Loading…
Reference in New Issue
Block a user