]> www.infradead.org Git - users/sagi/libnvme.git/commitdiff
tree: fix generic device open failure
authorMinwoo Im <minwoo.im@samsung.com>
Wed, 22 Mar 2023 22:59:03 +0000 (07:59 +0900)
committerDaniel Wagner <wagi@monom.org>
Mon, 27 Mar 2023 12:02:39 +0000 (14:02 +0200)
If scan_namespace is called with a generic device (e.g., /dev/ng0n1)
given, it fails to scan a namespace based on the generic device because
there's no entry point in /sys/block/ for the generic device.

This patch provides two helpers to change the given generic device name
to a block device name based on the instances:
ng0n1 -> nvme0n1

This patch fixes command failure:
root@vm:~/work/nvme-cli.git# nvme show-regs /dev/ng0n1
Unable to find ng0n1
get-property: Invalid argument

Signed-off-by: Minwoo Im <minwoo.im@samsung.com>
[dwagner: also catch blkdev allocation failures]
Signed-off-by: Daniel Wagner <dwagner@suse.de>
src/nvme/tree.c

index 83e35c488ce243b33ae7832d1860bccb3ceb7806..34844634f231d7c77bf586bb6ac824c9f41fe9b7 100644 (file)
@@ -1864,27 +1864,62 @@ free_ns:
        return NULL;
 }
 
+static inline bool nvme_ns_is_generic(const char *name)
+{
+       int instance, head_instance;
+
+       if (sscanf(name, "ng%dn%d", &instance, &head_instance) != 2)
+               return false;
+       return true;
+}
+
+static char *nvme_ns_generic_to_blkdev(const char *generic)
+{
+
+       int instance, head_instance;
+       char blkdev[PATH_MAX];
+
+       if (!nvme_ns_is_generic(generic))
+               return strdup(generic);
+
+       sscanf(generic, "ng%dn%d", &instance, &head_instance);
+       sprintf(blkdev, "nvme%dn%d", instance, head_instance);
+
+       return strdup(blkdev);
+}
+
 static struct nvme_ns *__nvme_scan_namespace(const char *sysfs_dir, const char *name)
 {
        struct nvme_ns *n;
        char *path;
        int ret;
+       char *blkdev;
 
-       ret = asprintf(&path, "%s/%s", sysfs_dir, name);
-       if (ret < 0) {
+       blkdev = nvme_ns_generic_to_blkdev(name);
+       if (!blkdev) {
                errno = ENOMEM;
                return NULL;
        }
 
-       n = nvme_ns_open(name);
+       ret = asprintf(&path, "%s/%s", sysfs_dir, blkdev);
+       if (ret < 0) {
+               errno = ENOMEM;
+               goto free_blkdev;
+       }
+
+       n = nvme_ns_open(blkdev);
        if (!n)
                goto free_path;
 
        n->sysfs_dir = path;
+
+       free(blkdev);
        return n;
 
 free_path:
        free(path);
+free_blkdev:
+       free(blkdev);
        return NULL;
 }