Btrfs: return old and new total ref mods when adding delayed refs
authorOmar Sandoval <osandov@fb.com>
Tue, 6 Jun 2017 23:45:30 +0000 (16:45 -0700)
committerDavid Sterba <dsterba@suse.com>
Thu, 29 Jun 2017 18:17:01 +0000 (20:17 +0200)
We need this to decide when to account pinned bytes.

Signed-off-by: Omar Sandoval <osandov@fb.com>
Tested-by: Holger Hoffstätte <holger@applied-asynchrony.com>
Signed-off-by: David Sterba <dsterba@suse.com>
fs/btrfs/delayed-ref.c
fs/btrfs/delayed-ref.h
fs/btrfs/extent-tree.c

index be70d90dfee591953d53100b3c872d0efc5f324f..93ffa898df6d8811a87907e719f7d4470f37ad6b 100644 (file)
@@ -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;
index c0264ff01b53cfe9e2fa44a7cdd7e9352012f0ee..ce88e4ac5276f44901e4f882b2948233bb26b9a6 100644 (file)
@@ -247,12 +247,14 @@ 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);
 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);
 int btrfs_add_delayed_extent_op(struct btrfs_fs_info *fs_info,
                                struct btrfs_trans_handle *trans,
                                u64 bytenr, u64 num_bytes,
index 40c80ed8d1f98c6cb1aca2c4f0ffb50eefb6575a..8121a78f6cbd69bcee32d65baaa36915326065ca 100644 (file)
@@ -2120,14 +2120,16 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
 
        if (owner < BTRFS_FIRST_FREE_OBJECTID) {
                ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr,
-                                       num_bytes,
-                                       parent, root_objectid, (int)owner,
-                                       BTRFS_ADD_DELAYED_REF, NULL);
+                                                num_bytes, parent,
+                                                root_objectid, (int)owner,
+                                                BTRFS_ADD_DELAYED_REF, NULL,
+                                                NULL, NULL);
        } else {
                ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
-                                       num_bytes, parent, root_objectid,
-                                       owner, offset, 0,
-                                       BTRFS_ADD_DELAYED_REF);
+                                                num_bytes, parent,
+                                                root_objectid, owner, offset,
+                                                0, BTRFS_ADD_DELAYED_REF, NULL,
+                                                NULL);
        }
        return ret;
 }
@@ -7184,12 +7186,12 @@ void btrfs_free_tree_block(struct btrfs_trans_handle *trans,
        int ret;
 
        if (root->root_key.objectid != BTRFS_TREE_LOG_OBJECTID) {
-               ret = btrfs_add_delayed_tree_ref(fs_info, trans,
-                                                buf->start, buf->len,
-                                                parent,
+               ret = btrfs_add_delayed_tree_ref(fs_info, trans, buf->start,
+                                                buf->len, parent,
                                                 root->root_key.objectid,
                                                 btrfs_header_level(buf),
-                                                BTRFS_DROP_DELAYED_REF, NULL);
+                                                BTRFS_DROP_DELAYED_REF, NULL,
+                                                NULL, NULL);
                BUG_ON(ret); /* -ENOMEM */
        }
 
@@ -7257,15 +7259,16 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans,
                ret = 0;
        } else if (owner < BTRFS_FIRST_FREE_OBJECTID) {
                ret = btrfs_add_delayed_tree_ref(fs_info, trans, bytenr,
-                                       num_bytes,
-                                       parent, root_objectid, (int)owner,
-                                       BTRFS_DROP_DELAYED_REF, NULL);
+                                                num_bytes, parent,
+                                                root_objectid, (int)owner,
+                                                BTRFS_DROP_DELAYED_REF, NULL,
+                                                NULL, NULL);
        } else {
                ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
-                                               num_bytes,
-                                               parent, root_objectid, owner,
-                                               offset, 0,
-                                               BTRFS_DROP_DELAYED_REF);
+                                                num_bytes, parent,
+                                                root_objectid, owner, offset,
+                                                0, BTRFS_DROP_DELAYED_REF,
+                                                NULL, NULL);
        }
        return ret;
 }
@@ -8213,9 +8216,9 @@ int btrfs_alloc_reserved_file_extent(struct btrfs_trans_handle *trans,
        BUG_ON(root_objectid == BTRFS_TREE_LOG_OBJECTID);
 
        ret = btrfs_add_delayed_data_ref(fs_info, trans, ins->objectid,
-                                        ins->offset, 0,
-                                        root_objectid, owner, offset,
-                                        ram_bytes, BTRFS_ADD_DELAYED_EXTENT);
+                                        ins->offset, 0, root_objectid, owner,
+                                        offset, ram_bytes,
+                                        BTRFS_ADD_DELAYED_EXTENT, NULL, NULL);
        return ret;
 }
 
@@ -8435,11 +8438,11 @@ struct extent_buffer *btrfs_alloc_tree_block(struct btrfs_trans_handle *trans,
                extent_op->is_data = false;
                extent_op->level = level;
 
-               ret = btrfs_add_delayed_tree_ref(fs_info, trans,
-                                                ins.objectid, ins.offset,
-                                                parent, root_objectid, level,
+               ret = btrfs_add_delayed_tree_ref(fs_info, trans, ins.objectid,
+                                                ins.offset, parent,
+                                                root_objectid, level,
                                                 BTRFS_ADD_DELAYED_EXTENT,
-                                                extent_op);
+                                                extent_op, NULL, NULL);
                if (ret)
                        goto out_free_delayed;
        }