The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=e9897199576a40360440aa4d2aa48d61c4010f11

commit e9897199576a40360440aa4d2aa48d61c4010f11
Author:     Konstantin Belousov <k...@freebsd.org>
AuthorDate: 2025-06-03 20:01:24 +0000
Commit:     Konstantin Belousov <k...@freebsd.org>
CommitDate: 2025-06-05 22:41:40 +0000

    pseudofs: make dup name an error instead of panic
    
    There are enough cases where the duplicate name is caused by dubious
    hardware configuration.  Stopping the whole system instead of failing a
    driver, or even a diagnostic subsystem in a driver, is more
    user-friendly.
    
    Another issue right now is that the check is only present for the
    INVARIANTS builds, silently accepting the request to create an entry
    with the existing name on production builds.
    
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D50669
---
 sys/fs/pseudofs/pseudofs.c | 53 +++++++++++++++++++++++++++++++---------------
 1 file changed, 36 insertions(+), 17 deletions(-)

diff --git a/sys/fs/pseudofs/pseudofs.c b/sys/fs/pseudofs/pseudofs.c
index eafa2947490a..ef45f96a6192 100644
--- a/sys/fs/pseudofs/pseudofs.c
+++ b/sys/fs/pseudofs/pseudofs.c
@@ -98,12 +98,10 @@ pfs_alloc_node(struct pfs_info *pi, const char *name, 
pfs_type_t type)
 /*
  * Add a node to a directory
  */
-static void
+static int
 pfs_add_node(struct pfs_node *parent, struct pfs_node *pn)
 {
-#ifdef INVARIANTS
        struct pfs_node *iter;
-#endif
 
        KASSERT(parent != NULL,
            ("%s(): parent is NULL", __func__));
@@ -123,9 +121,6 @@ pfs_add_node(struct pfs_node *parent, struct pfs_node *pn)
                        KASSERT(iter->pn_type != pfstype_procdir,
                            ("%s(): nested process directories", __func__));
        for (iter = parent->pn_nodes; iter != NULL; iter = iter->pn_next) {
-               KASSERT(strcmp(pn->pn_name, iter->pn_name) != 0,
-                   ("%s(): homonymous siblings: '%s' type %d", __func__,
-                   pn->pn_name, pn->pn_type));
                if (pn->pn_type == pfstype_procdir)
                        KASSERT(iter->pn_type != pfstype_procdir,
                            ("%s(): sibling process directories", __func__));
@@ -134,8 +129,19 @@ pfs_add_node(struct pfs_node *parent, struct pfs_node *pn)
 
        pn->pn_parent = parent;
        pfs_fileno_alloc(pn);
-
        pfs_lock(parent);
+       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",
+                   parent->pn_name, pn->pn_name, pn->pn_type);
+               /* Do not detach, because we are not yet attached. */
+               pn->pn_parent = NULL;
+               pfs_unlock(parent);
+               return (EEXIST);
+       }
+
+
        if ((parent->pn_flags & PFS_PROCDEP) != 0)
                pn->pn_flags |= PFS_PROCDEP;
        if (parent->pn_nodes == NULL) {
@@ -152,6 +158,7 @@ pfs_add_node(struct pfs_node *parent, struct pfs_node *pn)
                parent->pn_last_node = pn;
        }
        pfs_unlock(parent);
+       return (0);
 }
 
 /*
@@ -197,6 +204,7 @@ static int
 pfs_fixup_dir_flags(struct pfs_node *parent, int flags)
 {
        struct pfs_node *dot, *dotdot;
+       int rc;
 
        dot = pfs_alloc_node_flags(parent->pn_info, ".", pfstype_this, flags);
        if (dot == NULL)
@@ -206,9 +214,14 @@ pfs_fixup_dir_flags(struct pfs_node *parent, int flags)
                pfs_destroy(dot);
                return (ENOMEM);
        }
-       pfs_add_node(parent, dot);
-       pfs_add_node(parent, dotdot);
-       return (0);
+       rc = pfs_add_node(parent, dot);
+       if (rc == 0)
+               rc = pfs_add_node(parent, dotdot);
+       if (rc != 0) {
+               pfs_destroy(dot);
+               pfs_destroy(dotdot);
+       }
+       return (rc);
 }
 
 static void
@@ -237,11 +250,12 @@ pfs_create_dir(struct pfs_node *parent, const char *name,
        pn->pn_vis = vis;
        pn->pn_destroy = destroy;
        pn->pn_flags = flags;
-       pfs_add_node(parent, pn);
-       rc = pfs_fixup_dir_flags(pn, flags);
-       if (rc) {
+       rc = pfs_add_node(parent, pn);
+       if (rc == 0)
+               rc = pfs_fixup_dir_flags(pn, flags);
+       if (rc != 0) {
                pfs_destroy(pn);
-               return (NULL);
+               pn = NULL;
        }
        return (pn);
 }
@@ -264,8 +278,10 @@ pfs_create_file(struct pfs_node *parent, const char *name, 
pfs_fill_t fill,
        pn->pn_vis = vis;
        pn->pn_destroy = destroy;
        pn->pn_flags = flags;
-       pfs_add_node(parent, pn);
-
+       if (pfs_add_node(parent, pn) != 0) {
+               pfs_destroy(pn);
+               pn = NULL;
+       }
        return (pn);
 }
 
@@ -287,7 +303,10 @@ pfs_create_link(struct pfs_node *parent, const char *name, 
pfs_fill_t fill,
        pn->pn_vis = vis;
        pn->pn_destroy = destroy;
        pn->pn_flags = flags;
-       pfs_add_node(parent, pn);
+       if (pfs_add_node(parent, pn) != 0) {
+               pfs_destroy(pn);
+               pn = NULL;
+       }
 
        return (pn);
 }

Reply via email to