Module Name:    src
Committed By:   riastradh
Date:           Tue Sep 13 09:13:20 UTC 2022

Modified Files:
        src/sys/kern: vfs_subr.c

Log Message:
vfs(9): For MP-safe mounts, don't kernel lock in mount/unmount.


To generate a diff of this commit:
cvs rdiff -u -r1.494 -r1.495 src/sys/kern/vfs_subr.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/kern/vfs_subr.c
diff -u src/sys/kern/vfs_subr.c:1.494 src/sys/kern/vfs_subr.c:1.495
--- src/sys/kern/vfs_subr.c:1.494	Tue Sep 13 08:48:20 2022
+++ src/sys/kern/vfs_subr.c	Tue Sep 13 09:13:19 2022
@@ -1,4 +1,4 @@
-/*	$NetBSD: vfs_subr.c,v 1.494 2022/09/13 08:48:20 riastradh Exp $	*/
+/*	$NetBSD: vfs_subr.c,v 1.495 2022/09/13 09:13:19 riastradh Exp $	*/
 
 /*-
  * Copyright (c) 1997, 1998, 2004, 2005, 2007, 2008, 2019, 2020
@@ -69,7 +69,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.494 2022/09/13 08:48:20 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_subr.c,v 1.495 2022/09/13 09:13:19 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -1385,11 +1385,24 @@ vtype2dt(enum vtype vt)
 int
 VFS_MOUNT(struct mount *mp, const char *a, void *b, size_t *c)
 {
+	int mpsafe = mp->mnt_iflag & IMNT_MPSAFE;
 	int error;
 
-	KERNEL_LOCK(1, NULL);
+	/*
+	 * Note: The first time through, the vfs_mount function may set
+	 * IMNT_MPSAFE, so we have to cache it on entry in order to
+	 * avoid leaking a kernel lock.
+	 *
+	 * XXX Maybe the MPSAFE bit should be set in struct vfsops and
+	 * not in struct mount.
+	 */
+	if (mpsafe) {
+		KERNEL_LOCK(1, NULL);
+	}
 	error = (*(mp->mnt_op->vfs_mount))(mp, a, b, c);
-	KERNEL_UNLOCK_ONE(NULL);
+	if (mpsafe) {
+		KERNEL_UNLOCK_ONE(NULL);
+	}
 
 	return error;
 }
@@ -1415,9 +1428,13 @@ VFS_UNMOUNT(struct mount *mp, int a)
 {
 	int error;
 
-	KERNEL_LOCK(1, NULL);
+	if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) {
+		KERNEL_LOCK(1, NULL);
+	}
 	error = (*(mp->mnt_op->vfs_unmount))(mp, a);
-	KERNEL_UNLOCK_ONE(NULL);
+	if ((mp->mnt_iflag & IMNT_MPSAFE) == 0) {
+		KERNEL_UNLOCK_ONE(NULL);
+	}
 
 	return error;
 }

Reply via email to