From: Wenwei Tao <ww.tao0320@gmail.com>
To: mb@lightnvm.io, jg@lightnvm.io
Cc: linux-kernel@vger.kernel.org, linux-block@vger.kernel.org
Subject: [PATCH v5 2/3] lightnvm: add non-continuous lun target creation support
Date: Sun, 20 Mar 2016 00:58:57 +0800 [thread overview]
Message-ID: <1458406738-4828-2-git-send-email-ww.tao0320@gmail.com> (raw)
In-Reply-To: <1458406738-4828-1-git-send-email-ww.tao0320@gmail.com>
When create a target, we specify the begin lunid and
the end lunid, and get the corresponding continuous
luns from media manager, if one of the luns is not free,
we failed to create the target, even if the device's
total free luns are enough.
So add non-continuous lun target creation support,
thus we can improve the backend device's space utilization.
Signed-off-by: Wenwei Tao <ww.tao0320@gmail.com>
---
Changes since v4
-fix target creation fail.
-move code concerning the per-lun reverse translation
map to a new patch.
Changes since v3
-limit list luns to 768, thus we don't go
above a single memory page.
-move NVM_DEV_FREE_LUNS to its own patch and
rename it to NVM_DEV_LUNS_STATUS.
-insert and delete some lines to increase
readability.
-rebase to for-4.6
Changes since v2
-rebase on for-next branch
-move luns bitmap to PATCH 2
-remove the logic to dynamically select another lun than
the one requested
-implment lunid list in the lnvm ioctl interface
Changes since v1
-use NVM_FIXED instead NVM_C_FIXED in gennvm_get_lun
-add target creation flags check
-rebase to v4.5-rc1
drivers/lightnvm/core.c | 64 ++++++++++++++++++++++++-------------------
drivers/lightnvm/rrpc.c | 31 +++++++++++++++++----
include/linux/lightnvm.h | 3 +-
include/uapi/linux/lightnvm.h | 9 ++++++
4 files changed, 73 insertions(+), 34 deletions(-)
diff --git a/drivers/lightnvm/core.c b/drivers/lightnvm/core.c
index 0dc9a80..84bc72d 100644
--- a/drivers/lightnvm/core.c
+++ b/drivers/lightnvm/core.c
@@ -625,7 +625,7 @@ static const struct block_device_operations nvm_fops = {
static int nvm_create_target(struct nvm_dev *dev,
struct nvm_ioctl_create *create)
{
- struct nvm_ioctl_create_simple *s = &create->conf.s;
+ struct nvm_ioctl_create_conf *conf = &create->conf;
struct request_queue *tqueue;
struct gendisk *tdisk;
struct nvm_tgt_type *tt;
@@ -674,7 +674,7 @@ static int nvm_create_target(struct nvm_dev *dev,
tdisk->fops = &nvm_fops;
tdisk->queue = tqueue;
- targetdata = tt->init(dev, tdisk, s->lun_begin, s->lun_end);
+ targetdata = tt->init(dev, tdisk, conf);
if (IS_ERR(targetdata))
goto err_init;
@@ -726,7 +726,6 @@ static void nvm_remove_target(struct nvm_target *t)
static int __nvm_configure_create(struct nvm_ioctl_create *create)
{
struct nvm_dev *dev;
- struct nvm_ioctl_create_simple *s;
down_write(&nvm_lock);
dev = nvm_find_nvm_dev(create->dev);
@@ -736,17 +735,11 @@ static int __nvm_configure_create(struct nvm_ioctl_create *create)
return -EINVAL;
}
- if (create->conf.type != NVM_CONFIG_TYPE_SIMPLE) {
+ if (create->conf.type != NVM_CONFIG_TYPE_SIMPLE &&
+ create->conf.type != NVM_CONFIG_TYPE_LIST) {
pr_err("nvm: config type not valid\n");
return -EINVAL;
}
- s = &create->conf.s;
-
- if (s->lun_begin > s->lun_end || s->lun_end > dev->nr_luns) {
- pr_err("nvm: lun out of bound (%u:%u > %u)\n",
- s->lun_begin, s->lun_end, dev->nr_luns);
- return -EINVAL;
- }
return nvm_create_target(dev, create);
}
@@ -824,24 +817,29 @@ static int nvm_configure_remove(const char *val)
static int nvm_configure_create(const char *val)
{
- struct nvm_ioctl_create create;
+ struct nvm_ioctl_create *create;
char opcode;
int lun_begin, lun_end, ret;
- ret = sscanf(val, "%c %256s %256s %48s %u:%u", &opcode, create.dev,
- create.tgtname, create.tgttype,
+ create = kzalloc(sizeof(struct nvm_ioctl_create), GFP_KERNEL);
+ if (!create)
+ return -ENOMEM;
+
+ ret = sscanf(val, "%c %256s %256s %48s %u:%u", &opcode, create->dev,
+ create->tgtname, create->tgttype,
&lun_begin, &lun_end);
if (ret != 6) {
pr_err("nvm: invalid command. Use \"opcode device name tgttype lun_begin:lun_end\".\n");
+ kfree(create);
return -EINVAL;
}
- create.flags = 0;
- create.conf.type = NVM_CONFIG_TYPE_SIMPLE;
- create.conf.s.lun_begin = lun_begin;
- create.conf.s.lun_end = lun_end;
+ create->flags = 0;
+ create->conf.type = NVM_CONFIG_TYPE_SIMPLE;
+ create->conf.s.lun_begin = lun_begin;
+ create->conf.s.lun_end = lun_end;
- return __nvm_configure_create(&create);
+ return __nvm_configure_create(create);
}
@@ -993,24 +991,34 @@ static long nvm_ioctl_get_devices(struct file *file, void __user *arg)
static long nvm_ioctl_dev_create(struct file *file, void __user *arg)
{
- struct nvm_ioctl_create create;
+ struct nvm_ioctl_create *create;
+ long ret = -EINVAL;
if (!capable(CAP_SYS_ADMIN))
return -EPERM;
+ create = kzalloc(sizeof(struct nvm_ioctl_create), GFP_KERNEL);
+ if (!create)
+ return -ENOMEM;
- if (copy_from_user(&create, arg, sizeof(struct nvm_ioctl_create)))
- return -EFAULT;
+ if (copy_from_user(create, arg, sizeof(struct nvm_ioctl_create))) {
+ ret = -EFAULT;
+ goto out;
+ }
- create.dev[DISK_NAME_LEN - 1] = '\0';
- create.tgttype[NVM_TTYPE_NAME_MAX - 1] = '\0';
- create.tgtname[DISK_NAME_LEN - 1] = '\0';
+ create->dev[DISK_NAME_LEN - 1] = '\0';
+ create->tgttype[NVM_TTYPE_NAME_MAX - 1] = '\0';
+ create->tgtname[DISK_NAME_LEN - 1] = '\0';
- if (create.flags != 0) {
+ if (create->flags != 0) {
pr_err("nvm: no flags supported\n");
- return -EINVAL;
+ goto out;
}
- return __nvm_configure_create(&create);
+ ret = __nvm_configure_create(create);
+
+out:
+ kfree(create);
+ return ret;
}
static long nvm_ioctl_dev_remove(struct file *file, void __user *arg)
diff --git a/drivers/lightnvm/rrpc.c b/drivers/lightnvm/rrpc.c
index 4cc157a..9ed8374 100644
--- a/drivers/lightnvm/rrpc.c
+++ b/drivers/lightnvm/rrpc.c
@@ -1205,7 +1205,7 @@ static int rrpc_lun_init(struct rrpc *rrpc, struct rrpc_lun *rlun,
return 0;
}
-static int rrpc_luns_init(struct rrpc *rrpc, int lun_begin, int lun_end)
+static int rrpc_luns_init(struct rrpc *rrpc, struct nvm_ioctl_create_conf *conf)
{
struct nvm_dev *dev = rrpc->dev;
struct rrpc_lun *rlun;
@@ -1223,8 +1223,21 @@ static int rrpc_luns_init(struct rrpc *rrpc, int lun_begin, int lun_end)
/* 1:1 mapping */
for (i = 0; i < rrpc->nr_luns; i++) {
- int lunid = lun_begin + i;
struct nvm_lun *lun;
+ int lunid;
+
+ if (conf->type == NVM_CONFIG_TYPE_SIMPLE)
+ lunid = conf->s.lun_begin + i;
+ else if (conf->type == NVM_CONFIG_TYPE_LIST)
+ lunid = conf->l.lunid[i];
+ else
+ goto err;
+
+ if (lunid >= dev->nr_luns) {
+ pr_err("rrpc: lun out of bound (%u >= %u)\n",
+ lunid, dev->nr_luns);
+ goto err;
+ }
if (dev->mt->reserve_lun(dev, lunid)) {
pr_err("rrpc: lun %u is already allocated\n", lunid);
@@ -1395,7 +1408,7 @@ err:
static struct nvm_tgt_type tt_rrpc;
static void *rrpc_init(struct nvm_dev *dev, struct gendisk *tdisk,
- int lun_begin, int lun_end)
+ struct nvm_ioctl_create_conf *conf)
{
struct request_queue *bqueue = dev->q;
struct request_queue *tqueue = tdisk->queue;
@@ -1421,7 +1434,15 @@ static void *rrpc_init(struct nvm_dev *dev, struct gendisk *tdisk,
spin_lock_init(&rrpc->bio_lock);
INIT_WORK(&rrpc->ws_requeue, rrpc_requeue);
- rrpc->nr_luns = lun_end - lun_begin + 1;
+ if (conf->type == NVM_CONFIG_TYPE_SIMPLE)
+ rrpc->nr_luns = conf->s.lun_end - conf->s.lun_begin + 1;
+
+ else if (conf->type == NVM_CONFIG_TYPE_LIST)
+ rrpc->nr_luns = conf->l.nr_luns;
+ else {
+ kfree(rrpc);
+ return ERR_PTR(-EINVAL);
+ }
/* simple round-robin strategy */
atomic_set(&rrpc->next_lun, -1);
@@ -1433,7 +1454,7 @@ static void *rrpc_init(struct nvm_dev *dev, struct gendisk *tdisk,
}
rrpc->soffset = soffset;
- ret = rrpc_luns_init(rrpc, lun_begin, lun_end);
+ ret = rrpc_luns_init(rrpc, conf);
if (ret) {
pr_err("nvm: rrpc: could not initialize luns\n");
goto err;
diff --git a/include/linux/lightnvm.h b/include/linux/lightnvm.h
index 419a3db..b941a8c 100644
--- a/include/linux/lightnvm.h
+++ b/include/linux/lightnvm.h
@@ -431,7 +431,8 @@ static inline int ppa_to_slc(struct nvm_dev *dev, int slc_pg)
typedef blk_qc_t (nvm_tgt_make_rq_fn)(struct request_queue *, struct bio *);
typedef sector_t (nvm_tgt_capacity_fn)(void *);
-typedef void *(nvm_tgt_init_fn)(struct nvm_dev *, struct gendisk *, int, int);
+typedef void *(nvm_tgt_init_fn)(struct nvm_dev *, struct gendisk *,
+ struct nvm_ioctl_create_conf *);
typedef void (nvm_tgt_exit_fn)(void *);
struct nvm_tgt_type {
diff --git a/include/uapi/linux/lightnvm.h b/include/uapi/linux/lightnvm.h
index 774a431..6dbf6a0 100644
--- a/include/uapi/linux/lightnvm.h
+++ b/include/uapi/linux/lightnvm.h
@@ -35,6 +35,8 @@
#define NVM_TTYPE_MAX 63
#define NVM_MMTYPE_LEN 8
+#define NVM_LUNS_MAX 768
+
#define NVM_CTRL_FILE "/dev/lightnvm/control"
struct nvm_ioctl_info_tgt {
@@ -74,14 +76,21 @@ struct nvm_ioctl_create_simple {
__u32 lun_end;
};
+struct nvm_ioctl_create_list {
+ __u32 nr_luns;
+ __u32 lunid[NVM_LUNS_MAX];
+};
+
enum {
NVM_CONFIG_TYPE_SIMPLE = 0,
+ NVM_CONFIG_TYPE_LIST,
};
struct nvm_ioctl_create_conf {
__u32 type;
union {
struct nvm_ioctl_create_simple s;
+ struct nvm_ioctl_create_list l;
};
};
--
1.9.1
next prev parent reply other threads:[~2016-03-19 17:00 UTC|newest]
Thread overview: 6+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-03-19 16:58 [PATCH 1/3] lightnvm: divide global reverse translation map into per lun Wenwei Tao
2016-03-19 16:58 ` Wenwei Tao [this message]
2016-03-19 16:58 ` [PATCH 3/3] lightnvm: export per lun information to user Wenwei Tao
2016-03-21 10:27 ` Matias Bjørling
2016-03-22 11:28 ` Wenwei Tao
2016-03-22 20:56 ` Matias Bjørling
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1458406738-4828-2-git-send-email-ww.tao0320@gmail.com \
--to=ww.tao0320@gmail.com \
--cc=jg@lightnvm.io \
--cc=linux-block@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mb@lightnvm.io \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®