From: Wang Xiaoguang <wangxg.f...@cn.fujitsu.com> Unlike in-memory or on-disk dedupe method, only SHA256 hash method is supported yet, so implement btrfs_dedupe_calc_hash() interface using SHA256.
Signed-off-by: Qu Wenruo <quwen...@cn.fujitsu.com> Signed-off-by: Wang Xiaoguang <wangxg.f...@cn.fujitsu.com> Reviewed-by: Josef Bacik <jba...@fb.com> Signed-off-by: Lu Fengqi <lufq.f...@cn.fujitsu.com> --- fs/btrfs/dedupe.c | 50 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/fs/btrfs/dedupe.c b/fs/btrfs/dedupe.c index 03ad41423c01..6199215022e6 100644 --- a/fs/btrfs/dedupe.c +++ b/fs/btrfs/dedupe.c @@ -644,3 +644,53 @@ int btrfs_dedupe_search(struct btrfs_fs_info *fs_info, } return ret; } + +int btrfs_dedupe_calc_hash(struct btrfs_fs_info *fs_info, + struct inode *inode, u64 start, + struct btrfs_dedupe_hash *hash) +{ + int i; + int ret; + struct page *p; + struct shash_desc *shash; + struct btrfs_dedupe_info *dedupe_info = fs_info->dedupe_info; + struct crypto_shash *tfm = dedupe_info->dedupe_driver; + u64 dedupe_bs; + u64 sectorsize = fs_info->sectorsize; + + shash = kmalloc(sizeof(*shash) + crypto_shash_descsize(tfm), GFP_NOFS); + if (!shash) + return -ENOMEM; + + if (!fs_info->dedupe_enabled || !hash) + return 0; + + if (WARN_ON(dedupe_info == NULL)) + return -EINVAL; + + WARN_ON(!IS_ALIGNED(start, sectorsize)); + + dedupe_bs = dedupe_info->blocksize; + + shash->tfm = tfm; + shash->flags = 0; + ret = crypto_shash_init(shash); + if (ret) + return ret; + for (i = 0; sectorsize * i < dedupe_bs; i++) { + char *d; + + p = find_get_page(inode->i_mapping, + (start >> PAGE_SHIFT) + i); + if (WARN_ON(!p)) + return -ENOENT; + d = kmap(p); + ret = crypto_shash_update(shash, d, sectorsize); + kunmap(p); + put_page(p); + if (ret) + return ret; + } + ret = crypto_shash_final(shash, hash->hash); + return ret; +} -- 2.19.1