summaryrefslogtreecommitdiff
path: root/fs/nfsd/nfs4state.c
diff options
context:
space:
mode:
authorJ. Bruce Fields <bfields@redhat.com>2018-06-08 12:28:47 -0400
committerJ. Bruce Fields <bfields@redhat.com>2018-06-17 10:20:47 -0400
commit03f318ca652889a1aa407e7088b9a2f6a14ae374 (patch)
tree9c60c888c2fa0b4e2bdf1dae64754680e0b7faad /fs/nfsd/nfs4state.c
parentce397d215ccd07b8ae3f71db689aedb85d56ab40 (diff)
nfsd4: extend reclaim period for reclaiming clients
If the client is only renewing state a little sooner than once a lease period, then it might not discover the server has restarted till close to the end of the grace period, and might run out of time to do the actual reclaim. Extend the grace period by a second each time we notice there are clients still trying to reclaim, up to a limit of another whole lease period. Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Diffstat (limited to 'fs/nfsd/nfs4state.c')
-rw-r--r--fs/nfsd/nfs4state.c31
1 files changed, 30 insertions, 1 deletions
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index 857141446d6b..9b2ce80abee0 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -4693,6 +4693,28 @@ nfsd4_end_grace(struct nfsd_net *nn)
*/
}
+/*
+ * If we've waited a lease period but there are still clients trying to
+ * reclaim, wait a little longer to give them a chance to finish.
+ */
+static bool clients_still_reclaiming(struct nfsd_net *nn)
+{
+ unsigned long now = get_seconds();
+ unsigned long double_grace_period_end = nn->boot_time +
+ 2 * nn->nfsd4_lease;
+
+ if (!nn->somebody_reclaimed)
+ return false;
+ nn->somebody_reclaimed = false;
+ /*
+ * If we've given them *two* lease times to reclaim, and they're
+ * still not done, give up:
+ */
+ if (time_after(now, double_grace_period_end))
+ return false;
+ return true;
+}
+
static time_t
nfs4_laundromat(struct nfsd_net *nn)
{
@@ -4706,6 +4728,11 @@ nfs4_laundromat(struct nfsd_net *nn)
time_t t, new_timeo = nn->nfsd4_lease;
dprintk("NFSD: laundromat service - starting\n");
+
+ if (clients_still_reclaiming(nn)) {
+ new_timeo = 0;
+ goto out;
+ }
nfsd4_end_grace(nn);
INIT_LIST_HEAD(&reaplist);
spin_lock(&nn->client_lock);
@@ -4803,7 +4830,7 @@ nfs4_laundromat(struct nfsd_net *nn)
posix_unblock_lock(&nbl->nbl_lock);
free_blocked_lock(nbl);
}
-
+out:
new_timeo = max_t(time_t, new_timeo, NFSD_LAUNDROMAT_MINTIMEOUT);
return new_timeo;
}
@@ -6053,6 +6080,8 @@ nfsd4_lock(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
case 0: /* success! */
nfs4_inc_and_copy_stateid(&lock->lk_resp_stateid, &lock_stp->st_stid);
status = 0;
+ if (lock->lk_reclaim)
+ nn->somebody_reclaimed = true;
break;
case FILE_LOCK_DEFERRED:
nbl = NULL;