nfscl: Fix two more cases for forced dismount
Although I was not able to cause a failure during testing, there are places in nfscl_removedeleg() and nfscl_renamedeleg() where I think a forced dismount could get hung. This patch fixes those. This patch only affects forced dismount and only if the NFSv4 server is issuing delegations to the client. Found by code inspection. MFC after: 2 weeks
This commit is contained in:
parent
e2157cd000
commit
f5d5164fb6
@ -4669,6 +4669,7 @@ nfscl_removedeleg(vnode_t vp, NFSPROC_T *p, nfsv4stateid_t *stp)
|
||||
struct nfsclowner *owp;
|
||||
struct nfscllockowner *lp;
|
||||
struct nfsmount *nmp;
|
||||
struct mount *mp;
|
||||
struct ucred *cred;
|
||||
struct nfsnode *np;
|
||||
int igotlock = 0, triedrecall = 0, needsrecall, retcnt = 0, islept;
|
||||
@ -4683,6 +4684,7 @@ nfscl_removedeleg(vnode_t vp, NFSPROC_T *p, nfsv4stateid_t *stp)
|
||||
}
|
||||
NFSUNLOCKMNT(nmp);
|
||||
np = VTONFS(vp);
|
||||
mp = nmp->nm_mountp;
|
||||
NFSLOCKCLSTATE();
|
||||
/*
|
||||
* Loop around waiting for:
|
||||
@ -4709,8 +4711,13 @@ nfscl_removedeleg(vnode_t vp, NFSPROC_T *p, nfsv4stateid_t *stp)
|
||||
igotlock = 0;
|
||||
}
|
||||
dp->nfsdl_rwlock.nfslock_lock |= NFSV4LOCK_WANTED;
|
||||
(void) nfsmsleep(&dp->nfsdl_rwlock,
|
||||
NFSCLSTATEMUTEXPTR, PZERO, "nfscld", NULL);
|
||||
msleep(&dp->nfsdl_rwlock, NFSCLSTATEMUTEXPTR, PZERO,
|
||||
"nfscld", hz);
|
||||
if (NFSCL_FORCEDISM(mp)) {
|
||||
dp->nfsdl_flags &= ~NFSCLDL_DELEGRET;
|
||||
NFSUNLOCKCLSTATE();
|
||||
return (0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
needsrecall = 0;
|
||||
@ -4733,7 +4740,14 @@ nfscl_removedeleg(vnode_t vp, NFSPROC_T *p, nfsv4stateid_t *stp)
|
||||
islept = 0;
|
||||
while (!igotlock) {
|
||||
igotlock = nfsv4_lock(&clp->nfsc_lock, 1,
|
||||
&islept, NFSCLSTATEMUTEXPTR, NULL);
|
||||
&islept, NFSCLSTATEMUTEXPTR, mp);
|
||||
if (NFSCL_FORCEDISM(mp)) {
|
||||
dp->nfsdl_flags &= ~NFSCLDL_DELEGRET;
|
||||
if (igotlock)
|
||||
nfsv4_unlock(&clp->nfsc_lock, 0);
|
||||
NFSUNLOCKCLSTATE();
|
||||
return (0);
|
||||
}
|
||||
if (islept)
|
||||
break;
|
||||
}
|
||||
@ -4774,6 +4788,7 @@ nfscl_renamedeleg(vnode_t fvp, nfsv4stateid_t *fstp, int *gotfdp, vnode_t tvp,
|
||||
struct nfsclowner *owp;
|
||||
struct nfscllockowner *lp;
|
||||
struct nfsmount *nmp;
|
||||
struct mount *mp;
|
||||
struct ucred *cred;
|
||||
struct nfsnode *np;
|
||||
int igotlock = 0, triedrecall = 0, needsrecall, retcnt = 0, islept;
|
||||
@ -4789,6 +4804,7 @@ nfscl_renamedeleg(vnode_t fvp, nfsv4stateid_t *fstp, int *gotfdp, vnode_t tvp,
|
||||
return (retcnt);
|
||||
}
|
||||
NFSUNLOCKMNT(nmp);
|
||||
mp = nmp->nm_mountp;
|
||||
NFSLOCKCLSTATE();
|
||||
/*
|
||||
* Loop around waiting for:
|
||||
@ -4816,8 +4832,15 @@ nfscl_renamedeleg(vnode_t fvp, nfsv4stateid_t *fstp, int *gotfdp, vnode_t tvp,
|
||||
igotlock = 0;
|
||||
}
|
||||
dp->nfsdl_rwlock.nfslock_lock |= NFSV4LOCK_WANTED;
|
||||
(void) nfsmsleep(&dp->nfsdl_rwlock,
|
||||
NFSCLSTATEMUTEXPTR, PZERO, "nfscld", NULL);
|
||||
msleep(&dp->nfsdl_rwlock, NFSCLSTATEMUTEXPTR, PZERO,
|
||||
"nfscld", hz);
|
||||
if (NFSCL_FORCEDISM(mp)) {
|
||||
dp->nfsdl_flags &= ~NFSCLDL_DELEGRET;
|
||||
NFSUNLOCKCLSTATE();
|
||||
*gotfdp = 0;
|
||||
*gottdp = 0;
|
||||
return (0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
needsrecall = 0;
|
||||
@ -4840,7 +4863,16 @@ nfscl_renamedeleg(vnode_t fvp, nfsv4stateid_t *fstp, int *gotfdp, vnode_t tvp,
|
||||
islept = 0;
|
||||
while (!igotlock) {
|
||||
igotlock = nfsv4_lock(&clp->nfsc_lock, 1,
|
||||
&islept, NFSCLSTATEMUTEXPTR, NULL);
|
||||
&islept, NFSCLSTATEMUTEXPTR, mp);
|
||||
if (NFSCL_FORCEDISM(mp)) {
|
||||
dp->nfsdl_flags &= ~NFSCLDL_DELEGRET;
|
||||
if (igotlock)
|
||||
nfsv4_unlock(&clp->nfsc_lock, 0);
|
||||
NFSUNLOCKCLSTATE();
|
||||
*gotfdp = 0;
|
||||
*gottdp = 0;
|
||||
return (0);
|
||||
}
|
||||
if (islept)
|
||||
break;
|
||||
}
|
||||
@ -4877,8 +4909,14 @@ nfscl_renamedeleg(vnode_t fvp, nfsv4stateid_t *fstp, int *gotfdp, vnode_t tvp,
|
||||
*/
|
||||
if (dp->nfsdl_rwlock.nfslock_usecnt > 0) {
|
||||
dp->nfsdl_rwlock.nfslock_lock |= NFSV4LOCK_WANTED;
|
||||
(void) nfsmsleep(&dp->nfsdl_rwlock,
|
||||
NFSCLSTATEMUTEXPTR, PZERO, "nfscld", NULL);
|
||||
msleep(&dp->nfsdl_rwlock, NFSCLSTATEMUTEXPTR, PZERO,
|
||||
"nfscld", hz);
|
||||
if (NFSCL_FORCEDISM(mp)) {
|
||||
NFSUNLOCKCLSTATE();
|
||||
*gotfdp = 0;
|
||||
*gottdp = 0;
|
||||
return (0);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
LIST_FOREACH(owp, &dp->nfsdl_owner, nfsow_list) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user