Fix an NFSv4.1 client specific case where a forced dismount would hang.
The hang occurred in nfsv4_setsequence() when it couldn't find an available session slot and is fixed by checking for a forced dismount in progress and just returning for this case. MFC after: 1 month
This commit is contained in:
parent
d4e70c8074
commit
42b6336a98
@ -3693,8 +3693,8 @@ nfsv4_seqsess_cacherep(uint32_t slotid, struct nfsslot *slots, struct mbuf *rep)
|
|||||||
* Generate the xdr for an NFSv4.1 Sequence Operation.
|
* Generate the xdr for an NFSv4.1 Sequence Operation.
|
||||||
*/
|
*/
|
||||||
APPLESTATIC void
|
APPLESTATIC void
|
||||||
nfsv4_setsequence(struct nfsrv_descript *nd, struct nfsclsession *sep,
|
nfsv4_setsequence(struct nfsmount *nmp, struct nfsrv_descript *nd,
|
||||||
int dont_replycache)
|
struct nfsclsession *sep, int dont_replycache)
|
||||||
{
|
{
|
||||||
uint32_t *tl, slotseq = 0;
|
uint32_t *tl, slotseq = 0;
|
||||||
int i, maxslot, slotpos;
|
int i, maxslot, slotpos;
|
||||||
@ -3717,9 +3717,21 @@ nfsv4_setsequence(struct nfsrv_descript *nd, struct nfsclsession *sep,
|
|||||||
}
|
}
|
||||||
bitval <<= 1;
|
bitval <<= 1;
|
||||||
}
|
}
|
||||||
if (slotpos == -1)
|
if (slotpos == -1) {
|
||||||
|
/*
|
||||||
|
* If a forced dismount is in progress, just return.
|
||||||
|
* This RPC attempt will fail when it calls
|
||||||
|
* newnfs_request().
|
||||||
|
*/
|
||||||
|
if ((nmp->nm_mountp->mnt_kern_flag & MNTK_UNMOUNTF)
|
||||||
|
!= 0) {
|
||||||
|
mtx_unlock(&sep->nfsess_mtx);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
/* Wake up once/sec, to check for a forced dismount. */
|
||||||
(void)mtx_sleep(&sep->nfsess_slots, &sep->nfsess_mtx,
|
(void)mtx_sleep(&sep->nfsess_slots, &sep->nfsess_mtx,
|
||||||
PZERO, "nfsclseq", 0);
|
PZERO, "nfsclseq", hz);
|
||||||
|
}
|
||||||
} while (slotpos == -1);
|
} while (slotpos == -1);
|
||||||
/* Now, find the highest slot in use. (nfsc_slots is 64bits) */
|
/* Now, find the highest slot in use. (nfsc_slots is 64bits) */
|
||||||
bitval = 1;
|
bitval = 1;
|
||||||
|
@ -265,7 +265,8 @@ int nfsv4_getipaddr(struct nfsrv_descript *, struct sockaddr_storage *,
|
|||||||
int nfsv4_seqsession(uint32_t, uint32_t, uint32_t, struct nfsslot *,
|
int nfsv4_seqsession(uint32_t, uint32_t, uint32_t, struct nfsslot *,
|
||||||
struct mbuf **, uint16_t);
|
struct mbuf **, uint16_t);
|
||||||
void nfsv4_seqsess_cacherep(uint32_t, struct nfsslot *, struct mbuf *);
|
void nfsv4_seqsess_cacherep(uint32_t, struct nfsslot *, struct mbuf *);
|
||||||
void nfsv4_setsequence(struct nfsrv_descript *, struct nfsclsession *, int);
|
void nfsv4_setsequence(struct nfsmount *, struct nfsrv_descript *,
|
||||||
|
struct nfsclsession *, int);
|
||||||
void nfsv4_freeslot(struct nfsclsession *, int);
|
void nfsv4_freeslot(struct nfsclsession *, int);
|
||||||
|
|
||||||
/* nfs_clcomsubs.c */
|
/* nfs_clcomsubs.c */
|
||||||
|
@ -203,10 +203,11 @@ nfscl_reqstart(struct nfsrv_descript *nd, int procnum, struct nfsmount *nmp,
|
|||||||
NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
|
NFSM_BUILD(tl, u_int32_t *, NFSX_UNSIGNED);
|
||||||
*tl = txdr_unsigned(NFSV4OP_SEQUENCE);
|
*tl = txdr_unsigned(NFSV4OP_SEQUENCE);
|
||||||
if (sep == NULL)
|
if (sep == NULL)
|
||||||
nfsv4_setsequence(nd, NFSMNT_MDSSESSION(nmp),
|
nfsv4_setsequence(nmp, nd,
|
||||||
|
NFSMNT_MDSSESSION(nmp),
|
||||||
nfs_bigreply[procnum]);
|
nfs_bigreply[procnum]);
|
||||||
else
|
else
|
||||||
nfsv4_setsequence(nd, sep,
|
nfsv4_setsequence(nmp, nd, sep,
|
||||||
nfs_bigreply[procnum]);
|
nfs_bigreply[procnum]);
|
||||||
}
|
}
|
||||||
if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh > 0) {
|
if (nfsv4_opflag[nfsv4_opmap[procnum].op].needscfh > 0) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user