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;

Reply via email to