OSDN Git Service

nfsd: helper for laundromat expiry calculations
authorJ. Bruce Fields <bfields@redhat.com>
Tue, 2 Mar 2021 15:46:23 +0000 (10:46 -0500)
committerChuck Lever <chuck.lever@oracle.com>
Mon, 22 Mar 2021 14:19:03 +0000 (10:19 -0400)
We do this same logic repeatedly, and it's easy to get the sense of the
comparison wrong.

Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/nfsd/nfs4state.c

index 3290d0a..1aa7d4e 100644 (file)
@@ -5338,6 +5338,22 @@ static bool clients_still_reclaiming(struct nfsd_net *nn)
        return true;
 }
 
+struct laundry_time {
+       time64_t cutoff;
+       time64_t new_timeo;
+};
+
+static bool state_expired(struct laundry_time *lt, time64_t last_refresh)
+{
+       time64_t time_remaining;
+
+       if (last_refresh < lt->cutoff)
+               return true;
+       time_remaining = last_refresh - lt->cutoff;
+       lt->new_timeo = min(lt->new_timeo, time_remaining);
+       return false;
+}
+
 static time64_t
 nfs4_laundromat(struct nfsd_net *nn)
 {
@@ -5347,14 +5363,16 @@ nfs4_laundromat(struct nfsd_net *nn)
        struct nfs4_ol_stateid *stp;
        struct nfsd4_blocked_lock *nbl;
        struct list_head *pos, *next, reaplist;
-       time64_t cutoff = ktime_get_boottime_seconds() - nn->nfsd4_lease;
-       time64_t t, new_timeo = nn->nfsd4_lease;
+       struct laundry_time lt = {
+               .cutoff = ktime_get_boottime_seconds() - nn->nfsd4_lease,
+               .new_timeo = nn->nfsd4_lease
+       };
        struct nfs4_cpntf_state *cps;
        copy_stateid_t *cps_t;
        int i;
 
        if (clients_still_reclaiming(nn)) {
-               new_timeo = 0;
+               lt.new_timeo = 0;
                goto out;
        }
        nfsd4_end_grace(nn);
@@ -5364,7 +5382,7 @@ nfs4_laundromat(struct nfsd_net *nn)
        idr_for_each_entry(&nn->s2s_cp_stateids, cps_t, i) {
                cps = container_of(cps_t, struct nfs4_cpntf_state, cp_stateid);
                if (cps->cp_stateid.sc_type == NFS4_COPYNOTIFY_STID &&
-                               cps->cpntf_time < cutoff)
+                               state_expired(&lt, cps->cpntf_time))
                        _free_cpntf_state_locked(nn, cps);
        }
        spin_unlock(&nn->s2s_cp_lock);
@@ -5372,11 +5390,8 @@ nfs4_laundromat(struct nfsd_net *nn)
        spin_lock(&nn->client_lock);
        list_for_each_safe(pos, next, &nn->client_lru) {
                clp = list_entry(pos, struct nfs4_client, cl_lru);
-               if (clp->cl_time > cutoff) {
-                       t = clp->cl_time - cutoff;
-                       new_timeo = min(new_timeo, t);
+               if (!state_expired(&lt, clp->cl_time))
                        break;
-               }
                if (mark_client_expired_locked(clp)) {
                        trace_nfsd_clid_expired(&clp->cl_clientid);
                        continue;
@@ -5393,11 +5408,8 @@ nfs4_laundromat(struct nfsd_net *nn)
        spin_lock(&state_lock);
        list_for_each_safe(pos, next, &nn->del_recall_lru) {
                dp = list_entry (pos, struct nfs4_delegation, dl_recall_lru);
-               if (dp->dl_time > cutoff) {
-                       t = dp->dl_time - cutoff;
-                       new_timeo = min(new_timeo, t);
+               if (!state_expired(&lt, dp->dl_time))
                        break;
-               }
                WARN_ON(!unhash_delegation_locked(dp));
                list_add(&dp->dl_recall_lru, &reaplist);
        }
@@ -5413,11 +5425,8 @@ nfs4_laundromat(struct nfsd_net *nn)
        while (!list_empty(&nn->close_lru)) {
                oo = list_first_entry(&nn->close_lru, struct nfs4_openowner,
                                        oo_close_lru);
-               if (oo->oo_time > cutoff) {
-                       t = oo->oo_time - cutoff;
-                       new_timeo = min(new_timeo, t);
+               if (!state_expired(&lt, oo->oo_time))
                        break;
-               }
                list_del_init(&oo->oo_close_lru);
                stp = oo->oo_last_closed_stid;
                oo->oo_last_closed_stid = NULL;
@@ -5443,11 +5452,8 @@ nfs4_laundromat(struct nfsd_net *nn)
        while (!list_empty(&nn->blocked_locks_lru)) {
                nbl = list_first_entry(&nn->blocked_locks_lru,
                                        struct nfsd4_blocked_lock, nbl_lru);
-               if (nbl->nbl_time > cutoff) {
-                       t = nbl->nbl_time - cutoff;
-                       new_timeo = min(new_timeo, t);
+               if (!state_expired(&lt, nbl->nbl_time))
                        break;
-               }
                list_move(&nbl->nbl_lru, &reaplist);
                list_del_init(&nbl->nbl_list);
        }
@@ -5460,8 +5466,7 @@ nfs4_laundromat(struct nfsd_net *nn)
                free_blocked_lock(nbl);
        }
 out:
-       new_timeo = max_t(time64_t, new_timeo, NFSD_LAUNDROMAT_MINTIMEOUT);
-       return new_timeo;
+       return max_t(time64_t, lt.new_timeo, NFSD_LAUNDROMAT_MINTIMEOUT);
 }
 
 static struct workqueue_struct *laundry_wq;