From 565b30e285934502e9fcaaf7d9b8bd81e5011d0f Mon Sep 17 00:00:00 2001 From: Tokunori Ikegami Date: Sun, 19 Jan 2025 10:08:06 +0900 Subject: [PATCH] nvme: use blkdev for direct if namespace-id specified Since IO commands rejected by the chardev if more than one namespace. Signed-off-by: Tokunori Ikegami --- nvme.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 52 insertions(+), 9 deletions(-) diff --git a/nvme.c b/nvme.c index 55a86fde..25e9f005 100644 --- 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])); -- 2.50.1