lightnvm: allow to init targets on factory mode
authorJavier González <jg@lightnvm.io>
Sat, 15 Apr 2017 18:55:45 +0000 (20:55 +0200)
committerJens Axboe <axboe@fb.com>
Sun, 16 Apr 2017 16:06:25 +0000 (10:06 -0600)
Target initialization has two responsibilities: creating the target
partition and instantiating the target. This patch enables to create a
factory partition (e.g., do not trigger recovery on the given target).
This is useful for target development and for being able to restore the
device state at any moment in time without requiring a full-device
erase.

Signed-off-by: Javier González <javier@cnexlabs.com>
Signed-off-by: Matias Bjørling <matias@cnexlabs.com>
Signed-off-by: Jens Axboe <axboe@fb.com>
drivers/lightnvm/core.c
drivers/lightnvm/rrpc.c
include/linux/lightnvm.h
include/uapi/linux/lightnvm.h

index 5f84d2a418f642970065f88db1aa3bbf166fba23..a63b563b1a8a001dc996d7181dbcf6e72ce0dafe 100644 (file)
@@ -280,7 +280,7 @@ static int nvm_create_tgt(struct nvm_dev *dev, struct nvm_ioctl_create *create)
        tdisk->fops = &nvm_fops;
        tdisk->queue = tqueue;
 
-       targetdata = tt->init(tgt_dev, tdisk);
+       targetdata = tt->init(tgt_dev, tdisk, create->flags);
        if (IS_ERR(targetdata))
                goto err_init;
 
@@ -1244,8 +1244,16 @@ static long nvm_ioctl_dev_create(struct file *file, void __user *arg)
        create.tgtname[DISK_NAME_LEN - 1] = '\0';
 
        if (create.flags != 0) {
-               pr_err("nvm: no flags supported\n");
-               return -EINVAL;
+               __u32 flags = create.flags;
+
+               /* Check for valid flags */
+               if (flags & NVM_TARGET_FACTORY)
+                       flags &= ~NVM_TARGET_FACTORY;
+
+               if (flags) {
+                       pr_err("nvm: flag not supported\n");
+                       return -EINVAL;
+               }
        }
 
        return __nvm_configure_create(&create);
index a8acf9e06401b73442a45ff0e27e016ca64dcb89..5dba54470c2ae4f794303e27a7ad5dbc8313117c 100644 (file)
@@ -1506,7 +1506,8 @@ err:
 
 static struct nvm_tgt_type tt_rrpc;
 
-static void *rrpc_init(struct nvm_tgt_dev *dev, struct gendisk *tdisk)
+static void *rrpc_init(struct nvm_tgt_dev *dev, struct gendisk *tdisk,
+                      int flags)
 {
        struct request_queue *bqueue = dev->q;
        struct request_queue *tqueue = tdisk->queue;
index eff7d1f312a8ab3c43149f005430d40a31da7cfb..7dfa56ebbc6d0f1bd4e215c93d5e642b3231334b 100644 (file)
@@ -436,7 +436,8 @@ static inline int ppa_cmp_blk(struct ppa_addr ppa1, struct ppa_addr ppa2)
 
 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_tgt_dev *, struct gendisk *);
+typedef void *(nvm_tgt_init_fn)(struct nvm_tgt_dev *, struct gendisk *,
+                               int flags);
 typedef void (nvm_tgt_exit_fn)(void *);
 typedef int (nvm_tgt_sysfs_init_fn)(struct gendisk *);
 typedef void (nvm_tgt_sysfs_exit_fn)(struct gendisk *);
index fd19f36b3129278343f37ee5e59dfa280713eb9c..c8aec4b9e73b8c85189eb9b62fa98cf1fb6e7bfa 100644 (file)
@@ -85,6 +85,10 @@ struct nvm_ioctl_create_conf {
        };
 };
 
+enum {
+       NVM_TARGET_FACTORY = 1 << 0,    /* Init target in factory mode */
+};
+
 struct nvm_ioctl_create {
        char dev[DISK_NAME_LEN];                /* open-channel SSD device */
        char tgttype[NVM_TTYPE_NAME_MAX];       /* target type name */