diff --git a/dm-dedup-hash.c b/dm-dedup-hash.c index ebb272f..13738d2 100644 --- a/dm-dedup-hash.c +++ b/dm-dedup-hash.c @@ -26,26 +26,57 @@ * this scenario, we moved the declaration and initialization out * of critical path. */ -static struct hash_desc *slot_to_desc(struct hash_desc_table *desc_table, - unsigned long slot) +#if SHASH +static struct shash_desc * +#else +static struct hash_desc * +#endif +slot_to_desc(struct hash_desc_table *desc_table, unsigned long slot) { BUG_ON(slot >= DEDUP_HASH_DESC_COUNT); - return &(desc_table->desc[slot]); +#if SHASH + return &desc_table->desc[slot*desc_table->desc_state_size]; +#else + return &desc_table->desc[slot]; +#endif } struct hash_desc_table *desc_table_init(char *hash_alg) { int i = 0; +#if SHASH + struct shash_desc *desc; + struct crypto_shash *tfm = NULL; +#else struct hash_desc *desc; +#endif struct hash_desc_table *desc_table; - desc_table = kmalloc(sizeof(struct hash_desc_table), GFP_NOIO); + desc_table = kzalloc(sizeof(struct hash_desc_table), GFP_NOIO); if (!desc_table) return ERR_PTR(-ENOMEM); - +#if SHASH + /* + * This snippet is only to get size of state for + * if sha1 sha1_state, if sha256 sha256_state like generically + */ + tfm = crypto_alloc_hash(hash_alg, 0, CRYPTO_ALG_ASYNC); + desc_table->desc_state_size = sizeof(struct shash_desc) + + crypto_shash_descsize(tfm); + crypto_free_hash(tfm); + tfm = NULL; + desc_table->desc = + kzalloc(desc_table->desc_state_size * DEDUP_HASH_DESC_COUNT, GFP_NOIO); + if (!desc_table->desc) + return ERR_PTR(-ENOMEM); +#endif for (i = 0; i < DEDUP_HASH_DESC_COUNT; i++) { desc_table->free_bitmap[i] = true; +#if SHASH + desc = &desc_table->desc[i*desc_table->desc_state_size]; +#else desc = &desc_table->desc[i]; +#endif desc->flags = 0; desc->tfm = crypto_alloc_hash(hash_alg, 0, CRYPTO_ALG_ASYNC); if (IS_ERR(desc->tfm)) @@ -60,13 +91,22 @@ struct hash_desc_table *desc_table_init(char *hash_alg) void desc_table_deinit(struct hash_desc_table *desc_table) { int i = 0; +#if SHASH + struct shash_desc *desc; +#else struct hash_desc *desc; - +#endif for (i = 0; i < DEDUP_HASH_DESC_COUNT; i++) { - desc = desc_table->desc + i; +#if SHASH + desc = &desc_table->desc[i*desc_table->desc_state_size]; +#else + desc = &desc_table->desc[i]; +#endif crypto_free_hash(desc->tfm); } - +#if SHASH + kfree(desc_table->desc); +#endif kfree(desc_table); desc_table = NULL; } @@ -106,12 +146,20 @@ static void put_slot(struct hash_desc_table *desc_table, unsigned long slot) unsigned int get_hash_digestsize(struct hash_desc_table *desc_table) { unsigned long slot; +#if SHASH + struct shash_desc *desc; +#else struct hash_desc *desc; +#endif + unsigned int ret = 0; slot = get_next_slot(desc_table); desc = slot_to_desc(desc_table, slot); - return crypto_hash_digestsize(desc->tfm); + ret = crypto_hash_digestsize(desc->tfm); + put_slot(desc_table, slot); + + return ret; } int compute_hash_bio(struct hash_desc_table *desc_table, @@ -122,8 +170,11 @@ int compute_hash_bio(struct hash_desc_table *desc_table, unsigned long slot; struct bio_vec bvec; struct bvec_iter iter; +#if SHASH + struct shash_desc *desc; +#else struct hash_desc *desc; - +#endif slot = get_next_slot(desc_table); desc = slot_to_desc(desc_table, slot); @@ -133,9 +184,20 @@ int compute_hash_bio(struct hash_desc_table *desc_table, sg_init_table(&sg, 1); __bio_for_each_segment(bvec, bio, iter, bio->bi_iter) { - sg_set_page(&sg, bvec.bv_page, bvec.bv_len, - bvec.bv_offset); - crypto_hash_update(desc, &sg, sg.length); +#if 0 + /* + * TODO: Don't know why the hash generation is not unique even + * same data being fed to hash_interface. Need to look at it. + * As of now alternete added. + */ + sg_set_page(&sg, bvec.bv_page, bvec.bv_len, + bvec.bv_offset); + crypto_hash_update(desc, &sg, sg.length); +#else + u8 _b[4096] = {0}; + memcpy(_b,(page_address(bvec.bv_page)+bvec.bv_offset),bvec.bv_len); + crypto_hash_update(desc, _b, bvec.bv_len); +#endif } crypto_hash_final(desc, hash); diff --git a/dm-dedup-hash.h b/dm-dedup-hash.h index 9eb791d..c1c12c5 100644 --- a/dm-dedup-hash.h +++ b/dm-dedup-hash.h @@ -13,10 +13,43 @@ #ifndef DM_DEDUP_HASH_H #define DM_DEDUP_HASH_H +#include + #define DEDUP_HASH_DESC_COUNT 128 +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,6,0) //4.6.0-rc1 +#define SHASH 1 +#define crypto_alloc_hash crypto_alloc_shash +#define crypto_hash_final crypto_shash_final +#define crypto_hash_init crypto_shash_init +#define crypto_hash_update crypto_shash_update +#define crypto_hash_digestsize crypto_shash_digestsize +#define crypto_free_hash crypto_free_shash +#define hash_desc shash_desc +#endif + +static inline int crypto_has_hash(const char *alg_name, u32 type, u32 mask) +{ + type &= ~CRYPTO_ALG_TYPE_MASK; + mask &= ~CRYPTO_ALG_TYPE_MASK; + type |= CRYPTO_ALG_TYPE_SHASH; + mask |= CRYPTO_ALG_TYPE_HASH_MASK; + + return crypto_has_alg(alg_name, type, mask); +} + struct hash_desc_table { +#if SHASH + union{ + /*Made as pointer from array to extra data allocation for context/state*/ + struct shash_desc *shd;//[DEDUP_HASH_DESC_COUNT]; + /*Added void pointer for better access, to increment byte wise*/ + void *desc; + }; + uint32_t desc_state_size; +#else struct hash_desc desc[DEDUP_HASH_DESC_COUNT]; +#endif bool free_bitmap[DEDUP_HASH_DESC_COUNT]; atomic_long_t slot_counter; } /*desc_table*/; diff --git a/dm-dedup-target.c b/dm-dedup-target.c index c450d89..f670502 100644 --- a/dm-dedup-target.c +++ b/dm-dedup-target.c @@ -26,6 +26,13 @@ #define MIN_DATA_DEV_BLOCK_SIZE (4 * 1024) #define MAX_DATA_DEV_BLOCK_SIZE (1024 * 1024) +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,8,0) // 4.8-rc1 +#define bi_rw bi_opf +#ifndef REQ_FLUSH +#define REQ_FLUSH REQ_PREFLUSH +#endif +#endif + struct on_disk_stats { uint64_t physical_block_counter; uint64_t logical_block_counter;