The branch main has been updated by kevans: URL: https://cgit.FreeBSD.org/src/commit/?id=cc70c7989bfbc528806a3abce2194f739089286b
commit cc70c7989bfbc528806a3abce2194f739089286b Author: Kyle Evans <kev...@freebsd.org> AuthorDate: 2025-09-04 02:08:51 +0000 Commit: Kyle Evans <kev...@freebsd.org> CommitDate: 2025-09-04 02:08:51 +0000 linsysfs: error check device-directory creation This one in particular is ripe with opportunities to trigger a duplicate node error in pfs_create_dir(), so we do actually want to error-check it. The rest, more or less, should be expected not to fail. We'll propagate the error from pfs_create_dir() up through linsysfs_run_bus and complain about the device node that caused the error. Note that we avoid failing vfs_init() since a partially-constructed linsysfs with missing devices is probably more useful than missing linsysfs entirely. While we're here, convert two malloc() that weren't being error checked to M_WAITOK -- we already wait in the rest of the function, might as well do the same here. Add a missing newline to the pseudofs error mesage. Reviewed by: fuz, kib Differential Revision: https://reviews.freebsd.org/D52038 --- sys/compat/linsysfs/linsysfs.c | 46 +++++++++++++++++++++++++++++++++--------- sys/fs/pseudofs/pseudofs.c | 2 +- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/sys/compat/linsysfs/linsysfs.c b/sys/compat/linsysfs/linsysfs.c index 7f70221b420d..b70cb43d0f9a 100644 --- a/sys/compat/linsysfs/linsysfs.c +++ b/sys/compat/linsysfs/linsysfs.c @@ -267,6 +267,8 @@ linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi, struct pci_devinfo *dinfo; char *device, *host, *new_path, *devname; + children = NULL; + device = host = NULL; new_path = path; devname = malloc(16, M_TEMP, M_WAITOK); @@ -294,6 +296,10 @@ linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi, strcat(new_path, device); dir = pfs_create_dir(dir, device, NULL, NULL, NULL, 0); + if (dir == NULL) { + error = EEXIST; + goto out; + } cur_file = pfs_create_file(dir, "vendor", &linsysfs_fill_vendor, NULL, NULL, NULL, PFS_RD); @@ -338,10 +344,10 @@ linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi, NULL, NULL, NULL, 0); scsi_host = malloc(sizeof( struct scsi_host_queue), - M_DEVBUF, M_NOWAIT); + M_DEVBUF, M_WAITOK); scsi_host->path = malloc( strlen(new_path) + 1, - M_DEVBUF, M_NOWAIT); + M_DEVBUF, M_WAITOK); scsi_host->path[0] = '\000'; bcopy(new_path, scsi_host->path, strlen(new_path) + 1); @@ -360,8 +366,6 @@ linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi, TAILQ_INSERT_TAIL(&scsi_host_q, scsi_host, scsi_host_next); } - free(device, M_TEMP); - free(host, M_TEMP); } } @@ -401,17 +405,37 @@ linsysfs_run_bus(device_t dev, struct pfs_node *dir, struct pfs_node *scsi, error = device_get_children(dev, &children, &nchildren); if (error == 0) { - for (i = 0; i < nchildren; i++) - if (children[i]) - linsysfs_run_bus(children[i], dir, scsi, + for (i = 0; i < nchildren; i++) { + if (children[i]) { + error = linsysfs_run_bus(children[i], dir, scsi, chardev, drm, new_path, prefix); - free(children, M_TEMP); + if (error != 0) { + printf( + "linsysfs_run_bus: %s omitted from sysfs tree, error %d\n", + device_get_nameunit(children[i]), + error); + } + } + } + + /* + * We override the error to avoid cascading failures; the + * innermost device that failed in a tree is probably the most + * significant one for diagnostics, its parents would be noise. + */ + error = 0; } + +out: + free(host, M_TEMP); + free(device, M_TEMP); + if (children != NULL) + free(children, M_TEMP); if (new_path != path) free(new_path, M_TEMP); free(devname, M_TEMP); - return (1); + return (error); } /* @@ -509,6 +533,10 @@ linsysfs_init(PFS_INIT_ARGS) return (0); } + /* + * This assumes that the root node is unlikely to error out in + * linsysfs_run_bus, which may or may not be true. + */ dev = devclass_get_device(devclass, 0); linsysfs_run_bus(dev, pci, scsi, chardev, drm, "/pci0000:00", "0000"); diff --git a/sys/fs/pseudofs/pseudofs.c b/sys/fs/pseudofs/pseudofs.c index ef45f96a6192..cc34489b92f2 100644 --- a/sys/fs/pseudofs/pseudofs.c +++ b/sys/fs/pseudofs/pseudofs.c @@ -133,7 +133,7 @@ pfs_add_node(struct pfs_node *parent, struct pfs_node *pn) for (iter = parent->pn_nodes; iter != NULL; iter = iter->pn_next) { if (strcmp(pn->pn_name, iter->pn_name) != 0) continue; - printf("pfs_add_node: homonymous siblings: '%s/%s' type %d", + printf("pfs_add_node: homonymous siblings: '%s/%s' type %d\n", parent->pn_name, pn->pn_name, pn->pn_type); /* Do not detach, because we are not yet attached. */ pn->pn_parent = NULL;