From d21670b5d5b0f29eada55081ca0cd79ecfed6031 Mon Sep 17 00:00:00 2001 From: bp Date: Wed, 13 Sep 2000 08:57:56 +0000 Subject: Unlock current directory when calling VFS_ROOT() because underlying filesystem may hold the lock. Otherwise unavoidable deadlock will occur. This shouldn't have any side effects as long as we hold vfs lock. Obtained from: NetBSD --- sys/kern/vfs_lookup.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'sys/kern') diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 4cdec9e..c9f43d4 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -274,6 +274,7 @@ lookup(ndp) int rdonly; /* lookup read-only flag bit */ int trailing_slash; int error = 0; + int dpunlocked = 0; /* dp has already been unlocked */ struct componentname *cnp = &ndp->ni_cnd; struct proc *p = cnp->cn_proc; @@ -487,11 +488,14 @@ unionlookup: (cnp->cn_flags & NOCROSSMOUNT) == 0) { if (vfs_busy(mp, 0, 0, p)) continue; + VOP_UNLOCK(dp, 0, p); error = VFS_ROOT(mp, &tdp); vfs_unbusy(mp, p); - if (error) + if (error) { + dpunlocked = 1; goto bad2; - vput(dp); + } + vrele(dp); ndp->ni_vp = dp = tdp; } @@ -557,7 +561,10 @@ bad2: VOP_UNLOCK(ndp->ni_dvp, 0, p); vrele(ndp->ni_dvp); bad: - vput(dp); + if (dpunlocked) + vrele(dp); + else + vput(dp); ndp->ni_vp = NULL; return (error); } -- cgit v1.1