Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 4 Sep 2025 02:09:49 GMT
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: cc70c7989bfb - main - linsysfs: error check device-directory creation
Message-ID:  <202509040209.58429nGs012287@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202509040209.58429nGs012287>