|
@@ -189,6 +189,8 @@ static inline void drop_delayed_ref(struct btrfs_trans_handle *trans,
|
|
} else {
|
|
} else {
|
|
assert_spin_locked(&head->lock);
|
|
assert_spin_locked(&head->lock);
|
|
list_del(&ref->list);
|
|
list_del(&ref->list);
|
|
|
|
+ if (!list_empty(&ref->add_list))
|
|
|
|
+ list_del(&ref->add_list);
|
|
}
|
|
}
|
|
ref->in_tree = 0;
|
|
ref->in_tree = 0;
|
|
btrfs_put_delayed_ref(ref);
|
|
btrfs_put_delayed_ref(ref);
|
|
@@ -431,6 +433,15 @@ add_delayed_ref_tail_merge(struct btrfs_trans_handle *trans,
|
|
exist->action = ref->action;
|
|
exist->action = ref->action;
|
|
mod = -exist->ref_mod;
|
|
mod = -exist->ref_mod;
|
|
exist->ref_mod = ref->ref_mod;
|
|
exist->ref_mod = ref->ref_mod;
|
|
|
|
+ if (ref->action == BTRFS_ADD_DELAYED_REF)
|
|
|
|
+ list_add_tail(&exist->add_list,
|
|
|
|
+ &href->ref_add_list);
|
|
|
|
+ else if (ref->action == BTRFS_DROP_DELAYED_REF) {
|
|
|
|
+ ASSERT(!list_empty(&exist->add_list));
|
|
|
|
+ list_del(&exist->add_list);
|
|
|
|
+ } else {
|
|
|
|
+ ASSERT(0);
|
|
|
|
+ }
|
|
} else
|
|
} else
|
|
mod = -ref->ref_mod;
|
|
mod = -ref->ref_mod;
|
|
}
|
|
}
|
|
@@ -444,6 +455,8 @@ add_delayed_ref_tail_merge(struct btrfs_trans_handle *trans,
|
|
|
|
|
|
add_tail:
|
|
add_tail:
|
|
list_add_tail(&ref->list, &href->ref_list);
|
|
list_add_tail(&ref->list, &href->ref_list);
|
|
|
|
+ if (ref->action == BTRFS_ADD_DELAYED_REF)
|
|
|
|
+ list_add_tail(&ref->add_list, &href->ref_add_list);
|
|
atomic_inc(&root->num_entries);
|
|
atomic_inc(&root->num_entries);
|
|
trans->delayed_ref_updates++;
|
|
trans->delayed_ref_updates++;
|
|
spin_unlock(&href->lock);
|
|
spin_unlock(&href->lock);
|
|
@@ -590,6 +603,7 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
|
|
head_ref->must_insert_reserved = must_insert_reserved;
|
|
head_ref->must_insert_reserved = must_insert_reserved;
|
|
head_ref->is_data = is_data;
|
|
head_ref->is_data = is_data;
|
|
INIT_LIST_HEAD(&head_ref->ref_list);
|
|
INIT_LIST_HEAD(&head_ref->ref_list);
|
|
|
|
+ INIT_LIST_HEAD(&head_ref->ref_add_list);
|
|
head_ref->processing = 0;
|
|
head_ref->processing = 0;
|
|
head_ref->total_ref_mod = count_mod;
|
|
head_ref->total_ref_mod = count_mod;
|
|
head_ref->qgroup_reserved = 0;
|
|
head_ref->qgroup_reserved = 0;
|
|
@@ -671,6 +685,8 @@ add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
|
|
ref->is_head = 0;
|
|
ref->is_head = 0;
|
|
ref->in_tree = 1;
|
|
ref->in_tree = 1;
|
|
ref->seq = seq;
|
|
ref->seq = seq;
|
|
|
|
+ INIT_LIST_HEAD(&ref->list);
|
|
|
|
+ INIT_LIST_HEAD(&ref->add_list);
|
|
|
|
|
|
full_ref = btrfs_delayed_node_to_tree_ref(ref);
|
|
full_ref = btrfs_delayed_node_to_tree_ref(ref);
|
|
full_ref->parent = parent;
|
|
full_ref->parent = parent;
|
|
@@ -726,6 +742,8 @@ add_delayed_data_ref(struct btrfs_fs_info *fs_info,
|
|
ref->is_head = 0;
|
|
ref->is_head = 0;
|
|
ref->in_tree = 1;
|
|
ref->in_tree = 1;
|
|
ref->seq = seq;
|
|
ref->seq = seq;
|
|
|
|
+ INIT_LIST_HEAD(&ref->list);
|
|
|
|
+ INIT_LIST_HEAD(&ref->add_list);
|
|
|
|
|
|
full_ref = btrfs_delayed_node_to_data_ref(ref);
|
|
full_ref = btrfs_delayed_node_to_data_ref(ref);
|
|
full_ref->parent = parent;
|
|
full_ref->parent = parent;
|