|
@@ -470,7 +470,8 @@ add_tail:
|
|
|
static noinline void
|
|
|
update_existing_head_ref(struct btrfs_delayed_ref_root *delayed_refs,
|
|
|
struct btrfs_delayed_ref_node *existing,
|
|
|
- struct btrfs_delayed_ref_node *update)
|
|
|
+ struct btrfs_delayed_ref_node *update,
|
|
|
+ int *old_ref_mod_ret)
|
|
|
{
|
|
|
struct btrfs_delayed_ref_head *existing_ref;
|
|
|
struct btrfs_delayed_ref_head *ref;
|
|
@@ -523,6 +524,8 @@ update_existing_head_ref(struct btrfs_delayed_ref_root *delayed_refs,
|
|
|
* currently, for refs we just added we know we're a-ok.
|
|
|
*/
|
|
|
old_ref_mod = existing_ref->total_ref_mod;
|
|
|
+ if (old_ref_mod_ret)
|
|
|
+ *old_ref_mod_ret = old_ref_mod;
|
|
|
existing->ref_mod += update->ref_mod;
|
|
|
existing_ref->total_ref_mod += update->ref_mod;
|
|
|
|
|
@@ -550,7 +553,8 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
|
|
|
struct btrfs_delayed_ref_node *ref,
|
|
|
struct btrfs_qgroup_extent_record *qrecord,
|
|
|
u64 bytenr, u64 num_bytes, u64 ref_root, u64 reserved,
|
|
|
- int action, int is_data, int *qrecord_inserted_ret)
|
|
|
+ int action, int is_data, int *qrecord_inserted_ret,
|
|
|
+ int *old_ref_mod, int *new_ref_mod)
|
|
|
{
|
|
|
struct btrfs_delayed_ref_head *existing;
|
|
|
struct btrfs_delayed_ref_head *head_ref = NULL;
|
|
@@ -638,7 +642,8 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
|
|
|
if (existing) {
|
|
|
WARN_ON(ref_root && reserved && existing->qgroup_ref_root
|
|
|
&& existing->qgroup_reserved);
|
|
|
- update_existing_head_ref(delayed_refs, &existing->node, ref);
|
|
|
+ update_existing_head_ref(delayed_refs, &existing->node, ref,
|
|
|
+ old_ref_mod);
|
|
|
/*
|
|
|
* we've updated the existing ref, free the newly
|
|
|
* allocated ref
|
|
@@ -646,6 +651,8 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
|
|
|
kmem_cache_free(btrfs_delayed_ref_head_cachep, head_ref);
|
|
|
head_ref = existing;
|
|
|
} else {
|
|
|
+ if (old_ref_mod)
|
|
|
+ *old_ref_mod = 0;
|
|
|
if (is_data && count_mod < 0)
|
|
|
delayed_refs->pending_csums += num_bytes;
|
|
|
delayed_refs->num_heads++;
|
|
@@ -655,6 +662,8 @@ add_delayed_ref_head(struct btrfs_fs_info *fs_info,
|
|
|
}
|
|
|
if (qrecord_inserted_ret)
|
|
|
*qrecord_inserted_ret = qrecord_inserted;
|
|
|
+ if (new_ref_mod)
|
|
|
+ *new_ref_mod = head_ref->total_ref_mod;
|
|
|
return head_ref;
|
|
|
}
|
|
|
|
|
@@ -778,7 +787,8 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
|
|
|
struct btrfs_trans_handle *trans,
|
|
|
u64 bytenr, u64 num_bytes, u64 parent,
|
|
|
u64 ref_root, int level, int action,
|
|
|
- struct btrfs_delayed_extent_op *extent_op)
|
|
|
+ struct btrfs_delayed_extent_op *extent_op,
|
|
|
+ int *old_ref_mod, int *new_ref_mod)
|
|
|
{
|
|
|
struct btrfs_delayed_tree_ref *ref;
|
|
|
struct btrfs_delayed_ref_head *head_ref;
|
|
@@ -813,7 +823,8 @@ int btrfs_add_delayed_tree_ref(struct btrfs_fs_info *fs_info,
|
|
|
*/
|
|
|
head_ref = add_delayed_ref_head(fs_info, trans, &head_ref->node, record,
|
|
|
bytenr, num_bytes, 0, 0, action, 0,
|
|
|
- &qrecord_inserted);
|
|
|
+ &qrecord_inserted, old_ref_mod,
|
|
|
+ new_ref_mod);
|
|
|
|
|
|
add_delayed_tree_ref(fs_info, trans, head_ref, &ref->node, bytenr,
|
|
|
num_bytes, parent, ref_root, level, action);
|
|
@@ -838,7 +849,8 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
|
|
|
struct btrfs_trans_handle *trans,
|
|
|
u64 bytenr, u64 num_bytes,
|
|
|
u64 parent, u64 ref_root,
|
|
|
- u64 owner, u64 offset, u64 reserved, int action)
|
|
|
+ u64 owner, u64 offset, u64 reserved, int action,
|
|
|
+ int *old_ref_mod, int *new_ref_mod)
|
|
|
{
|
|
|
struct btrfs_delayed_data_ref *ref;
|
|
|
struct btrfs_delayed_ref_head *head_ref;
|
|
@@ -878,7 +890,8 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info *fs_info,
|
|
|
*/
|
|
|
head_ref = add_delayed_ref_head(fs_info, trans, &head_ref->node, record,
|
|
|
bytenr, num_bytes, ref_root, reserved,
|
|
|
- action, 1, &qrecord_inserted);
|
|
|
+ action, 1, &qrecord_inserted,
|
|
|
+ old_ref_mod, new_ref_mod);
|
|
|
|
|
|
add_delayed_data_ref(fs_info, trans, head_ref, &ref->node, bytenr,
|
|
|
num_bytes, parent, ref_root, owner, offset,
|
|
@@ -909,7 +922,7 @@ int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
|
|
|
|
|
|
add_delayed_ref_head(fs_info, trans, &head_ref->node, NULL, bytenr,
|
|
|
num_bytes, 0, 0, BTRFS_UPDATE_DELAYED_HEAD,
|
|
|
- extent_op->is_data, NULL);
|
|
|
+ extent_op->is_data, NULL, NULL, NULL);
|
|
|
|
|
|
spin_unlock(&delayed_refs->lock);
|
|
|
return 0;
|