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
This commit is contained in:
+1
-1
@@ -420,7 +420,7 @@ disk_parsedev(struct devdesc **idev, const char *devspec, const char **path)
|
|||||||
char *cp;
|
char *cp;
|
||||||
struct disk_devdesc *dev;
|
struct disk_devdesc *dev;
|
||||||
|
|
||||||
np = devspec;
|
np = devspec + 4; /* Skip the leading 'disk' */
|
||||||
unit = -1;
|
unit = -1;
|
||||||
/*
|
/*
|
||||||
* If there is path/file info after the device info, then any missing
|
* If there is path/file info after the device info, then any missing
|
||||||
|
|||||||
@@ -214,7 +214,7 @@ main(void)
|
|||||||
devinit();
|
devinit();
|
||||||
|
|
||||||
/* XXX assumes this will be a disk, but it looks likely give above */
|
/* 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,
|
bootdev = MAKEBOOTDEV(dev_maj[DEVT_DISK], devdesc->d_slice + 1,
|
||||||
devdesc->dd.d_unit,
|
devdesc->dd.d_unit,
|
||||||
|
|||||||
@@ -112,7 +112,7 @@ ofw_parsedev(struct ofw_devdesc **dev, const char *devspec, const char **path)
|
|||||||
if (dv->dv_parsedev != NULL) {
|
if (dv->dv_parsedev != NULL) {
|
||||||
p = devspec + strlen(dv->dv_name);
|
p = devspec + strlen(dv->dv_name);
|
||||||
free(idev);
|
free(idev);
|
||||||
err = dv->dv_parsedev((struct devdesc **)&idev, p, path);
|
err = dv->dv_parsedev((struct devdesc **)&idev, devspec, path);
|
||||||
if (err != 0) {
|
if (err != 0) {
|
||||||
return (err);
|
return (err);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -134,7 +134,7 @@ devparse(struct devdesc **dev, const char *devspec, const char **path)
|
|||||||
idev = NULL;
|
idev = NULL;
|
||||||
err = 0;
|
err = 0;
|
||||||
if (dv->dv_parsedev) {
|
if (dv->dv_parsedev) {
|
||||||
err = dv->dv_parsedev(&idev, np, path);
|
err = dv->dv_parsedev(&idev, devspec, path);
|
||||||
} else {
|
} else {
|
||||||
np = devspec + strlen(dv->dv_name);
|
np = devspec + strlen(dv->dv_name);
|
||||||
err = default_parsedev(&idev, np, path);
|
err = default_parsedev(&idev, np, path);
|
||||||
|
|||||||
@@ -385,7 +385,7 @@ zfs_mount(const char *dev, const char *path, void **data)
|
|||||||
int rv;
|
int rv;
|
||||||
|
|
||||||
errno = 0;
|
errno = 0;
|
||||||
rv = zfs_parsedev((struct devdesc **)&zfsdev, dev + 3, NULL);
|
rv = zfs_parsedev((struct devdesc **)&zfsdev, dev, NULL);
|
||||||
if (rv != 0) {
|
if (rv != 0) {
|
||||||
return (rv);
|
return (rv);
|
||||||
}
|
}
|
||||||
@@ -1644,7 +1644,7 @@ zfs_parsedev(struct devdesc **idev, const char *devspec, const char **path)
|
|||||||
int rv;
|
int rv;
|
||||||
struct zfs_devdesc *dev;
|
struct zfs_devdesc *dev;
|
||||||
|
|
||||||
np = devspec;
|
np = devspec + 3; /* Skip the leading 'zfs' */
|
||||||
if (*np != ':')
|
if (*np != ':')
|
||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
np++;
|
np++;
|
||||||
|
|||||||
@@ -116,7 +116,7 @@ uboot_parsedev(struct uboot_devdesc **dev, const char *devspec,
|
|||||||
#ifdef LOADER_DISK_SUPPORT
|
#ifdef LOADER_DISK_SUPPORT
|
||||||
case DEVT_DISK:
|
case DEVT_DISK:
|
||||||
free(idev);
|
free(idev);
|
||||||
err = disk_parsedev((struct devdesc **)&idev, np, path);
|
err = disk_parsedev((struct devdesc **)&idev, devspec, path);
|
||||||
if (err != 0)
|
if (err != 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
break;
|
break;
|
||||||
|
|||||||
+7
-1
@@ -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
|
* 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
|
* those results. Otherwise we'll fall through to the code that parses
|
||||||
* the legacy format.
|
* 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) {
|
if (*type & DEV_TYP_STOR) {
|
||||||
size_t len = strlen(p);
|
size_t len = strlen(p);
|
||||||
if (strcspn(p, " .") == len && strcspn(p, ":") >= len - 1 &&
|
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;
|
*unit = dev->dd.d_unit;
|
||||||
*slice = dev->d_slice;
|
*slice = dev->d_slice;
|
||||||
*partition = dev->d_partition;
|
*partition = dev->d_partition;
|
||||||
|
|||||||
Reference in New Issue
Block a user