[dm-devel] [PATCH RFC 01/10] dm-dedup: main data structures
Vasily Tarasov
tarasov at vasily.name
Thu Apr 17 19:10:47 UTC 2014
We maintain one dedup_config structure for every dm-dedup target instance.
Every target instance has a metadata backend associated with it. Metadata
backends should implement operations defined in the metadata_ops structure.
Every backend should support two key-value stores: (1) sparse store, where the
hash-to-pbn mapping (the hash index) is stored; and (2) linear store, where the
lbn-to-pbn mapping is stored.
Signed-off-by: Vasily Tarasov <tarasov at vasily.name>
---
drivers/md/dm-dedup-backend.h | 114 +++++++++++++++++++++++++++++++++++++++++
drivers/md/dm-dedup-kvstore.h | 51 ++++++++++++++++++
drivers/md/dm-dedup-target.h | 100 ++++++++++++++++++++++++++++++++++++
3 files changed, 265 insertions(+), 0 deletions(-)
create mode 100644 drivers/md/dm-dedup-backend.h
create mode 100644 drivers/md/dm-dedup-kvstore.h
create mode 100644 drivers/md/dm-dedup-target.h
diff --git a/drivers/md/dm-dedup-backend.h b/drivers/md/dm-dedup-backend.h
new file mode 100644
index 0000000..9fa572b
--- /dev/null
+++ b/drivers/md/dm-dedup-backend.h
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2012-2014 Vasily Tarasov
+ * Copyright (C) 2012-2014 Geoff Kuenning
+ * Copyright (C) 2012-2014 Sonam Mandal
+ * Copyright (C) 2012-2014 Karthikeyani Palanisami
+ * Copyright (C) 2012-2014 Philip Shilane
+ * Copyright (C) 2012-2014 Sagar Trehan
+ * Copyright (C) 2012-2014 Erez Zadok
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef BACKEND_H
+#define BACKEND_H
+
+struct metadata; /* metadata store identifier */
+struct kvstore; /* key-value store identifier */
+
+#define BF_NEGATIVE -1
+#define BF_POSITIVE 0
+
+struct metadata_ops {
+ /*
+ * Returns ERR_PTR(*) on error.
+ * Valid pointer on success.
+ */
+ struct metadata * (*init_meta)(void *init_param, bool reconstruct);
+
+ void (*exit_meta)(struct metadata *md);
+
+ /*
+ * Creates linear key-value store. Ksize and vsize in bytes.
+ * If ksize or vsize are equal to zero, it means that keys
+ * and values will be of a variable size. kmax is the
+ * maximum _value_ of the key. If kmax is equal to zero,
+ * then maximum is not known by the caller.
+ *
+ * Returns -ERR_PTR(*) on error.
+ * Valid pointer on success.
+ */
+ struct kvstore * (*kvs_create_linear)(struct metadata *md,
+ uint32_t ksize, uint32_t vsize, uint32_t kmax,
+ bool reconstruct);
+ /*
+ * Creates sparse key-value store. Ksize and vsize in bytes.
+ * If ksize or vsize are equal to zero, it means that keys
+ * and values will be of a variable size. knummax is the
+ * maximum _number_ of the keys. If keymax is equal to zero,
+ * then maximum is not known by the caller.
+ *
+ * Returns -ERR_PTR(*) on error.
+ * Valid pointer on success.
+ */
+ struct kvstore * (*kvs_create_sparse)(struct metadata *md,
+ uint32_t ksize, uint32_t vsize, uint32_t knummax,
+ bool reconstruct);
+
+ /*
+ * Returns -ERR* on error.
+ * Returns 0 on success. In this case, "blockn" contains a newly
+ * allocated block number.
+ */
+ int (*alloc_data_block)(struct metadata *md, uint64_t *blockn);
+
+ /*
+ * Returns -ERR* on error.
+ * Returns 0 on success.
+ */
+ int (*inc_refcount)(struct metadata *md, uint64_t blockn);
+
+ /*
+ * Returns -ERR* on error.
+ * Returns 0 on success.
+ */
+ int (*dec_refcount)(struct metadata *md, uint64_t blockn);
+
+ /*
+ * Returns -ERR* on error.
+ * Returns 0 on success.
+ */
+ int (*get_refcount)(struct metadata *md, uint64_t blockn);
+
+ /*
+ * Returns -ERR on error.
+ * Return 0 on success.
+ */
+ int (*flush_meta)(struct metadata *md);
+
+ /*
+ * Returns the private data stored in the metadata.
+ *
+ * Returns -ERR* on error.
+ * Returns 0 on success.
+ */
+ int (*get_private_data)(struct metadata *md, void **data,
+ uint32_t size);
+
+ /*
+ * Fills in private data stored in the metadata.
+ *
+ * Returns -ERR* on error.
+ * Returns 0 on success.
+ */
+ int (*set_private_data)(struct metadata *md, void *data, uint32_t size);
+
+ /*
+ * This is a hack to drop cache. In future we want to implement
+ * proper message passing interface, to accomplish this and other
+ * tasks.
+ */
+ void (*flush_bufio_cache)(struct metadata *md);
+};
+
+#endif /* BACKEND_H */
diff --git a/drivers/md/dm-dedup-kvstore.h b/drivers/md/dm-dedup-kvstore.h
new file mode 100644
index 0000000..365a7f6
--- /dev/null
+++ b/drivers/md/dm-dedup-kvstore.h
@@ -0,0 +1,51 @@
+/*
+ * Copyright (C) 2012-2014 Vasily Tarasov
+ * Copyright (C) 2012-2014 Geoff Kuenning
+ * Copyright (C) 2012-2014 Sonam Mandal
+ * Copyright (C) 2012-2014 Karthikeyani Palanisami
+ * Copyright (C) 2012-2014 Philip Shilane
+ * Copyright (C) 2012-2014 Sagar Trehan
+ * Copyright (C) 2012-2014 Erez Zadok
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef KVSTORE_H
+#define KVSTORE_H
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/device-mapper.h>
+#include <linux/dm-io.h>
+#include <linux/dm-kcopyd.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <asm/current.h>
+#include <linux/string.h>
+#include <linux/gfp.h>
+
+#include <linux/scatterlist.h>
+#include <asm/page.h>
+#include <asm/unaligned.h>
+#include <crypto/hash.h>
+#include <crypto/md5.h>
+#include <crypto/algapi.h>
+
+#include "dm-dedup-target.h"
+
+struct kvstore {
+ uint32_t vsize;
+ uint32_t ksize;
+
+ int (*kvs_delete)(struct kvstore *kvs, void *key, int32_t ksize);
+ int (*kvs_lookup)(struct kvstore *kvs, void *key, int32_t ksize,
+ void *value, int32_t *vsize);
+ int (*kvs_insert)(struct kvstore *kvs, void *key, int32_t ksize,
+ void *value, int32_t vsize);
+ int (*kvs_iterate)(struct kvstore *kvs, int (*itr_action)
+ (void *key, int32_t ksize, void *value,
+ int32_t vsize, void *data), void *data);
+};
+
+#endif /* KVSTORE_H */
diff --git a/drivers/md/dm-dedup-target.h b/drivers/md/dm-dedup-target.h
new file mode 100644
index 0000000..703ad04
--- /dev/null
+++ b/drivers/md/dm-dedup-target.h
@@ -0,0 +1,100 @@
+/*
+ * Copyright (C) 2012-2014 Vasily Tarasov
+ * Copyright (C) 2012-2014 Geoff Kuenning
+ * Copyright (C) 2012-2014 Sonam Mandal
+ * Copyright (C) 2012-2014 Karthikeyani Palanisami
+ * Copyright (C) 2012-2014 Philip Shilane
+ * Copyright (C) 2012-2014 Sagar Trehan
+ * Copyright (C) 2012-2014 Erez Zadok
+ *
+ * This file is released under the GPL.
+ */
+
+#ifndef DM_DEDUP_H
+#define DM_DEDUP_H
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/device-mapper.h>
+#include <linux/dm-io.h>
+#include <linux/dm-kcopyd.h>
+#include <linux/list.h>
+#include <linux/err.h>
+#include <asm/current.h>
+#include <linux/string.h>
+#include <linux/gfp.h>
+#include <linux/delay.h>
+#include <linux/time.h>
+#include <linux/parser.h>
+#include <linux/blk_types.h>
+#include <linux/mempool.h>
+
+#include <linux/scatterlist.h>
+#include <asm/page.h>
+#include <asm/unaligned.h>
+#include <crypto/hash.h>
+#include <crypto/md5.h>
+#include <crypto/sha.h>
+#include <crypto/algapi.h>
+
+#define DM_MSG_PREFIX "dedup-mod"
+
+#define CRYPTO_ALG_NAME_LEN 16
+#define MAX_DIGEST_SIZE SHA256_DIGEST_SIZE
+
+#define MIN_DEDUP_WORK_IO 16
+
+/* Per target instance structure */
+struct dedup_config {
+ struct dm_dev *data_dev;
+ struct dm_dev *metadata_dev;
+
+ uint32_t block_size; /* in bytes */
+ uint32_t sectors_per_block;
+
+ uint32_t pblocks; /* physical blocks */
+ uint32_t lblocks; /* logical blocks */
+
+ struct workqueue_struct *workqueue;
+
+ struct hash_desc_table *desc_table;
+
+ uint64_t logical_block_counter; /* Total number of used LBNs */
+ uint64_t physical_block_counter;/* Total number of allocated PBNs */
+
+ uint64_t writes; /* total number of writes */
+ uint64_t dupwrites;
+ uint64_t uniqwrites;
+ uint64_t reads_on_writes;
+ uint64_t overwrites; /* writes to a prev. written offset */
+ uint64_t newwrites; /* writes to never written offsets */
+
+ struct dm_io_client *io_client; /* used for read-on-write
+ of misaligned requests */
+
+ struct metadata_ops *mdops;
+ struct metadata *bmd;
+ struct kvstore *kvs_hash_pbn;
+ struct kvstore *kvs_lbn_pbn;
+
+ char crypto_alg[CRYPTO_ALG_NAME_LEN];
+ int crypto_key_size;
+
+ uint32_t flushrq; /* after how many writes call flush */
+ uint64_t writes_after_flush; /* # of writes after the last flush */
+
+ mempool_t *dedup_work_pool; /* Dedup work pool */
+};
+
+/* Value of the HASH-PBN key-value store */
+struct hash_pbn_value {
+ uint64_t pbn; /* in blocks */
+};
+
+/* Value of the LBN-PBN key-value store */
+struct lbn_pbn_value {
+ uint64_t pbn; /* in blocks */
+};
+
+#endif /* DM_DEDUP_H */
--
1.7.1
More information about the dm-devel
mailing list