The branch stable/15 has been updated by kib:

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

commit fffd409a29ce4966f2cca620aedc9f0eb1df9862
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2026-01-26 01:49:32 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2026-02-09 00:51:57 +0000

    devfs: unlock the directory vnode around the call to dev_clone handler
    
    (cherry picked from commit a8e92198f854c2766eedec5a2ea3cc23c64d7b12)
---
 sys/fs/devfs/devfs_vnops.c | 20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)

diff --git a/sys/fs/devfs/devfs_vnops.c b/sys/fs/devfs/devfs_vnops.c
index 880756264b0f..8c188e768de8 100644
--- a/sys/fs/devfs/devfs_vnops.c
+++ b/sys/fs/devfs/devfs_vnops.c
@@ -367,6 +367,9 @@ devfs_populate_vp(struct vnode *vp)
 
        ASSERT_VOP_LOCKED(vp, "devfs_populate_vp");
 
+       if (VN_IS_DOOMED(vp))
+               return (ENOENT);
+
        dmp = VFSTODEVFS(vp->v_mount);
        if (!devfs_populate_needed(dmp)) {
                sx_xlock(&dmp->dm_lock);
@@ -1128,8 +1131,25 @@ devfs_lookupx(struct vop_lookup_args *ap, int *dm_unlock)
                cdev = NULL;
                DEVFS_DMP_HOLD(dmp);
                sx_xunlock(&dmp->dm_lock);
+               dvplocked = VOP_ISLOCKED(dvp);
+
+               /*
+                * Invoke the dev_clone handler.  Unlock dvp around it
+                * to simplify the cloner operations.
+                *
+                * If dvp is reclaimed while we unlocked it, we return
+                * with ENOENT by some of the paths below.  If cloner
+                * returned cdev, then devfs_populate_vp() notes the
+                * reclamation.  Otherwise, note that either our devfs
+                * mount is being unmounted, then DEVFS_DMP_DROP()
+                * returns true, and we return ENOENT this way.  Or,
+                * because de == NULL, the check for it after the loop
+                * returns ENOENT.
+                */
+               VOP_UNLOCK(dvp);
                EVENTHANDLER_INVOKE(dev_clone,
                    td->td_ucred, pname, strlen(pname), &cdev);
+               vn_lock(dvp, dvplocked | LK_RETRY);
 
                if (cdev == NULL)
                        sx_xlock(&dmp->dm_lock);

Reply via email to