]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
NFSD: Add nfsd4_copy time-to-live
authorChuck Lever <chuck.lever@oracle.com>
Thu, 31 Oct 2024 13:40:08 +0000 (09:40 -0400)
committerChuck Lever <chuck.lever@oracle.com>
Tue, 19 Nov 2024 01:23:11 +0000 (20:23 -0500)
Keep async copy state alive for a few lease cycles after the copy
completes so that OFFLOAD_STATUS returns something meaningful.

This means that NFSD's client shutdown processing needs to purge
any of this state that happens to be waiting to die.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
fs/nfsd/nfs4proc.c
fs/nfsd/state.h
fs/nfsd/xdr4.h

index dfc118bf9aa5d33ccf690cacafdcb7c0621c9441..f8a10f90bc7a4b288c20d2733c85f331cc0a8dba 100644 (file)
@@ -1326,8 +1326,10 @@ void nfsd4_async_copy_reaper(struct nfsd_net *nn)
                list_for_each_safe(pos, next, &clp->async_copies) {
                        copy = list_entry(pos, struct nfsd4_copy, copies);
                        if (test_bit(NFSD4_COPY_F_OFFLOAD_DONE, &copy->cp_flags)) {
-                               list_del_init(&copy->copies);
-                               list_add(&copy->copies, &reaplist);
+                               if (--copy->cp_ttl) {
+                                       list_del_init(&copy->copies);
+                                       list_add(&copy->copies, &reaplist);
+                               }
                        }
                }
                spin_unlock(&clp->async_lock);
@@ -1921,6 +1923,7 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
                async_copy->cp_nn = nn;
                INIT_LIST_HEAD(&async_copy->copies);
                refcount_set(&async_copy->refcount, 1);
+               async_copy->cp_ttl = NFSD_COPY_INITIAL_TTL;
                /* Arbitrary cap on number of pending async copy operations */
                if (atomic_inc_return(&nn->pending_async_copies) >
                                (int)rqstp->rq_pool->sp_nrthreads)
index dcbebd53e5f409d0b661c5464a779afa80e9dc62..8092894e8f3cdddd24259368d8bfe1977c3418a6 100644 (file)
@@ -137,6 +137,21 @@ struct nfs4_cpntf_state {
        time64_t                cpntf_time;     /* last time stateid used */
 };
 
+/*
+ * RFC 7862 Section 4.8 states:
+ *
+ * | A copy offload stateid will be valid until either (A) the client
+ * | or server restarts or (B) the client returns the resource by
+ * | issuing an OFFLOAD_CANCEL operation or the client replies to a
+ * | CB_OFFLOAD operation.
+ *
+ * Because a client might not reply to a CB_OFFLOAD, or a reply
+ * might get lost due to connection loss, NFSD purges async copy
+ * state after a short period to prevent it from accumulating
+ * over time.
+ */
+#define NFSD_COPY_INITIAL_TTL 10
+
 struct nfs4_cb_fattr {
        struct nfsd4_callback ncf_getattr;
        u32 ncf_cb_status;
index 5951360f6d0393ce886e2594a7b6ce94f53a31a6..382cc138939655f4489de74adcfe317854844d0b 100644 (file)
@@ -715,6 +715,7 @@ struct nfsd4_copy {
        struct list_head        copies;
        struct task_struct      *copy_task;
        refcount_t              refcount;
+       unsigned int            cp_ttl;
 
        struct nfsd4_ssc_umount_item *ss_nsui;
        struct nfs_fh           c_fh;