- Set cn_lkflags to LK_SHARED in the LOOKUP_SHARED case so that we only
acquire shared locks on intermediate directories. - For the LASTCN, we may have to LK_UPGRADE the parent directory before we lookup the last component. - Acquire VFS_ROOT and dp locks based on the cn_lkflag. Sponsored by: Isilon Systems, Inc.
This commit is contained in:
parent
18b24235a1
commit
99f3c87034
@ -360,11 +360,20 @@ lookup(ndp)
|
||||
cnp->cn_nameiop != LOOKUP))
|
||||
docache = 0;
|
||||
rdonly = cnp->cn_flags & RDONLY;
|
||||
ndp->ni_dvp = NULL;
|
||||
cnp->cn_flags &= ~ISSYMLINK;
|
||||
ndp->ni_dvp = NULL;
|
||||
#ifdef LOOKUP_SHARED
|
||||
/*
|
||||
* We use shared locks until we hit the parent of the last cn then
|
||||
* we adjust based on the requesting flags.
|
||||
*/
|
||||
cnp->cn_lkflags = LK_SHARED;
|
||||
#else
|
||||
cnp->cn_lkflags = LK_EXCLUSIVE;
|
||||
#endif
|
||||
dp = ndp->ni_startdir;
|
||||
ndp->ni_startdir = NULLVP;
|
||||
vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
vn_lock(dp, cnp->cn_lkflags | LK_RETRY, td);
|
||||
|
||||
dirloop:
|
||||
/*
|
||||
@ -487,7 +496,7 @@ lookup(ndp)
|
||||
vfslocked = VFS_LOCK_GIANT(dp->v_mount);
|
||||
VFS_UNLOCK_GIANT(tvfslocked);
|
||||
VREF(dp);
|
||||
vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
vn_lock(dp, cnp->cn_lkflags | LK_RETRY, td);
|
||||
}
|
||||
}
|
||||
|
||||
@ -505,6 +514,20 @@ lookup(ndp)
|
||||
ndp->ni_dvp = dp;
|
||||
ndp->ni_vp = NULL;
|
||||
ASSERT_VOP_LOCKED(dp, "lookup");
|
||||
/*
|
||||
* If we have a shared lock we may need to upgrade the lock for the
|
||||
* last operation.
|
||||
*/
|
||||
if (VOP_ISLOCKED(dp, td) == LK_SHARED &&
|
||||
(cnp->cn_flags & ISLASTCN) && (cnp->cn_flags & LOCKPARENT))
|
||||
vn_lock(dp, LK_UPGRADE|LK_RETRY, td);
|
||||
/*
|
||||
* If we're looking up the last component and we need an exclusive
|
||||
* lock, adjust our lkflags.
|
||||
*/
|
||||
if ((cnp->cn_flags & (ISLASTCN|LOCKSHARED|LOCKLEAF)) ==
|
||||
(ISLASTCN|LOCKLEAF))
|
||||
cnp->cn_lkflags = LK_EXCLUSIVE;
|
||||
#ifdef NAMEI_DIAGNOSTIC
|
||||
vprint("lookup in", dp);
|
||||
#endif
|
||||
@ -523,7 +546,7 @@ lookup(ndp)
|
||||
vfslocked = VFS_LOCK_GIANT(dp->v_mount);
|
||||
VFS_UNLOCK_GIANT(tvfslocked);
|
||||
VREF(dp);
|
||||
vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
vn_lock(dp, cnp->cn_lkflags | LK_RETRY, td);
|
||||
goto unionlookup;
|
||||
}
|
||||
|
||||
@ -604,7 +627,7 @@ lookup(ndp)
|
||||
continue;
|
||||
VOP_UNLOCK(dp, 0, td);
|
||||
tvfslocked = VFS_LOCK_GIANT(mp);
|
||||
error = VFS_ROOT(mp, LK_EXCLUSIVE, &tdp, td);
|
||||
error = VFS_ROOT(mp, cnp->cn_lkflags, &tdp, td);
|
||||
vfs_unbusy(mp, td);
|
||||
if (error) {
|
||||
VFS_UNLOCK_GIANT(tvfslocked);
|
||||
@ -725,6 +748,7 @@ relookup(dvp, vpp, cnp)
|
||||
rdonly = cnp->cn_flags & RDONLY;
|
||||
cnp->cn_flags &= ~ISSYMLINK;
|
||||
dp = dvp;
|
||||
cnp->cn_lkflags = LK_EXCLUSIVE;
|
||||
vn_lock(dp, LK_EXCLUSIVE | LK_RETRY, td);
|
||||
|
||||
/*
|
||||
|
Loading…
Reference in New Issue
Block a user