summaryrefslogtreecommitdiff
path: root/include/linux/lightnvm.h
diff options
context:
space:
mode:
authorJavier González <jg@lightnvm.io>2016-01-12 09:49:33 +0300
committerJens Axboe <axboe@fb.com>2016-01-12 18:21:17 +0300
commitff0e498bfa185fad5e86c4c7a2db4f9648d2344f (patch)
tree52cf32454a651b0f90e81987353dc1ce0fbad5a7 /include/linux/lightnvm.h
parentb5d4acd4cbf5029a2616084d9e9f392046d53a37 (diff)
downloadlinux-ff0e498bfa185fad5e86c4c7a2db4f9648d2344f.tar.xz
lightnvm: manage open and closed blocks separately
LightNVM targets need to know the state of the flash block when doing flash optimizations. An example is implementing a write buffer to respect the flash page size. Currently, block state is not accounted for; the media manager only differentiates among free, bad and in-use blocks. This patch adds the logic in the generic media manager to enable targets manage blocks into open and close separately, and it implements such management in rrpc. It also adds a set of flags to describe the state of the block (open, closed, free, bad). In order to avoid taking two locks (nvm_lun and rrpc_lun) consecutively, we introduce lockless get_/put_block primitives so that the open and close list locks and future common logic is handled within the nvm_lun lock. Signed-off-by: Javier González <javier@cnexlabs.com> Signed-off-by: Matias Bjørling <m@bjorling.me> Signed-off-by: Jens Axboe <axboe@fb.com>
Diffstat (limited to 'include/linux/lightnvm.h')
-rw-r--r--include/linux/lightnvm.h25
1 files changed, 22 insertions, 3 deletions
diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
index 4a700a137460..aa35907714b8 100644
--- a/include/linux/lightnvm.h
+++ b/include/linux/lightnvm.h
@@ -229,12 +229,25 @@ struct nvm_lun {
int lun_id;
int chnl_id;
- unsigned int nr_inuse_blocks; /* Number of used blocks */
+ /* It is up to the target to mark blocks as closed. If the target does
+ * not do it, all blocks are marked as open, and nr_open_blocks
+ * represents the number of blocks in use
+ */
+ unsigned int nr_open_blocks; /* Number of used, writable blocks */
+ unsigned int nr_closed_blocks; /* Number of used, read-only blocks */
unsigned int nr_free_blocks; /* Number of unused blocks */
unsigned int nr_bad_blocks; /* Number of bad blocks */
- struct nvm_block *blocks;
spinlock_t lock;
+
+ struct nvm_block *blocks;
+};
+
+enum {
+ NVM_BLK_ST_FREE = 0x1, /* Free block */
+ NVM_BLK_ST_OPEN = 0x2, /* Open block - read-write */
+ NVM_BLK_ST_CLOSED = 0x4, /* Closed block - read-only */
+ NVM_BLK_ST_BAD = 0x8, /* Bad block */
};
struct nvm_block {
@@ -243,7 +256,7 @@ struct nvm_block {
unsigned long id;
void *priv;
- int type;
+ int state;
};
struct nvm_dev {
@@ -404,6 +417,8 @@ struct nvmm_type {
nvmm_unregister_fn *unregister_mgr;
/* Block administration callbacks */
+ nvmm_get_blk_fn *get_blk_unlocked;
+ nvmm_put_blk_fn *put_blk_unlocked;
nvmm_get_blk_fn *get_blk;
nvmm_put_blk_fn *put_blk;
nvmm_open_blk_fn *open_blk;
@@ -424,6 +439,10 @@ struct nvmm_type {
extern int nvm_register_mgr(struct nvmm_type *);
extern void nvm_unregister_mgr(struct nvmm_type *);
+extern struct nvm_block *nvm_get_blk_unlocked(struct nvm_dev *,
+ struct nvm_lun *, unsigned long);
+extern void nvm_put_blk_unlocked(struct nvm_dev *, struct nvm_block *);
+
extern struct nvm_block *nvm_get_blk(struct nvm_dev *, struct nvm_lun *,
unsigned long);
extern void nvm_put_blk(struct nvm_dev *, struct nvm_block *);