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;
}