To avoid a deadlock when handling .. directory during a lookup, we unlock
parent vnode and relock it after locking child vnode. The problem was that we always relock it exclusively, even when it was share-locked. Discussed with: jeff
This commit is contained in:
parent
29aee808df
commit
f9fef47d89
@ -315,7 +315,7 @@ cache_lookup(dvp, vpp, cnp)
|
||||
{
|
||||
struct namecache *ncp;
|
||||
u_int32_t hash;
|
||||
int error;
|
||||
int error, ltype;
|
||||
|
||||
if (!doingcache) {
|
||||
cnp->cn_flags &= ~MAKEENTRY;
|
||||
@ -421,13 +421,16 @@ success:
|
||||
CACHE_UNLOCK();
|
||||
return (-1);
|
||||
}
|
||||
if (cnp->cn_flags & ISDOTDOT)
|
||||
ltype = 0; /* silence gcc warning */
|
||||
if (cnp->cn_flags & ISDOTDOT) {
|
||||
ltype = VOP_ISLOCKED(dvp, cnp->cn_thread);
|
||||
VOP_UNLOCK(dvp, 0, cnp->cn_thread);
|
||||
}
|
||||
VI_LOCK(*vpp);
|
||||
CACHE_UNLOCK();
|
||||
error = vget(*vpp, cnp->cn_lkflags | LK_INTERLOCK, cnp->cn_thread);
|
||||
if (cnp->cn_flags & ISDOTDOT)
|
||||
vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, cnp->cn_thread);
|
||||
vn_lock(dvp, ltype | LK_RETRY, cnp->cn_thread);
|
||||
if (error) {
|
||||
*vpp = NULL;
|
||||
goto retry;
|
||||
|
Loading…
x
Reference in New Issue
Block a user