An NFSv4 server will reply NFSERR_GRACE for non-recovery RPCs
during the grace period after startup. This grace period must be at least the lease duration, which is typically 1-2 minutes. It seems prudent for the experimental NFS client to wait a few seconds before retrying such an RPC, so that the server isn't flooded with non-recovery RPCs during recovery. This patch adds an argument to nfs_catnap() to implement a 5 second delay for this case. MFC after: 1 week
This commit is contained in:
parent
bf59faa385
commit
23f929dfe8
@ -650,7 +650,7 @@ newnfs_request(struct nfsrv_descript *nd, struct nfsmount *nmp,
|
||||
trylater_delay = NFS_TRYLATERDEL;
|
||||
waituntil = NFSD_MONOSEC + trylater_delay;
|
||||
while (NFSD_MONOSEC < waituntil)
|
||||
(void) nfs_catnap(PZERO, "nfstry");
|
||||
(void) nfs_catnap(PZERO, 0, "nfstry");
|
||||
trylater_delay *= 2;
|
||||
goto tryagain;
|
||||
}
|
||||
|
@ -345,17 +345,21 @@ newnfs_timer(void *arg)
|
||||
|
||||
|
||||
/*
|
||||
* sleep for a short period of time.
|
||||
* Sleep for a short period of time unless errval == NFSERR_GRACE, where
|
||||
* the sleep should be for 5 seconds.
|
||||
* Since lbolt doesn't exist in FreeBSD-CURRENT, just use a timeout on
|
||||
* an event that never gets a wakeup. Only return EINTR or 0.
|
||||
*/
|
||||
int
|
||||
nfs_catnap(int prio, const char *wmesg)
|
||||
nfs_catnap(int prio, int errval, const char *wmesg)
|
||||
{
|
||||
static int non_event;
|
||||
int ret;
|
||||
|
||||
ret = tsleep(&non_event, prio, wmesg, 1);
|
||||
if (errval == NFSERR_GRACE)
|
||||
ret = tsleep(&non_event, prio, wmesg, 5 * hz);
|
||||
else
|
||||
ret = tsleep(&non_event, prio, wmesg, 1);
|
||||
if (ret != EINTR)
|
||||
ret = 0;
|
||||
return (ret);
|
||||
|
@ -322,7 +322,7 @@ int nfsvno_v4rootexport(struct nfsrv_descript *);
|
||||
void newnfs_portinit(void);
|
||||
struct ucred *newnfs_getcred(void);
|
||||
void newnfs_setroot(struct ucred *);
|
||||
int nfs_catnap(int, const char *);
|
||||
int nfs_catnap(int, int, const char *);
|
||||
struct nfsreferral *nfsv4root_getreferral(vnode_t, vnode_t, u_int32_t);
|
||||
int nfsrv_atroot(vnode_t, long *);
|
||||
void newnfs_timer(void *);
|
||||
|
@ -143,21 +143,21 @@
|
||||
#define NFSMGET(m) do { \
|
||||
MGET((m), M_TRYWAIT, MT_DATA); \
|
||||
while ((m) == NULL ) { \
|
||||
(void) nfs_catnap(PZERO, "nfsmget"); \
|
||||
(void) nfs_catnap(PZERO, 0, "nfsmget"); \
|
||||
MGET((m), M_TRYWAIT, MT_DATA); \
|
||||
} \
|
||||
} while (0)
|
||||
#define NFSMGETHDR(m) do { \
|
||||
MGETHDR((m), M_TRYWAIT, MT_DATA); \
|
||||
while ((m) == NULL ) { \
|
||||
(void) nfs_catnap(PZERO, "nfsmget"); \
|
||||
(void) nfs_catnap(PZERO, 0, "nfsmget"); \
|
||||
MGETHDR((m), M_TRYWAIT, MT_DATA); \
|
||||
} \
|
||||
} while (0)
|
||||
#define NFSMCLGET(m, w) do { \
|
||||
MGET((m), M_TRYWAIT, MT_DATA); \
|
||||
while ((m) == NULL ) { \
|
||||
(void) nfs_catnap(PZERO, "nfsmget"); \
|
||||
(void) nfs_catnap(PZERO, 0, "nfsmget"); \
|
||||
MGET((m), M_TRYWAIT, MT_DATA); \
|
||||
} \
|
||||
MCLGET((m), (w)); \
|
||||
@ -165,7 +165,7 @@
|
||||
#define NFSMCLGETHDR(m, w) do { \
|
||||
MGETHDR((m), M_TRYWAIT, MT_DATA); \
|
||||
while ((m) == NULL ) { \
|
||||
(void) nfs_catnap(PZERO, "nfsmget"); \
|
||||
(void) nfs_catnap(PZERO, 0, "nfsmget"); \
|
||||
MGETHDR((m), M_TRYWAIT, MT_DATA); \
|
||||
} \
|
||||
} while (0)
|
||||
|
@ -298,7 +298,7 @@ else printf(" fhl=0\n");
|
||||
nfscl_openrelease(op, error, newone);
|
||||
if (error == NFSERR_GRACE || error == NFSERR_STALECLIENTID ||
|
||||
error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY) {
|
||||
(void) nfs_catnap(PZERO, "nfs_open");
|
||||
(void) nfs_catnap(PZERO, error, "nfs_open");
|
||||
} else if ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID)
|
||||
&& clidrev != 0) {
|
||||
expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
|
||||
@ -460,7 +460,7 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen,
|
||||
ret = nfsrpc_openconfirm(vp, newfhp, newfhlen, op,
|
||||
cred, p);
|
||||
if (ret == NFSERR_DELAY)
|
||||
(void) nfs_catnap(PZERO, "nfs_open");
|
||||
(void) nfs_catnap(PZERO, ret, "nfs_open");
|
||||
} while (ret == NFSERR_DELAY);
|
||||
error = ret;
|
||||
}
|
||||
@ -484,7 +484,7 @@ nfsrpc_openrpc(struct nfsmount *nmp, vnode_t vp, u_int8_t *nfhp, int fhlen,
|
||||
newfhlen, mode, op, name, namelen, &ndp, 0, 0x0,
|
||||
cred, p, syscred, 1);
|
||||
if (ret == NFSERR_DELAY)
|
||||
(void) nfs_catnap(PZERO, "nfs_open2");
|
||||
(void) nfs_catnap(PZERO, ret, "nfs_open2");
|
||||
} while (ret == NFSERR_DELAY);
|
||||
if (ret) {
|
||||
if (ndp != NULL)
|
||||
@ -624,6 +624,7 @@ nfsrpc_doclose(struct nfsmount *nmp, struct nfsclopen *op, NFSPROC_T *p)
|
||||
nd->nd_repstat == NFSERR_DELAY) &&
|
||||
error == 0)
|
||||
(void) nfs_catnap(PZERO,
|
||||
(int)nd->nd_repstat,
|
||||
"nfs_close");
|
||||
} while ((nd->nd_repstat == NFSERR_GRACE ||
|
||||
nd->nd_repstat == NFSERR_DELAY) &&
|
||||
@ -645,7 +646,7 @@ nfsrpc_doclose(struct nfsmount *nmp, struct nfsclopen *op, NFSPROC_T *p)
|
||||
do {
|
||||
error = nfscl_tryclose(op, tcred, nmp, p);
|
||||
if (error == NFSERR_GRACE)
|
||||
(void) nfs_catnap(PZERO, "nfs_close");
|
||||
(void) nfs_catnap(PZERO, error, "nfs_close");
|
||||
} while (error == NFSERR_GRACE);
|
||||
NFSLOCKCLSTATE();
|
||||
nfscl_lockunlock(&op->nfso_own->nfsow_rwlock);
|
||||
@ -999,7 +1000,7 @@ nfsrpc_setattr(vnode_t vp, struct vattr *vap, NFSACL_T *aclp,
|
||||
if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
|
||||
error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
|
||||
error == NFSERR_OLDSTATEID) {
|
||||
(void) nfs_catnap(PZERO, "nfs_setattr");
|
||||
(void) nfs_catnap(PZERO, error, "nfs_setattr");
|
||||
} else if ((error == NFSERR_EXPIRED ||
|
||||
error == NFSERR_BADSTATEID) && clidrev != 0) {
|
||||
expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
|
||||
@ -1244,7 +1245,7 @@ nfsrpc_read(vnode_t vp, struct uio *uiop, struct ucred *cred,
|
||||
if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
|
||||
error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
|
||||
error == NFSERR_OLDSTATEID) {
|
||||
(void) nfs_catnap(PZERO, "nfs_read");
|
||||
(void) nfs_catnap(PZERO, error, "nfs_read");
|
||||
} else if ((error == NFSERR_EXPIRED ||
|
||||
error == NFSERR_BADSTATEID) && clidrev != 0) {
|
||||
expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
|
||||
@ -1409,7 +1410,7 @@ nfscl_dumpstate(nmp, 1, 1, 0, 0);
|
||||
if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
|
||||
error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY ||
|
||||
error == NFSERR_OLDSTATEID) {
|
||||
(void) nfs_catnap(PZERO, "nfs_write");
|
||||
(void) nfs_catnap(PZERO, error, "nfs_write");
|
||||
} else if ((error == NFSERR_EXPIRED ||
|
||||
error == NFSERR_BADSTATEID) && clidrev != 0) {
|
||||
expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
|
||||
@ -1736,7 +1737,7 @@ nfsrpc_create(vnode_t dvp, char *name, int namelen, struct vattr *vap,
|
||||
nfscl_ownerrelease(owp, error, newone, unlocked);
|
||||
if (error == NFSERR_GRACE || error == NFSERR_STALECLIENTID ||
|
||||
error == NFSERR_STALEDONTRECOVER || error == NFSERR_DELAY) {
|
||||
(void) nfs_catnap(PZERO, "nfs_open");
|
||||
(void) nfs_catnap(PZERO, error, "nfs_open");
|
||||
} else if ((error == NFSERR_EXPIRED ||
|
||||
error == NFSERR_BADSTATEID) && clidrev != 0) {
|
||||
expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
|
||||
@ -1969,7 +1970,7 @@ nfsrpc_createv4(vnode_t dvp, char *name, int namelen, struct vattr *vap,
|
||||
ret = nfsrpc_openconfirm(dvp, nfhp->nfh_fh,
|
||||
nfhp->nfh_len, op, cred, p);
|
||||
if (ret == NFSERR_DELAY)
|
||||
(void) nfs_catnap(PZERO, "nfs_create");
|
||||
(void) nfs_catnap(PZERO, ret, "nfs_create");
|
||||
} while (ret == NFSERR_DELAY);
|
||||
error = ret;
|
||||
}
|
||||
@ -1991,7 +1992,7 @@ nfsrpc_createv4(vnode_t dvp, char *name, int namelen, struct vattr *vap,
|
||||
(NFSV4OPEN_ACCESSWRITE | NFSV4OPEN_ACCESSREAD), op,
|
||||
name, namelen, &dp, 0, 0x0, cred, p, 0, 1);
|
||||
if (ret == NFSERR_DELAY)
|
||||
(void) nfs_catnap(PZERO, "nfs_crt2");
|
||||
(void) nfs_catnap(PZERO, ret, "nfs_crt2");
|
||||
} while (ret == NFSERR_DELAY);
|
||||
if (ret) {
|
||||
if (dp != NULL)
|
||||
@ -3533,7 +3534,8 @@ nfsrpc_advlock(vnode_t vp, off_t size, int op, struct flock *fl,
|
||||
if ((nd->nd_repstat == NFSERR_GRACE ||
|
||||
nd->nd_repstat == NFSERR_DELAY) &&
|
||||
error == 0)
|
||||
(void) nfs_catnap(PZERO, "nfs_advlock");
|
||||
(void) nfs_catnap(PZERO, (int)nd->nd_repstat,
|
||||
"nfs_advlock");
|
||||
} while ((nd->nd_repstat == NFSERR_GRACE ||
|
||||
nd->nd_repstat == NFSERR_DELAY) && error == 0);
|
||||
}
|
||||
@ -3570,7 +3572,7 @@ nfsrpc_advlock(vnode_t vp, off_t size, int op, struct flock *fl,
|
||||
if (error == NFSERR_GRACE || error == NFSERR_STALESTATEID ||
|
||||
error == NFSERR_STALEDONTRECOVER ||
|
||||
error == NFSERR_STALECLIENTID || error == NFSERR_DELAY) {
|
||||
(void) nfs_catnap(PZERO, "nfs_advlock");
|
||||
(void) nfs_catnap(PZERO, error, "nfs_advlock");
|
||||
} else if ((error == NFSERR_EXPIRED || error == NFSERR_BADSTATEID)
|
||||
&& clidrev != 0) {
|
||||
expireret = nfscl_hasexpired(nmp->nm_clp, clidrev, p);
|
||||
|
@ -784,7 +784,7 @@ nfscl_getcl(vnode_t vp, struct ucred *cred, NFSPROC_T *p,
|
||||
if (error == NFSERR_STALECLIENTID ||
|
||||
error == NFSERR_STALEDONTRECOVER ||
|
||||
error == NFSERR_CLIDINUSE) {
|
||||
(void) nfs_catnap(PZERO, "nfs_setcl");
|
||||
(void) nfs_catnap(PZERO, error, "nfs_setcl");
|
||||
}
|
||||
} while (((error == NFSERR_STALECLIENTID ||
|
||||
error == NFSERR_STALEDONTRECOVER) && --trystalecnt > 0) ||
|
||||
@ -2046,7 +2046,7 @@ nfscl_recover(struct nfsclclient *clp, struct ucred *cred, NFSPROC_T *p)
|
||||
newnfs_copycred(&op->nfso_cred, tcred);
|
||||
error = nfscl_tryclose(op, tcred, nmp, p);
|
||||
if (error == NFSERR_GRACE)
|
||||
(void) nfs_catnap(PZERO, "nfsexcls");
|
||||
(void) nfs_catnap(PZERO, error, "nfsexcls");
|
||||
} while (error == NFSERR_GRACE);
|
||||
LIST_REMOVE(op, nfso_list);
|
||||
FREE((caddr_t)op, M_NFSCLOPEN);
|
||||
@ -2059,7 +2059,7 @@ nfscl_recover(struct nfsclclient *clp, struct ucred *cred, NFSPROC_T *p)
|
||||
newnfs_copycred(&dp->nfsdl_cred, tcred);
|
||||
error = nfscl_trydelegreturn(dp, tcred, nmp, p);
|
||||
if (error == NFSERR_GRACE)
|
||||
(void) nfs_catnap(PZERO, "nfsexdlg");
|
||||
(void) nfs_catnap(PZERO, error, "nfsexdlg");
|
||||
} while (error == NFSERR_GRACE);
|
||||
TAILQ_REMOVE(&extra_deleg, dp, nfsdl_list);
|
||||
FREE((caddr_t)dp, M_NFSCLDELEG);
|
||||
@ -3619,7 +3619,7 @@ nfscl_tryopen(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp, int fhlen,
|
||||
mode, op, name, namelen, ndpp, reclaim, delegtype, cred, p,
|
||||
0, 0);
|
||||
if (error == NFSERR_DELAY)
|
||||
(void) nfs_catnap(PZERO, "nfstryop");
|
||||
(void) nfs_catnap(PZERO, error, "nfstryop");
|
||||
} while (error == NFSERR_DELAY);
|
||||
if (error == EAUTH || error == EACCES) {
|
||||
/* Try again using system credentials */
|
||||
@ -3629,7 +3629,7 @@ nfscl_tryopen(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp, int fhlen,
|
||||
newfhlen, mode, op, name, namelen, ndpp, reclaim,
|
||||
delegtype, cred, p, 1, 0);
|
||||
if (error == NFSERR_DELAY)
|
||||
(void) nfs_catnap(PZERO, "nfstryop");
|
||||
(void) nfs_catnap(PZERO, error, "nfstryop");
|
||||
} while (error == NFSERR_DELAY);
|
||||
}
|
||||
return (error);
|
||||
@ -3652,7 +3652,8 @@ nfscl_trylock(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp,
|
||||
error = nfsrpc_lock(nd, nmp, vp, fhp, fhlen, nlp, newone,
|
||||
reclaim, off, len, type, cred, p, 0);
|
||||
if (!error && nd->nd_repstat == NFSERR_DELAY)
|
||||
(void) nfs_catnap(PZERO, "nfstrylck");
|
||||
(void) nfs_catnap(PZERO, (int)nd->nd_repstat,
|
||||
"nfstrylck");
|
||||
} while (!error && nd->nd_repstat == NFSERR_DELAY);
|
||||
if (!error)
|
||||
error = nd->nd_repstat;
|
||||
@ -3663,7 +3664,8 @@ nfscl_trylock(struct nfsmount *nmp, vnode_t vp, u_int8_t *fhp,
|
||||
error = nfsrpc_lock(nd, nmp, vp, fhp, fhlen, nlp,
|
||||
newone, reclaim, off, len, type, cred, p, 1);
|
||||
if (!error && nd->nd_repstat == NFSERR_DELAY)
|
||||
(void) nfs_catnap(PZERO, "nfstrylck");
|
||||
(void) nfs_catnap(PZERO, (int)nd->nd_repstat,
|
||||
"nfstrylck");
|
||||
} while (!error && nd->nd_repstat == NFSERR_DELAY);
|
||||
if (!error)
|
||||
error = nd->nd_repstat;
|
||||
@ -3685,7 +3687,7 @@ nfscl_trydelegreturn(struct nfscldeleg *dp, struct ucred *cred,
|
||||
do {
|
||||
error = nfsrpc_delegreturn(dp, cred, nmp, p, 0);
|
||||
if (error == NFSERR_DELAY)
|
||||
(void) nfs_catnap(PZERO, "nfstrydp");
|
||||
(void) nfs_catnap(PZERO, error, "nfstrydp");
|
||||
} while (error == NFSERR_DELAY);
|
||||
if (error == EAUTH || error == EACCES) {
|
||||
/* Try again using system credentials */
|
||||
@ -3693,7 +3695,7 @@ nfscl_trydelegreturn(struct nfscldeleg *dp, struct ucred *cred,
|
||||
do {
|
||||
error = nfsrpc_delegreturn(dp, cred, nmp, p, 1);
|
||||
if (error == NFSERR_DELAY)
|
||||
(void) nfs_catnap(PZERO, "nfstrydp");
|
||||
(void) nfs_catnap(PZERO, error, "nfstrydp");
|
||||
} while (error == NFSERR_DELAY);
|
||||
}
|
||||
return (error);
|
||||
@ -3714,7 +3716,7 @@ nfscl_tryclose(struct nfsclopen *op, struct ucred *cred,
|
||||
do {
|
||||
error = nfsrpc_closerpc(nd, nmp, op, cred, p, 0);
|
||||
if (error == NFSERR_DELAY)
|
||||
(void) nfs_catnap(PZERO, "nfstrycl");
|
||||
(void) nfs_catnap(PZERO, error, "nfstrycl");
|
||||
} while (error == NFSERR_DELAY);
|
||||
if (error == EAUTH || error == EACCES) {
|
||||
/* Try again using system credentials */
|
||||
@ -3722,7 +3724,7 @@ nfscl_tryclose(struct nfsclopen *op, struct ucred *cred,
|
||||
do {
|
||||
error = nfsrpc_closerpc(nd, nmp, op, cred, p, 1);
|
||||
if (error == NFSERR_DELAY)
|
||||
(void) nfs_catnap(PZERO, "nfstrycl");
|
||||
(void) nfs_catnap(PZERO, error, "nfstrycl");
|
||||
} while (error == NFSERR_DELAY);
|
||||
}
|
||||
return (error);
|
||||
|
@ -652,7 +652,7 @@ nfs_decode_args(struct mount *mp, struct nfsmount *nmp, struct nfs_args *argp,
|
||||
while (newnfs_connect(nmp, &nmp->nm_sockreq,
|
||||
cred, td, 0)) {
|
||||
printf("newnfs_args: retrying connect\n");
|
||||
(void) nfs_catnap(PSOCK, "newnfscon");
|
||||
(void) nfs_catnap(PSOCK, 0, "newnfscon");
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1188,7 +1188,7 @@ mountnfs(struct nfs_args *argp, struct mount *mp, struct sockaddr *nam,
|
||||
error = nfsrpc_getdirpath(nmp, NFSMNT_DIRPATH(nmp),
|
||||
cred, td);
|
||||
if (error)
|
||||
(void) nfs_catnap(PZERO, "nfsgetdirp");
|
||||
(void) nfs_catnap(PZERO, error, "nfsgetdirp");
|
||||
} while (error && --trycnt > 0);
|
||||
if (error) {
|
||||
error = nfscl_maperr(td, error, (uid_t)0, (gid_t)0);
|
||||
@ -1284,7 +1284,7 @@ nfs_unmount(struct mount *mp, int mntflags)
|
||||
do {
|
||||
error = vflush(mp, 1, flags, td);
|
||||
if ((mntflags & MNT_FORCE) && error != 0 && ++trycnt < 30)
|
||||
(void) nfs_catnap(PSOCK, "newndm");
|
||||
(void) nfs_catnap(PSOCK, error, "newndm");
|
||||
} while ((mntflags & MNT_FORCE) && error != 0 && trycnt < 30);
|
||||
if (error)
|
||||
goto out;
|
||||
|
@ -2871,7 +2871,8 @@ nfs_advlock(struct vop_advlock_args *ap)
|
||||
if (ret == NFSERR_DENIED && (ap->a_flags & F_WAIT) &&
|
||||
ap->a_op == F_SETLK) {
|
||||
VOP_UNLOCK(vp, 0);
|
||||
error = nfs_catnap(PZERO | PCATCH, "ncladvl");
|
||||
error = nfs_catnap(PZERO | PCATCH, ret,
|
||||
"ncladvl");
|
||||
if (error)
|
||||
return (EINTR);
|
||||
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
|
||||
|
@ -4578,7 +4578,7 @@ nfsd_recalldelegation(vnode_t vp, NFSPROC_T *p)
|
||||
100000)
|
||||
return;
|
||||
/* Sleep for a short period of time */
|
||||
(void) nfs_catnap(PZERO, "nfsremove");
|
||||
(void) nfs_catnap(PZERO, 0, "nfsremove");
|
||||
}
|
||||
} while (error == NFSERR_DELAY);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user