git: 62f382631793 - stable/13 - stand: parsedev API change: devspec now points to start of full device name

From: Warner Losh <imp_at_FreeBSD.org>
Date: Tue, 24 Jan 2023 22:13:24 UTC
The branch stable/13 has been updated by imp:

URL: https://cgit.FreeBSD.org/src/commit/?id=62f38263179338f551110a14f14d47a62309fbb8

commit 62f38263179338f551110a14f14d47a62309fbb8
Author:     Warner Losh <imp@FreeBSD.org>
AuthorDate: 2022-11-30 22:09:36 +0000
Commit:     Warner Losh <imp@FreeBSD.org>
CommitDate: 2023-01-24 21:49:39 +0000

    stand: parsedev API change: devspec now points to start of full device name
    
    To support more flexible device matching, we now pass in the full
    devspec to the parsedev routines. For everything execpt uboot, this is
    just a drop in (since everything except uboot and openfirmware always
    uses disk...: and/or zfs:, but openfirmware isn't really affected).
    
    uboot we kludge around it by subtracting 4 from where the rest of the
    device name starts. This is unforunate, and can compute the address one
    before the string. But we never dereference that address. uboot needs
    more work, and this is an acceptable UB until that other work happens.
    
    OFW doesn't really use the parsedev routines these days (since none of
    the supported device uses this... yet). It too needs more work, but it
    needs device matching support first.
    
    Sponsored by:           Netflix
    Reviewed by:            delphij
    Differential Revision:  https://reviews.freebsd.org/D37553
    
    (cherry picked from commit 33bbe5ddcbbce03b6395a4948927643107b55c06)
---
 stand/common/disk.c          | 2 +-
 stand/i386/zfsboot/zfsboot.c | 2 +-
 stand/libofw/devicename.c    | 2 +-
 stand/libsa/dev.c            | 2 +-
 stand/libsa/zfs/zfs.c        | 4 ++--
 stand/uboot/devicename.c     | 2 +-
 stand/uboot/main.c           | 8 +++++++-
 7 files changed, 14 insertions(+), 8 deletions(-)

diff --git a/stand/common/disk.c b/stand/common/disk.c
index 653f971d46b8..eecf519c52aa 100644
--- a/stand/common/disk.c
+++ b/stand/common/disk.c
@@ -420,7 +420,7 @@ disk_parsedev(struct devdesc **idev, const char *devspec, const char **path)
 	char *cp;
 	struct disk_devdesc *dev;
 
-	np = devspec;
+	np = devspec + 4;	/* Skip the leading 'disk' */
 	unit = -1;
 	/*
 	 * If there is path/file info after the device info, then any missing
diff --git a/stand/i386/zfsboot/zfsboot.c b/stand/i386/zfsboot/zfsboot.c
index 1d64ace063e0..c6305b41493e 100644
--- a/stand/i386/zfsboot/zfsboot.c
+++ b/stand/i386/zfsboot/zfsboot.c
@@ -214,7 +214,7 @@ main(void)
 	devinit();
 
 	/* XXX assumes this will be a disk, but it looks likely give above */
-	disk_parsedev((struct devdesc **)&devdesc, boot_devname + 4, NULL);
+	disk_parsedev((struct devdesc **)&devdesc, boot_devname, NULL);
 
 	bootdev = MAKEBOOTDEV(dev_maj[DEVT_DISK], devdesc->d_slice + 1,
 	    devdesc->dd.d_unit,
diff --git a/stand/libofw/devicename.c b/stand/libofw/devicename.c
index f03703e3872f..ecf966506194 100644
--- a/stand/libofw/devicename.c
+++ b/stand/libofw/devicename.c
@@ -112,7 +112,7 @@ found:
     if (dv->dv_parsedev != NULL) {
 	p = devspec + strlen(dv->dv_name);
 	free(idev);
-	err = dv->dv_parsedev((struct devdesc **)&idev, p, path);
+	err = dv->dv_parsedev((struct devdesc **)&idev, devspec, path);
 	if (err != 0) {
 	    return (err);
 	}
diff --git a/stand/libsa/dev.c b/stand/libsa/dev.c
index 158b4d69381b..b16637181059 100644
--- a/stand/libsa/dev.c
+++ b/stand/libsa/dev.c
@@ -134,7 +134,7 @@ devparse(struct devdesc **dev, const char *devspec, const char **path)
 	idev = NULL;
 	err = 0;
 	if (dv->dv_parsedev) {
-		err = dv->dv_parsedev(&idev, np, path);
+		err = dv->dv_parsedev(&idev, devspec, path);
 	} else {
 		np = devspec + strlen(dv->dv_name);
 		err = default_parsedev(&idev, np, path);
diff --git a/stand/libsa/zfs/zfs.c b/stand/libsa/zfs/zfs.c
index db4bed7f7697..d7aecc71ab5c 100644
--- a/stand/libsa/zfs/zfs.c
+++ b/stand/libsa/zfs/zfs.c
@@ -385,7 +385,7 @@ zfs_mount(const char *dev, const char *path, void **data)
 	int rv;
 
 	errno = 0;
-	rv = zfs_parsedev((struct devdesc **)&zfsdev, dev + 3, NULL);
+	rv = zfs_parsedev((struct devdesc **)&zfsdev, dev, NULL);
 	if (rv != 0) {
 		return (rv);
 	}
@@ -1644,7 +1644,7 @@ zfs_parsedev(struct devdesc **idev, const char *devspec, const char **path)
 	int		rv;
 	struct zfs_devdesc *dev;
 
-	np = devspec;
+	np = devspec + 3;			/* Skip the leading 'zfs' */
 	if (*np != ':')
 		return (EINVAL);
 	np++;
diff --git a/stand/uboot/devicename.c b/stand/uboot/devicename.c
index 8f867406e6fa..075880baa59f 100644
--- a/stand/uboot/devicename.c
+++ b/stand/uboot/devicename.c
@@ -116,7 +116,7 @@ uboot_parsedev(struct uboot_devdesc **dev, const char *devspec,
 #ifdef LOADER_DISK_SUPPORT
 	case DEVT_DISK:
 		free(idev);
-		err = disk_parsedev((struct devdesc **)&idev, np, path);
+		err = disk_parsedev((struct devdesc **)&idev, devspec, path);
 		if (err != 0)
 			goto fail;
 		break;
diff --git a/stand/uboot/main.c b/stand/uboot/main.c
index cf41917d6ee5..58de335edf7f 100644
--- a/stand/uboot/main.c
+++ b/stand/uboot/main.c
@@ -233,11 +233,17 @@ get_load_device(int *type, int *unit, int *slice, int *partition)
 	 * parse the remainder of the string as such, and if it works, return
 	 * those results. Otherwise we'll fall through to the code that parses
 	 * the legacy format.
+	 *
+	 * disk_parsedev now assumes that it points to the start of the device
+	 * name, but since it doesn't know about uboot's usage, just subtract 4
+	 * since it always adds 4. This is the least-bad solution since it makes
+	 * all the other loader code easier (might be better to create a fake
+	 * 'disk...' string, but that's more work than uboot is worth).
 	 */
 	if (*type & DEV_TYP_STOR) {
 		size_t len = strlen(p);
 		if (strcspn(p, " .") == len && strcspn(p, ":") >= len - 1 &&
-		    disk_parsedev((struct devdesc **)&dev, p, NULL) == 0) {
+		    disk_parsedev((struct devdesc **)&dev, p - 4, NULL) == 0) { /* Hack */
 			*unit = dev->dd.d_unit;
 			*slice = dev->d_slice;
 			*partition = dev->d_partition;