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, ©->cp_flags)) {
-                               list_del_init(©->copies);
-                               list_add(©->copies, &reaplist);
+                               if (--copy->cp_ttl) {
+                                       list_del_init(©->copies);
+                                       list_add(©->copies, &reaplist);
+                               }
                        }
                }
                spin_unlock(&clp->async_lock);
                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)
 
        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;