[PATCH v10 16/21] btrfs: dedupe: Add basic tree structure for on-disk dedupe method
Introduce a new tree, dedupe tree to record on-disk dedupe hash. As a persist hash storage instead of in-memeory only implement. Unlike Liu Bo's implement, in this version we won't do hack for bytenr -> hash search, but add a new type, DEDUP_BYTENR_ITEM for such search case, just like in-memory backend. Signed-off-by: Liu BoSigned-off-by: Wang Xiaoguang Signed-off-by: Qu Wenruo --- Fix a small rebase bug, which missed 4 lines. --- fs/btrfs/ctree.h | 53 +++- fs/btrfs/dedupe.h| 5 + fs/btrfs/disk-io.c | 6 + fs/btrfs/relocation.c| 3 ++- include/trace/events/btrfs.h | 3 ++- 5 files changed, 67 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 0e8933c..659790c 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -100,6 +100,9 @@ struct btrfs_ordered_sum; /* tracks free space in block groups. */ #define BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL +/* on-disk dedupe tree (EXPERIMENTAL) */ +#define BTRFS_DEDUPE_TREE_OBJECTID 11ULL + /* device stats in the device tree */ #define BTRFS_DEV_STATS_OBJECTID 0ULL @@ -538,7 +541,8 @@ struct btrfs_super_block { #define BTRFS_FEATURE_COMPAT_SAFE_CLEAR0ULL #define BTRFS_FEATURE_COMPAT_RO_SUPP \ - (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE) + (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE | \ +BTRFS_FEATURE_COMPAT_RO_DEDUPE) #define BTRFS_FEATURE_COMPAT_RO_SAFE_SET 0ULL #define BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR 0ULL @@ -960,6 +964,36 @@ struct btrfs_csum_item { u8 csum; } __attribute__ ((__packed__)); +/* + * Objectid: 0 + * Type: BTRFS_DEDUPE_STATUS_ITEM_KEY + * Offset: 0 + */ +struct btrfs_dedupe_status_item { + __le64 blocksize; + __le64 limit_nr; + __le16 hash_type; + __le16 backend; +} __attribute__ ((__packed__)); + +/* + * Objectid: Last 64 bit of the hash + * Type: BTRFS_DEDUPE_HASH_ITEM_KEY + * Offset: Bytenr of the hash + * + * Used for hash <-> bytenr search + * Hash exclude the last 64 bit follows + */ + +/* + * Objectid: bytenr + * Type: BTRFS_DEDUPE_BYTENR_ITEM_KEY + * offset: Last 64 bit of the hash + * + * Used for bytenr <-> hash search (for free_extent) + * Its itemsize should always be 0. + */ + struct btrfs_dev_stats_item { /* * grow this item struct at the end for future enhancements and keep @@ -2168,6 +2202,13 @@ struct btrfs_ioctl_defrag_range_args { #define BTRFS_CHUNK_ITEM_KEY 228 /* + * Dedup item and status + */ +#define BTRFS_DEDUPE_STATUS_ITEM_KEY 230 +#define BTRFS_DEDUPE_HASH_ITEM_KEY 231 +#define BTRFS_DEDUPE_BYTENR_ITEM_KEY 232 + +/* * Records the overall state of the qgroups. * There's only one instance of this key present, * (0, BTRFS_QGROUP_STATUS_KEY, 0) @@ -3265,6 +3306,16 @@ static inline unsigned long btrfs_leaf_data(struct extent_buffer *l) return offsetof(struct btrfs_leaf, items); } +/* btrfs_dedupe_status */ +BTRFS_SETGET_FUNCS(dedupe_status_blocksize, struct btrfs_dedupe_status_item, + blocksize, 64); +BTRFS_SETGET_FUNCS(dedupe_status_limit, struct btrfs_dedupe_status_item, + limit_nr, 64); +BTRFS_SETGET_FUNCS(dedupe_status_hash_type, struct btrfs_dedupe_status_item, + hash_type, 16); +BTRFS_SETGET_FUNCS(dedupe_status_backend, struct btrfs_dedupe_status_item, + backend, 16); + /* struct btrfs_file_extent_item */ BTRFS_SETGET_FUNCS(file_extent_type, struct btrfs_file_extent_item, type, 8); BTRFS_SETGET_STACK_FUNCS(stack_file_extent_disk_bytenr, diff --git a/fs/btrfs/dedupe.h b/fs/btrfs/dedupe.h index f5d2b45..1ac1bcb 100644 --- a/fs/btrfs/dedupe.h +++ b/fs/btrfs/dedupe.h @@ -60,6 +60,8 @@ struct btrfs_dedupe_hash { u8 hash[]; }; +struct btrfs_root; + struct btrfs_dedupe_info { /* dedupe blocksize */ u64 blocksize; @@ -75,6 +77,9 @@ struct btrfs_dedupe_info { struct list_head lru_list; u64 limit_nr; u64 current_nr; + + /* for persist data like dedup-hash and dedupe status */ + struct btrfs_root *dedupe_root; }; struct btrfs_trans_handle; diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index ed6a6fd..c7eda03 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -184,6 +184,7 @@ static struct btrfs_lockdep_keyset { { .id = BTRFS_DATA_RELOC_TREE_OBJECTID, .name_stem = "dreloc" }, { .id = BTRFS_UUID_TREE_OBJECTID, .name_stem = "uuid" }, { .id = BTRFS_FREE_SPACE_TREE_OBJECTID, .name_stem = "free-space" }, + { .id = BTRFS_DEDUPE_TREE_OBJECTID, .name_stem = "dedupe" }, { .id = 0, .name_stem = "tree" }, }; @@ -1678,6 +1679,11 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info, if (location->objectid ==
[PATCH v10 16/21] btrfs: dedupe: Add basic tree structure for on-disk dedupe method
Introduce a new tree, dedupe tree to record on-disk dedupe hash. As a persist hash storage instead of in-memeory only implement. Unlike Liu Bo's implement, in this version we won't do hack for bytenr -> hash search, but add a new type, DEDUP_BYTENR_ITEM for such search case, just like in-memory backend. Signed-off-by: Liu BoSigned-off-by: Wang Xiaoguang Signed-off-by: Qu Wenruo --- fs/btrfs/ctree.h | 53 +++- fs/btrfs/dedupe.h| 5 + fs/btrfs/disk-io.c | 6 + fs/btrfs/relocation.c| 3 ++- include/trace/events/btrfs.h | 3 ++- 5 files changed, 67 insertions(+), 3 deletions(-) diff --git a/fs/btrfs/ctree.h b/fs/btrfs/ctree.h index 0e8933c..659790c 100644 --- a/fs/btrfs/ctree.h +++ b/fs/btrfs/ctree.h @@ -100,6 +100,9 @@ struct btrfs_ordered_sum; /* tracks free space in block groups. */ #define BTRFS_FREE_SPACE_TREE_OBJECTID 10ULL +/* on-disk dedupe tree (EXPERIMENTAL) */ +#define BTRFS_DEDUPE_TREE_OBJECTID 11ULL + /* device stats in the device tree */ #define BTRFS_DEV_STATS_OBJECTID 0ULL @@ -538,7 +541,8 @@ struct btrfs_super_block { #define BTRFS_FEATURE_COMPAT_SAFE_CLEAR0ULL #define BTRFS_FEATURE_COMPAT_RO_SUPP \ - (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE) + (BTRFS_FEATURE_COMPAT_RO_FREE_SPACE_TREE | \ +BTRFS_FEATURE_COMPAT_RO_DEDUPE) #define BTRFS_FEATURE_COMPAT_RO_SAFE_SET 0ULL #define BTRFS_FEATURE_COMPAT_RO_SAFE_CLEAR 0ULL @@ -960,6 +964,36 @@ struct btrfs_csum_item { u8 csum; } __attribute__ ((__packed__)); +/* + * Objectid: 0 + * Type: BTRFS_DEDUPE_STATUS_ITEM_KEY + * Offset: 0 + */ +struct btrfs_dedupe_status_item { + __le64 blocksize; + __le64 limit_nr; + __le16 hash_type; + __le16 backend; +} __attribute__ ((__packed__)); + +/* + * Objectid: Last 64 bit of the hash + * Type: BTRFS_DEDUPE_HASH_ITEM_KEY + * Offset: Bytenr of the hash + * + * Used for hash <-> bytenr search + * Hash exclude the last 64 bit follows + */ + +/* + * Objectid: bytenr + * Type: BTRFS_DEDUPE_BYTENR_ITEM_KEY + * offset: Last 64 bit of the hash + * + * Used for bytenr <-> hash search (for free_extent) + * Its itemsize should always be 0. + */ + struct btrfs_dev_stats_item { /* * grow this item struct at the end for future enhancements and keep @@ -2168,6 +2202,13 @@ struct btrfs_ioctl_defrag_range_args { #define BTRFS_CHUNK_ITEM_KEY 228 /* + * Dedup item and status + */ +#define BTRFS_DEDUPE_STATUS_ITEM_KEY 230 +#define BTRFS_DEDUPE_HASH_ITEM_KEY 231 +#define BTRFS_DEDUPE_BYTENR_ITEM_KEY 232 + +/* * Records the overall state of the qgroups. * There's only one instance of this key present, * (0, BTRFS_QGROUP_STATUS_KEY, 0) @@ -3265,6 +3306,16 @@ static inline unsigned long btrfs_leaf_data(struct extent_buffer *l) return offsetof(struct btrfs_leaf, items); } +/* btrfs_dedupe_status */ +BTRFS_SETGET_FUNCS(dedupe_status_blocksize, struct btrfs_dedupe_status_item, + blocksize, 64); +BTRFS_SETGET_FUNCS(dedupe_status_limit, struct btrfs_dedupe_status_item, + limit_nr, 64); +BTRFS_SETGET_FUNCS(dedupe_status_hash_type, struct btrfs_dedupe_status_item, + hash_type, 16); +BTRFS_SETGET_FUNCS(dedupe_status_backend, struct btrfs_dedupe_status_item, + backend, 16); + /* struct btrfs_file_extent_item */ BTRFS_SETGET_FUNCS(file_extent_type, struct btrfs_file_extent_item, type, 8); BTRFS_SETGET_STACK_FUNCS(stack_file_extent_disk_bytenr, diff --git a/fs/btrfs/dedupe.h b/fs/btrfs/dedupe.h index f5d2b45..1ac1bcb 100644 --- a/fs/btrfs/dedupe.h +++ b/fs/btrfs/dedupe.h @@ -60,6 +60,8 @@ struct btrfs_dedupe_hash { u8 hash[]; }; +struct btrfs_root; + struct btrfs_dedupe_info { /* dedupe blocksize */ u64 blocksize; @@ -75,6 +77,9 @@ struct btrfs_dedupe_info { struct list_head lru_list; u64 limit_nr; u64 current_nr; + + /* for persist data like dedup-hash and dedupe status */ + struct btrfs_root *dedupe_root; }; struct btrfs_trans_handle; diff --git a/fs/btrfs/disk-io.c b/fs/btrfs/disk-io.c index ed6a6fd..c7eda03 100644 --- a/fs/btrfs/disk-io.c +++ b/fs/btrfs/disk-io.c @@ -184,6 +184,7 @@ static struct btrfs_lockdep_keyset { { .id = BTRFS_DATA_RELOC_TREE_OBJECTID, .name_stem = "dreloc" }, { .id = BTRFS_UUID_TREE_OBJECTID, .name_stem = "uuid" }, { .id = BTRFS_FREE_SPACE_TREE_OBJECTID, .name_stem = "free-space" }, + { .id = BTRFS_DEDUPE_TREE_OBJECTID, .name_stem = "dedupe" }, { .id = 0, .name_stem = "tree" }, }; @@ -1678,6 +1679,11 @@ struct btrfs_root *btrfs_get_fs_root(struct btrfs_fs_info *fs_info, if (location->objectid == BTRFS_FREE_SPACE_TREE_OBJECTID)