Add support for delayed_ref to handle dedup_hash.

Signed-off-by: Wang Xiaoguang <wangxg.f...@cn.fujitsu.com>
Signed-off-by: Qu Wenruo <quwen...@cn.fujitsu.com>
---
v3:
  Newly introduced.
---
 fs/btrfs/ctree.h       |  4 +++-
 fs/btrfs/delayed-ref.c |  3 ++-
 fs/btrfs/delayed-ref.h |  9 ++++++++-
 fs/btrfs/extent-tree.c | 17 ++++++++++++-----
 fs/btrfs/inode.c       |  2 +-
 5 files changed, 26 insertions(+), 9 deletions(-)

diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h
index 450790b..aa7f5fb 100644
--- a/fs/btrfs/ctree.h
+++ b/fs/btrfs/ctree.h
@@ -48,6 +48,7 @@ extern struct kmem_cache *btrfs_bit_radix_cachep;
 extern struct kmem_cache *btrfs_path_cachep;
 extern struct kmem_cache *btrfs_free_space_cachep;
 struct btrfs_ordered_sum;
+struct btrfs_dedup_hash;
 
 #ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
 #define STATIC noinline
@@ -3436,7 +3437,8 @@ int btrfs_alloc_reserved_file_extent(struct 
btrfs_trans_handle *trans,
                                     struct btrfs_root *root,
                                     u64 root_objectid, u64 owner,
                                     u64 offset, u64 ram_bytes,
-                                    struct btrfs_key *ins);
+                                    struct btrfs_key *ins,
+                                    struct btrfs_dedup_hash *hash);
 int btrfs_alloc_logged_file_extent(struct btrfs_trans_handle *trans,
                                   struct btrfs_root *root,
                                   u64 root_objectid, u64 owner, u64 offset,
diff --git a/fs/btrfs/delayed-ref.c b/fs/btrfs/delayed-ref.c
index 94609ec..fb9f47b 100644
--- a/fs/btrfs/delayed-ref.c
+++ b/fs/btrfs/delayed-ref.c
@@ -812,7 +812,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info 
*fs_info,
                               u64 bytenr, u64 num_bytes,
                               u64 parent, u64 ref_root,
                               u64 owner, u64 offset, u64 reserved, int action,
-                              int atomic)
+                              int atomic, struct btrfs_dedup_hash *hash)
 {
        struct btrfs_delayed_data_ref *ref;
        struct btrfs_delayed_ref_head *head_ref;
@@ -846,6 +846,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info 
*fs_info,
        }
 
        head_ref->extent_op = NULL;
+       ref->hash = hash;
 
        delayed_refs = &trans->transaction->delayed_refs;
 
diff --git a/fs/btrfs/delayed-ref.h b/fs/btrfs/delayed-ref.h
index 8928fe7..d67766b 100644
--- a/fs/btrfs/delayed-ref.h
+++ b/fs/btrfs/delayed-ref.h
@@ -24,6 +24,7 @@
 #define BTRFS_ADD_DELAYED_EXTENT 3 /* record a full extent allocation */
 #define BTRFS_UPDATE_DELAYED_HEAD 4 /* not changing ref count on head ref */
 
+struct btrfs_dedup_hash;
 /*
  * XXX: Qu: I really hate the design that ref_head and tree/data ref shares the
  * same ref_node structure.
@@ -152,6 +153,12 @@ struct btrfs_delayed_data_ref {
        u64 parent;
        u64 objectid;
        u64 offset;
+
+       /*
+        * For dedup hash miss case, to add it into dedup tree at
+        * run_delayed_ref() time.
+        */
+       struct btrfs_dedup_hash *hash;
 };
 
 struct btrfs_delayed_ref_root {
@@ -249,7 +256,7 @@ int btrfs_add_delayed_data_ref(struct btrfs_fs_info 
*fs_info,
                               u64 bytenr, u64 num_bytes,
                               u64 parent, u64 ref_root,
                               u64 owner, u64 offset, u64 reserved, int action,
-                              int atomic);
+                              int atomic, struct btrfs_dedup_hash *hash);
 int btrfs_add_delayed_qgroup_reserve(struct btrfs_fs_info *fs_info,
                                     struct btrfs_trans_handle *trans,
                                     u64 ref_root, u64 bytenr, u64 num_bytes);
