From 3fb0942cc5fb216ac733da94930e11a64e589d38 Mon Sep 17 00:00:00 2001 From: Fabian-Gruenbichler Date: Fri, 22 Mar 2024 00:38:24 +0100 Subject: [PATCH] udev: correctly handle partition #16 and later MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit If a zvol has more than 15 partitions, the minor device number exhausts the slot count reserved for partitions next to the zvol itself. As a result, the minor number cannot be used to determine the partition number for the higher partition, and doing so results in wrong named symlinks being generated by udev. Since the partition number is encoded in the block device name anyway, let's just extract it from there instead. Reviewed-by: Tony Hutter Reviewed by: Brian Behlendorf Reviewed-by: Tino Reichardt Signed-off-by: Fabian Grünbichler Closes #15904 Closes #15970 --- udev/zvol_id.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/udev/zvol_id.c b/udev/zvol_id.c index 5960b9787..609349594 100644 --- a/udev/zvol_id.c +++ b/udev/zvol_id.c @@ -51,7 +51,7 @@ const char *__asan_default_options(void) { int main(int argc, const char *const *argv) { - if (argc != 2) { + if (argc != 2 || strncmp(argv[1], "/dev/zd", 7) != 0) { fprintf(stderr, "usage: %s /dev/zdX\n", argv[0]); return (1); } @@ -72,9 +72,10 @@ main(int argc, const char *const *argv) return (1); } - unsigned int dev_part = minor(sb.st_rdev) % ZVOL_MINORS; - if (dev_part != 0) - sprintf(zvol_name + strlen(zvol_name), "-part%u", dev_part); + const char *dev_part = strrchr(dev_name, 'p'); + if (dev_part != NULL) { + sprintf(zvol_name + strlen(zvol_name), "-part%s", dev_part + 1); + } for (size_t i = 0; i < strlen(zvol_name); ++i) if (isblank(zvol_name[i]))