]> www.infradead.org Git - users/sagi/nvme-cli.git/commitdiff
nvme: use blkdev for direct if namespace-id specified
authorTokunori Ikegami <ikegami.t@gmail.com>
Sun, 19 Jan 2025 01:08:06 +0000 (10:08 +0900)
committerDaniel Wagner <wagi@monom.org>
Mon, 20 Jan 2025 16:20:41 +0000 (17:20 +0100)
Since IO commands rejected by the chardev if more than one namespace.

Signed-off-by: Tokunori Ikegami <ikegami.t@gmail.com>
nvme.c

diff --git a/nvme.c b/nvme.c
index 55a86fde131a7c58db65570e8c4b2d49ccbdfbe0..25e9f005860f444ec8aa386390e2e9085be1bdaa 100644 (file)
--- a/nvme.c
+++ b/nvme.c
@@ -299,7 +299,48 @@ static bool is_blkdev(struct nvme_dev *dev)
        return S_ISBLK(dev->direct.stat.st_mode);
 }
 
-static int open_dev_direct(struct nvme_dev **devp, char *devstr, int flags)
+static bool is_nvme_dev(char *dev)
+{
+       int instance;
+       int head_instance;
+
+       return sscanf(basename(dev), "nvme%dn%d", &instance, &head_instance) == 1;
+}
+
+static __u32 get_nsid(struct argconfig_commandline_options *opts)
+{
+       __u32 *nsid = argconfig_get_value(opts, "namespace-id");
+
+       if (nsid && *nsid != NVME_NSID_ALL)
+               return *nsid;
+
+       return NVME_NSID_NONE;
+}
+
+static int open_blkdev_direct(char *dev, int flags, __u32 nsid)
+{
+       _cleanup_free_ char *blkdev = NULL;
+       int fd = -1;
+
+       if (is_nvme_dev(dev) && nsid) {
+               if (asprintf(&blkdev, "%sn%d", dev, nsid) < 0)
+                       blkdev = NULL;
+       }
+
+       if (blkdev) {
+               fd = open(blkdev, flags);
+               print_info("blkdev: %s, fd: %d\n", blkdev, fd);
+       }
+
+       if (fd < 0) {
+               fd = open(dev, flags);
+               print_info("dev: %s, fd: %d\n", dev, fd);
+       }
+
+       return fd;
+}
+
+static int open_dev_direct(struct nvme_dev **devp, char *devstr, int flags, __u32 nsid)
 {
        struct nvme_dev *dev;
        int err;
@@ -310,7 +351,7 @@ static int open_dev_direct(struct nvme_dev **devp, char *devstr, int flags)
 
        dev->type = NVME_DEV_DIRECT;
        dev->name = basename(devstr);
-       err = open(devstr, flags);
+       err = open_blkdev_direct(devstr, flags, nsid);
        if (err < 0) {
                nvme_show_perror(devstr);
                goto err_free;
@@ -412,10 +453,12 @@ static int check_arg_dev(int argc, char **argv)
        return 0;
 }
 
-static int get_dev(struct nvme_dev **dev, int argc, char **argv, int flags)
+static int get_dev(struct nvme_dev **dev, int argc, char **argv, int flags,
+                  struct argconfig_commandline_options *opts)
 {
        char *devname;
        int ret;
+       __u32 nsid = get_nsid(opts);
 
        ret = check_arg_dev(argc, argv);
        if (ret)
@@ -427,7 +470,7 @@ static int get_dev(struct nvme_dev **dev, int argc, char **argv, int flags)
        if (!strncmp(devname, "mctp:", strlen("mctp:")))
                ret = open_dev_mi_mctp(dev, devname);
        else
-               ret = open_dev_direct(dev, devname, flags);
+               ret = open_dev_direct(dev, devname, flags, nsid);
 
        return ret ? -errno : 0;
 }
@@ -457,7 +500,7 @@ int parse_and_open(struct nvme_dev **dev, int argc, char **argv,
        if (ret)
                return ret;
 
-       ret = get_dev(dev, argc, argv, O_RDONLY);
+       ret = get_dev(dev, argc, argv, O_RDONLY, opts);
        if (ret < 0)
                argconfig_print_help(desc, opts);
 
@@ -465,14 +508,14 @@ int parse_and_open(struct nvme_dev **dev, int argc, char **argv,
 }
 
 int open_exclusive(struct nvme_dev **dev, int argc, char **argv,
-                  int ignore_exclusive)
+                  int ignore_exclusive, struct argconfig_commandline_options *opts)
 {
        int flags = O_RDONLY;
 
        if (!ignore_exclusive)
                flags |= O_EXCL;
 
-       return get_dev(dev, argc, argv, flags);
+       return get_dev(dev, argc, argv, flags, opts);
 }
 
 int validate_output_format(const char *format, nvme_print_flags_t *flags)
@@ -6202,7 +6245,7 @@ static int format_cmd(int argc, char **argv, struct command *cmd, struct plugin
        if (err)
                return err;
 
-       err = open_exclusive(&dev, argc, argv, cfg.force);
+       err = open_exclusive(&dev, argc, argv, cfg.force, opts);
        if (err) {
                if (errno == EBUSY) {
                        fprintf(stderr, "Failed to open %s.\n", basename(argv[optind]));
@@ -7883,7 +7926,7 @@ static int submit_io(int opcode, char *command, const char *desc, int argc, char
                err = parse_args(argc, argv, desc, opts);
                if (err)
                        return err;
-               err = open_exclusive(&dev, argc, argv, cfg.force);
+               err = open_exclusive(&dev, argc, argv, cfg.force, opts);
                if (err) {
                        if (errno == EBUSY) {
                                fprintf(stderr, "Failed to open %s.\n", basename(argv[optind]));