Date: Mon, 02 Feb 2026 19:51:20 +0000 From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org Subject: git: a8e92198f854 - main - devfs: unlock the directory vnode around the call to dev_clone handler Message-ID: <69810038.38a1b.716c7132@gitrepo.freebsd.org>
index | next in thread | raw e-mail
The branch main has been updated by kib: URL: https://cgit.FreeBSD.org/src/commit/?id=a8e92198f854c2766eedec5a2ea3cc23c64d7b12 commit a8e92198f854c2766eedec5a2ea3cc23c64d7b12 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2026-01-26 01:49:32 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2026-02-02 19:48:25 +0000 devfs: unlock the directory vnode around the call to dev_clone handler The lock around dev_clone is unfortunate because cloner might need to take its own locks that establish the order with devfs vnodes, and then transiently participates in further VFS locks order. For instance, this way the proctree_lock or allproc_lock become involved. Unlock dvp, we can unwind if the vnode become doomed while cloner was called. Reported and tested by: pho Reviewed by: kevans, markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D55028 --- 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 323f1e0fa961..d594b1584757 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);home | help
Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?69810038.38a1b.716c7132>
