git: cc70c7989bfb - main - linsysfs: error check device-directory creation
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 04 Sep 2025 02:09:49 UTC
The branch main has been updated by kevans:
URL: https://cgit.FreeBSD.org/src/commit/?id=cc70c7989bfbc528806a3abce2194f739089286b
commit cc70c7989bfbc528806a3abce2194f739089286b
Author: Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2025-09-04 02:08:51 +0000
Commit: Kyle Evans <kevans@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;