git: 1c8f3ba03ccc - stable/14 - nullfs: add nounixbypass mount option

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Fri, 24 Oct 2025 09:51:53 UTC
The branch stable/14 has been updated by kib:

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

commit 1c8f3ba03cccf6e14d38c2a479b889c29d0eb6bf
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2025-10-08 15:47:15 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2025-10-24 09:47:37 +0000

    nullfs: add nounixbypass mount option
    
    (cherry picked from commit 6fa205a6233fea7c41ba0306c778bc5cab37ce7d)
---
 sys/fs/nullfs/null.h        | 5 +++--
 sys/fs/nullfs/null_subr.c   | 4 +++-
 sys/fs/nullfs/null_vfsops.c | 9 +++++++++
 sys/fs/nullfs/null_vnops.c  | 8 ++++++++
 4 files changed, 23 insertions(+), 3 deletions(-)

diff --git a/sys/fs/nullfs/null.h b/sys/fs/nullfs/null.h
index 34b8b4225ba8..eebf6da571b8 100644
--- a/sys/fs/nullfs/null.h
+++ b/sys/fs/nullfs/null.h
@@ -37,7 +37,8 @@
 #ifndef	FS_NULL_H
 #define	FS_NULL_H
 
-#define	NULLM_CACHE	0x0001
+#define	NULLM_CACHE		0x0001
+#define	NULLM_NOUNPBYPASS	0x0002
 
 struct null_mount {
 	struct mount	*nullm_vfs;
@@ -88,7 +89,7 @@ null_is_nullfs_vnode(struct vnode *vp)
 	const struct vop_vector *op;
 
 	op = vp->v_op;
-	return (op == &null_vnodeops);
+	return (op == &null_vnodeops || op == &null_vnodeops_no_unp_bypass);
 }
 
 #ifdef MALLOC_DECLARE
diff --git a/sys/fs/nullfs/null_subr.c b/sys/fs/nullfs/null_subr.c
index 546f0aea3766..b0e3d15b4789 100644
--- a/sys/fs/nullfs/null_subr.c
+++ b/sys/fs/nullfs/null_subr.c
@@ -212,7 +212,9 @@ null_nodeget(struct mount *mp, struct vnode *lowervp, struct vnode **vpp)
 	 */
 	xp = malloc(sizeof(struct null_node), M_NULLFSNODE, M_WAITOK);
 
-	error = getnewvnode("nullfs", mp, &null_vnodeops, &vp);
+	error = getnewvnode("nullfs", mp, (MOUNTTONULLMOUNT(mp)->nullm_flags &
+	    NULLM_NOUNPBYPASS) != 0 ? &null_vnodeops_no_unp_bypass :
+	    &null_vnodeops, &vp);
 	if (error) {
 		vput(lowervp);
 		free(xp, M_NULLFSNODE);
diff --git a/sys/fs/nullfs/null_vfsops.c b/sys/fs/nullfs/null_vfsops.c
index 7f4cc5e38f96..8b9e04775449 100644
--- a/sys/fs/nullfs/null_vfsops.c
+++ b/sys/fs/nullfs/null_vfsops.c
@@ -91,6 +91,8 @@ nullfs_mount(struct mount *mp)
 	bool isvnunlocked;
 	static const char cache_opt_name[] = "cache";
 	static const char nocache_opt_name[] = "nocache";
+	static const char unixbypass_opt_name[] = "unixbypass";
+	static const char nounixbypass_opt_name[] = "nounixbypass";
 
 	NULLFSDEBUG("nullfs_mount(mp = %p)\n", (void *)mp);
 
@@ -226,6 +228,13 @@ nullfs_mount(struct mount *mp)
 		    &xmp->notify_node);
 	}
 
+	if (vfs_getopt(mp->mnt_optnew, unixbypass_opt_name, NULL, NULL) == 0) {
+		;
+	} else if (vfs_getopt(mp->mnt_optnew, nounixbypass_opt_name, NULL,
+	    NULL) == 0) {
+		xmp->nullm_flags |= NULLM_NOUNPBYPASS;
+	}
+
 	if (lowerrootvp == mp->mnt_vnodecovered) {
 		vn_lock(lowerrootvp, LK_EXCLUSIVE | LK_RETRY | LK_CANRECURSE);
 		lowerrootvp->v_vflag |= VV_CROSSLOCK;
diff --git a/sys/fs/nullfs/null_vnops.c b/sys/fs/nullfs/null_vnops.c
index e398053c7028..2e34b77a5a7e 100644
--- a/sys/fs/nullfs/null_vnops.c
+++ b/sys/fs/nullfs/null_vnops.c
@@ -1192,3 +1192,11 @@ struct vop_vector null_vnodeops = {
 	.vop_copy_file_range =	VOP_PANIC,
 };
 VFS_VOP_VECTOR_REGISTER(null_vnodeops);
+
+struct vop_vector null_vnodeops_no_unp_bypass = {
+	.vop_default =		&null_vnodeops,
+	.vop_unp_bind =		vop_stdunp_bind,
+	.vop_unp_connect =	vop_stdunp_connect,
+	.vop_unp_detach =	vop_stdunp_detach,
+};
+VFS_VOP_VECTOR_REGISTER(null_vnodeops_no_unp_bypass);