git: 2d21dbaaaf75 - main - fix p9fs_vget_common() panics

Konstantin Belousov <[email protected]>
Newsgroups gmane.os.freebsd.devel.cvs.src
Message-ID <6a72120e.1d981.9725633__7729.20274628035$1785860645$gmane$org@gitrepo.freebsd.org>
The branch main has been updated by kib:

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

commit 2d21dbaaaf75558b42a000561eb6224b6c1c0615
Author:     Nimish Jain <[email protected]>
AuthorDate: 2026-08-03 23:08:31 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2026-08-04 16:00:48 +0000

    fix p9fs_vget_common() panics
    
    This addresses a race when two vnodes attempt to call vfs_hash_insert(),
    but only one succeeds. Also, in case of an error from
    p9fs_reload_stats_dotl(), it marks the vnode for deletion.
    
    Reviewed by:    kib
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D58632
---
 sys/fs/p9fs/p9fs_vfsops.c | 56 +++++++++++++----------------------------------
 sys/fs/p9fs/p9fs_vnops.c  |  3 ---
 2 files changed, 15 insertions(+), 44 deletions(-)

diff --git a/sys/fs/p9fs/p9fs_vfsops.c b/sys/fs/p9fs/p9fs_vfsops.c
index fe8c1b5ded31..7a0859806b35 100644
--- a/sys/fs/p9fs/p9fs_vfsops.c
+++ b/sys/fs/p9fs/p9fs_vfsops.c
@@ -263,7 +263,7 @@ p9fs_vget_common(struct mount *mp, struct p9fs_node *np, int flags,
 	struct p9fs_node *node;
 	struct thread *td;
 	uint32_t hash;
-	int error, error_reload = 0;
+	int error;
 	struct p9fs_inode *inode;
 
 	td = curthread;
@@ -352,57 +352,31 @@ p9fs_vget_common(struct mount *mp, struct p9fs_node *np, int flags,
 	if (vp->v_type != VFIFO)
 		VN_LOCK_ASHARE(vp);
 	error = insmntque(vp, mp);
-	if (error != 0) {
-		/*
-		 * vput(vp) is already called from insmntque_stddtr().
-		 * Just goto 'out' to dispose the node.
-		 */
-		goto out;
-	}
+	if (error != 0)
+		return (error);
 
 	/* Init the vnode with the disk info*/
 	error = p9fs_reload_stats_dotl(vp, curthread->td_ucred);
 	if (error != 0) {
-		error_reload = 1;
-		goto out;
+		P9FS_NODE_SETF(np, P9FS_NODE_DELETED);
+		vgone(vp);
+		vput(vp);
+		return (error);
 	}
 
 	error = vfs_hash_insert(vp, hash, flags, td, vpp,
 	    p9fs_node_cmp, &fid->qid);
-	if (error != 0) {
-		goto out;
-	}
+	if (error != 0 || *vpp != NULL)
+		return (error);
 
-	if (*vpp == NULL) {
-		P9FS_LOCK(vses);
-		STAILQ_INSERT_TAIL(&vses->virt_node_list, np, p9fs_node_next);
-		P9FS_NODE_SETF(np, P9FS_NODE_IN_SESSION);
-		P9FS_UNLOCK(vses);
-		vn_set_state(vp, VSTATE_CONSTRUCTED);
-		*vpp = vp;
-	} else {
-		/*
-		 * Returning matching vp found in hashlist.
-		 * So cleanup the np allocated above in this context.
-		 */
-		if (!IS_ROOT(np)) {
-			p9fs_destroy_node(&np);
-		}
-	}
+	P9FS_LOCK(vses);
+	STAILQ_INSERT_TAIL(&vses->virt_node_list, np, p9fs_node_next);
+	P9FS_NODE_SETF(np, P9FS_NODE_IN_SESSION);
+	P9FS_UNLOCK(vses);
+	vn_set_state(vp, VSTATE_CONSTRUCTED);
+	*vpp = vp;
 
 	return (0);
-out:
-	/* Something went wrong, dispose the node */
-	if (!IS_ROOT(np)) {
-		p9fs_destroy_node(&np);
-	}
-
-	if (error_reload) {
-		vput(vp);
-	}
-
-	*vpp = NULL;
-	return (error);
 }
 
 /* Main mount function for 9pfs */
diff --git a/sys/fs/p9fs/p9fs_vnops.c b/sys/fs/p9fs/p9fs_vnops.c
index 2519e5cd050a..de2ffa3eb011 100644
--- a/sys/fs/p9fs/p9fs_vnops.c
+++ b/sys/fs/p9fs/p9fs_vnops.c
@@ -115,9 +115,6 @@ p9fs_cleanup(struct p9fs_node *np)
 	if ((np->flags & P9FS_NODE_IN_SESSION) != 0) {
 		P9FS_NODE_CLRF(np, P9FS_NODE_IN_SESSION);
 		STAILQ_REMOVE(&vses->virt_node_list, np, p9fs_node, p9fs_node_next);
-	} else {
-		P9FS_UNLOCK(vses);
-		return;
 	}
 	P9FS_UNLOCK(vses);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.