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;