Module Name: src
Committed By: hannken
Date: Mon Aug 22 09:14:59 UTC 2022
Modified Files:
src/sys/kern: vfs_lookup.c
Log Message:
Use fstrans_start()/fstrans_done() to cross the mount in lookup_crossmount().
It is sufficient here as it prevents the file system from unmount and
makes it safe to use VFS_ROOT() here.
Removes a rare deadlock where one thread has "foundobj" locked and waits
for "foundobj->v_mountedhere" to resume while the thread holding the file
system suspended tries to lookup a node and needs a lock on "foundobj".
To generate a diff of this commit:
cvs rdiff -u -r1.231 -r1.232 src/sys/kern/vfs_lookup.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_lookup.c
diff -u src/sys/kern/vfs_lookup.c:1.231 src/sys/kern/vfs_lookup.c:1.232
--- src/sys/kern/vfs_lookup.c:1.231 Thu Feb 10 10:59:12 2022
+++ src/sys/kern/vfs_lookup.c Mon Aug 22 09:14:59 2022
@@ -1,4 +1,4 @@
-/* $NetBSD: vfs_lookup.c,v 1.231 2022/02/10 10:59:12 hannken Exp $ */
+/* $NetBSD: vfs_lookup.c,v 1.232 2022/08/22 09:14:59 hannken Exp $ */
/*
* Copyright (c) 1982, 1986, 1989, 1993
@@ -37,7 +37,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.231 2022/02/10 10:59:12 hannken Exp $");
+__KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c,v 1.232 2022/08/22 09:14:59 hannken Exp $");
#ifdef _KERNEL_OPT
#include "opt_magiclinks.h"
@@ -51,6 +51,7 @@ __KERNEL_RCSID(0, "$NetBSD: vfs_lookup.c
#include <sys/namei.h>
#include <sys/vnode.h>
#include <sys/vnode_impl.h>
+#include <sys/fstrans.h>
#include <sys/mount.h>
#include <sys/errno.h>
#include <sys/filedesc.h>
@@ -948,31 +949,16 @@ lookup_crossmount(struct namei_state *st
vrele(foundobj);
foundobj = vp;
} else {
- /* First get the vnode stable. */
- error = vn_lock(foundobj, LK_SHARED);
- if (error != 0) {
- vrele(foundobj);
- foundobj = NULL;
- break;
- }
-
- /*
- * Check to see if something is still mounted on it.
- */
- if ((mp = foundobj->v_mountedhere) == NULL) {
- VOP_UNLOCK(foundobj);
- break;
+ /* First get the vnodes mount stable. */
+ while ((mp = foundobj->v_mountedhere) != NULL) {
+ fstrans_start(mp);
+ if (fstrans_held(mp) &&
+ mp == foundobj->v_mountedhere) {
+ break;
+ }
+ fstrans_done(mp);
}
-
- /*
- * Get a reference to the mountpoint, and unlock
- * foundobj.
- */
- error = vfs_busy(mp);
- VOP_UNLOCK(foundobj);
- if (error != 0) {
- vrele(foundobj);
- foundobj = NULL;
+ if (mp == NULL) {
break;
}
@@ -992,7 +978,7 @@ lookup_crossmount(struct namei_state *st
/* Finally, drop references to foundobj & mountpoint. */
vrele(foundobj);
- vfs_unbusy(mp);
+ fstrans_done(mp);
if (error) {
foundobj = NULL;
break;