diff --git a/fs/btrfs/extent-tree.c b/fs/btrfs/extent-tree.c
index d80f74d..a2e4c2b 100644
--- a/fs/btrfs/extent-tree.c
+++ b/fs/btrfs/extent-tree.c
@@ -36,6 +36,7 @@
 #include "math.h"
 #include "sysfs.h"
 #include "qgroup.h"
+#include "dedup.h"
 
 #undef SCRAMBLE_DELAYED_REFS
 
@@ -2089,7 +2090,7 @@ int btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
                ret = btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
                                        num_bytes, parent, root_objectid,
                                        owner, offset, 0,
-                                       BTRFS_ADD_DELAYED_REF, 0);
+                                       BTRFS_ADD_DELAYED_REF, 0, NULL);
        }
        return ret;
 }
@@ -2109,7 +2110,7 @@ int btrfs_inc_extent_ref_atomic(struct btrfs_trans_handle 
*trans,
                return -EINVAL;
        return btrfs_add_delayed_data_ref(fs_info, trans, bytenr,
                        num_bytes, parent, root_objectid,
-                       owner, offset, 0, BTRFS_ADD_DELAYED_REF, 1);
+                       owner, offset, 0, BTRFS_ADD_DELAYED_REF, 1, NULL);
 }
 
 static int __btrfs_inc_extent_ref(struct btrfs_trans_handle *trans,
@@ -2196,6 +2197,10 @@ static int run_delayed_data_ref(struct 
btrfs_trans_handle *trans,
                parent = ref->parent;
        ref_root = ref->root;
 
+       /* Add dedup hash into hash tree and free it */
+       btrfs_dedup_add(trans, root, ref->hash);
+       kfree(ref->hash);
+
        if (node->action == BTRFS_ADD_DELAYED_REF && insert_reserved) {
                if (extent_op)
                        flags |= extent_op->flags_to_set;
@@ -6854,7 +6859,8 @@ int btrfs_free_extent(struct btrfs_trans_handle *trans, 
struct btrfs_root *root,
                                                num_bytes,
                                                parent, root_objectid, owner,
                                                offset, 0,
-                                               BTRFS_DROP_DELAYED_REF, 0);
+                                               BTRFS_DROP_DELAYED_REF, 0,
+                                               NULL);
        }
        return ret;
 }
@@ -7786,7 +7792,8 @@ int btrfs_alloc_reserved_file_extent(struct 
btrfs_trans_handle *trans,
                                     struct btrfs_root *root,
                                     u64 root_objectid, u64 owner,
                                     u64 offset, u64 ram_bytes,
-                                    struct btrfs_key *ins)
+                                    struct btrfs_key *ins,
+                                    struct btrfs_dedup_hash *hash)
 {
        int ret;
 
@@ -7796,7 +7803,7 @@ int btrfs_alloc_reserved_file_extent(struct 
btrfs_trans_handle *trans,
                                         ins->offset, 0,
                                         root_objectid, owner, offset,
                                         ram_bytes, BTRFS_ADD_DELAYED_EXTENT,
-                                        0);
+                                        0, hash);
        return ret;
 }
 
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index f82d1f4..832a733 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -2134,7 +2134,7 @@ static int insert_reserved_file_extent(struct 
btrfs_trans_handle *trans,
        ret = btrfs_alloc_reserved_file_extent(trans, root,
                                        root->root_key.objectid,
                                        btrfs_ino(inode), file_pos,
-                                       ram_bytes, &ins);
+                                       ram_bytes, &ins, NULL);
        /*
         * Release the reserved range from inode dirty range map, as it is
         * already moved into delayed_ref_head
-- 
2.6.4



--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to