nfsd: make the server repeat CB_RECALL every couple of seconds
Commit 01ae8969a9ee stopped the NFSv4.1/4.2 server from implicitly binding the back channel to a new TCP connection so that it conforms to RFC5661, for NFSv4.1/4.2. An effect of this for the Linux NFS client is that it will do a BindConnectionToSession when it sees NFSV4SEQ_CBPATHDOWN set in a sequence reply. This will fix the back channel, but the first attempt at a callback like CB_RECALL will already have failed. Without this patch, a CB_RECALL will not be retried and that can result in a 5 minute delay until the delegation times out. This patch modifies the code so that it will retry the CB_RECALL every couple of seconds, often avoiding the 5 minute delay. This is not critical for correct behaviour, but avoids the 5 minute delay for the case where the Linux client re-binds the back channel via BindConnectionToSession. MFC after: 2 weeks
This commit is contained in:
parent
ea444392bb
commit
7a606f280a
@ -220,6 +220,7 @@ struct nfsstate {
|
||||
time_t expiry;
|
||||
time_t limit;
|
||||
u_int64_t compref;
|
||||
time_t last;
|
||||
} deleg;
|
||||
} ls_un;
|
||||
struct nfslockfile *ls_lfp; /* Back pointer */
|
||||
@ -238,6 +239,7 @@ struct nfsstate {
|
||||
#define ls_delegtime ls_un.deleg.expiry
|
||||
#define ls_delegtimelimit ls_un.deleg.limit
|
||||
#define ls_compref ls_un.deleg.compref
|
||||
#define ls_lastrecall ls_un.deleg.last
|
||||
|
||||
/*
|
||||
* Nfs lock structure.
|
||||
|
@ -3070,6 +3070,7 @@ tryagain:
|
||||
new_deleg->ls_clp = clp;
|
||||
new_deleg->ls_filerev = filerev;
|
||||
new_deleg->ls_compref = nd->nd_compref;
|
||||
new_deleg->ls_lastrecall = 0;
|
||||
LIST_INSERT_HEAD(&lfp->lf_deleg, new_deleg, ls_file);
|
||||
LIST_INSERT_HEAD(NFSSTATEHASH(clp,
|
||||
new_deleg->ls_stateid), new_deleg, ls_hash);
|
||||
@ -3191,6 +3192,7 @@ tryagain:
|
||||
new_deleg->ls_clp = clp;
|
||||
new_deleg->ls_filerev = filerev;
|
||||
new_deleg->ls_compref = nd->nd_compref;
|
||||
new_deleg->ls_lastrecall = 0;
|
||||
nfsrv_writedelegcnt++;
|
||||
LIST_INSERT_HEAD(&lfp->lf_deleg, new_deleg, ls_file);
|
||||
LIST_INSERT_HEAD(NFSSTATEHASH(clp,
|
||||
@ -3261,6 +3263,7 @@ tryagain:
|
||||
new_deleg->ls_clp = clp;
|
||||
new_deleg->ls_filerev = filerev;
|
||||
new_deleg->ls_compref = nd->nd_compref;
|
||||
new_deleg->ls_lastrecall = 0;
|
||||
LIST_INSERT_HEAD(&lfp->lf_deleg, new_deleg, ls_file);
|
||||
LIST_INSERT_HEAD(NFSSTATEHASH(clp,
|
||||
new_deleg->ls_stateid), new_deleg, ls_hash);
|
||||
@ -3339,6 +3342,7 @@ tryagain:
|
||||
new_deleg->ls_clp = clp;
|
||||
new_deleg->ls_filerev = filerev;
|
||||
new_deleg->ls_compref = nd->nd_compref;
|
||||
new_deleg->ls_lastrecall = 0;
|
||||
LIST_INSERT_HEAD(&lfp->lf_deleg, new_deleg,
|
||||
ls_file);
|
||||
LIST_INSERT_HEAD(NFSSTATEHASH(clp,
|
||||
@ -5265,7 +5269,8 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p,
|
||||
* - check to see if the delegation has expired
|
||||
* - if so, get the v4root lock and then expire it
|
||||
*/
|
||||
if (!(stp->ls_flags & NFSLCK_DELEGRECALL)) {
|
||||
if ((stp->ls_flags & NFSLCK_DELEGRECALL) == 0 || stp->ls_lastrecall <
|
||||
time_uptime) {
|
||||
/*
|
||||
* - do a recall callback, since not yet done
|
||||
* For now, never allow truncate to be set. To use
|
||||
@ -5280,11 +5285,14 @@ nfsrv_delegconflict(struct nfsstate *stp, int *haslockp, NFSPROC_T *p,
|
||||
* will be extended when ops are done on the delegation
|
||||
* stateid, up to the timelimit.)
|
||||
*/
|
||||
stp->ls_delegtime = NFSD_MONOSEC + (2 * nfsrv_lease) +
|
||||
NFSRV_LEASEDELTA;
|
||||
stp->ls_delegtimelimit = NFSD_MONOSEC + (6 * nfsrv_lease) +
|
||||
NFSRV_LEASEDELTA;
|
||||
stp->ls_flags |= NFSLCK_DELEGRECALL;
|
||||
if ((stp->ls_flags & NFSLCK_DELEGRECALL) == 0) {
|
||||
stp->ls_delegtime = NFSD_MONOSEC + (2 * nfsrv_lease) +
|
||||
NFSRV_LEASEDELTA;
|
||||
stp->ls_delegtimelimit = NFSD_MONOSEC + (6 *
|
||||
nfsrv_lease) + NFSRV_LEASEDELTA;
|
||||
stp->ls_flags |= NFSLCK_DELEGRECALL;
|
||||
}
|
||||
stp->ls_lastrecall = time_uptime + 1;
|
||||
|
||||
/*
|
||||
* Loop NFSRV_CBRETRYCNT times while the CBRecall replies
|
||||
|
Loading…
x
Reference in New Issue
Block a user