Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 04 Aug 2026 16:23:42 +0000
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Cc:        Nimish Jain <njain15@protonmail.com>
Subject:   git: 2d21dbaaaf75 - main - fix p9fs_vget_common() panics
Message-ID:  <6a72120e.1d981.9725633@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=2d21dbaaaf75558b42a000561eb6224b6c1c0615

commit 2d21dbaaaf75558b42a000561eb6224b6c1c0615
Author:     Nimish Jain <njain15@protonmail.com>
AuthorDate: 2026-08-03 23:08:31 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
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);
 


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a72120e.1d981.9725633>