diff options
| author | Jeff Roberson <jeff@FreeBSD.org> | 2006-02-01 09:34:32 +0000 |
|---|---|---|
| committer | Jeff Roberson <jeff@FreeBSD.org> | 2006-02-01 09:34:32 +0000 |
| commit | 9157b485f0d13758354a85f7c535d2d7444bac2f (patch) | |
| tree | 31148bcc2771afc3b68a4e8012573dcabc717e68 | |
| parent | 0ac72424f09c0f1f5f903f78e53f8d26ef45c675 (diff) | |
Notes
| -rw-r--r-- | sys/kern/vfs_lookup.c | 18 |
1 files changed, 13 insertions, 5 deletions
diff --git a/sys/kern/vfs_lookup.c b/sys/kern/vfs_lookup.c index 8ad90bbcf7c9..42327ca6a0e4 100644 --- a/sys/kern/vfs_lookup.c +++ b/sys/kern/vfs_lookup.c @@ -60,7 +60,7 @@ __FBSDID("$FreeBSD$"); #include <vm/uma.h> -#define NAMEI_DIAGNOSTIC 1 +#define NAMEI_DIAGNOSTIC 1 #undef NAMEI_DIAGNOSTIC /* @@ -352,11 +352,13 @@ lookup(ndp) struct thread *td = cnp->cn_thread; int vfslocked; int tvfslocked; + int dvfslocked; /* * Setup: break out flag bits into variables. */ vfslocked = (ndp->ni_cnd.cn_flags & GIANTHELD) != 0; + dvfslocked = 0; ndp->ni_cnd.cn_flags &= ~GIANTHELD; wantparent = cnp->cn_flags & (LOCKPARENT | WANTPARENT); KASSERT(cnp->cn_nameiop == LOOKUP || wantparent, @@ -623,9 +625,8 @@ unionlookup: if (vfs_busy(mp, 0, 0, td)) continue; vput(dp); - tvfslocked = VFS_LOCK_GIANT(mp); - VFS_UNLOCK_GIANT(vfslocked); - vfslocked = tvfslocked; + dvfslocked = vfslocked; + vfslocked = VFS_LOCK_GIANT(mp); VOP_UNLOCK(ndp->ni_dvp, 0, td); error = VFS_ROOT(mp, cnp->cn_lkflags, &tdp, td); VOP_LOCK(ndp->ni_dvp, cnp->cn_lkflags | LK_RETRY, td); @@ -687,6 +688,8 @@ nextname: vput(ndp->ni_dvp); else vrele(ndp->ni_dvp); + VFS_UNLOCK_GIANT(dvfslocked); + dvfslocked = 0; goto dirloop; } /* @@ -706,13 +709,17 @@ nextname: vput(ndp->ni_dvp); else vrele(ndp->ni_dvp); + VFS_UNLOCK_GIANT(dvfslocked); + dvfslocked = 0; } else if ((cnp->cn_flags & LOCKPARENT) == 0 && ndp->ni_dvp != dp) VOP_UNLOCK(ndp->ni_dvp, 0, td); if ((cnp->cn_flags & LOCKLEAF) == 0) VOP_UNLOCK(dp, 0, td); success: - if (vfslocked) + if (vfslocked && dvfslocked) + VFS_UNLOCK_GIANT(dvfslocked); /* Only need one */ + if (vfslocked || dvfslocked) ndp->ni_cnd.cn_flags |= GIANTHELD; return (0); @@ -725,6 +732,7 @@ bad: if (!dpunlocked) vput(dp); VFS_UNLOCK_GIANT(vfslocked); + VFS_UNLOCK_GIANT(dvfslocked); ndp->ni_cnd.cn_flags &= ~GIANTHELD; ndp->ni_vp = NULL; return (error); |
