Skip to content

Commit aa0ebd2

Browse files
committed
NFSD: Add nfsd4_copy time-to-live
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 <[email protected]> Signed-off-by: Chuck Lever <[email protected]>
1 parent ac0514f commit aa0ebd2

File tree

3 files changed

+21
-2
lines changed

3 files changed

+21
-2
lines changed

fs/nfsd/nfs4proc.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,8 +1326,10 @@ void nfsd4_async_copy_reaper(struct nfsd_net *nn)
13261326
list_for_each_safe(pos, next, &clp->async_copies) {
13271327
copy = list_entry(pos, struct nfsd4_copy, copies);
13281328
if (test_bit(NFSD4_COPY_F_OFFLOAD_DONE, &copy->cp_flags)) {
1329-
list_del_init(&copy->copies);
1330-
list_add(&copy->copies, &reaplist);
1329+
if (--copy->cp_ttl) {
1330+
list_del_init(&copy->copies);
1331+
list_add(&copy->copies, &reaplist);
1332+
}
13311333
}
13321334
}
13331335
spin_unlock(&clp->async_lock);
@@ -1921,6 +1923,7 @@ nfsd4_copy(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
19211923
async_copy->cp_nn = nn;
19221924
INIT_LIST_HEAD(&async_copy->copies);
19231925
refcount_set(&async_copy->refcount, 1);
1926+
async_copy->cp_ttl = NFSD_COPY_INITIAL_TTL;
19241927
/* Arbitrary cap on number of pending async copy operations */
19251928
if (atomic_inc_return(&nn->pending_async_copies) >
19261929
(int)rqstp->rq_pool->sp_nrthreads)

fs/nfsd/state.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,21 @@ struct nfs4_cpntf_state {
137137
time64_t cpntf_time; /* last time stateid used */
138138
};
139139

140+
/*
141+
* RFC 7862 Section 4.8 states:
142+
*
143+
* | A copy offload stateid will be valid until either (A) the client
144+
* | or server restarts or (B) the client returns the resource by
145+
* | issuing an OFFLOAD_CANCEL operation or the client replies to a
146+
* | CB_OFFLOAD operation.
147+
*
148+
* Because a client might not reply to a CB_OFFLOAD, or a reply
149+
* might get lost due to connection loss, NFSD purges async copy
150+
* state after a short period to prevent it from accumulating
151+
* over time.
152+
*/
153+
#define NFSD_COPY_INITIAL_TTL 10
154+
140155
struct nfs4_cb_fattr {
141156
struct nfsd4_callback ncf_getattr;
142157
u32 ncf_cb_status;

fs/nfsd/xdr4.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -715,6 +715,7 @@ struct nfsd4_copy {
715715
struct list_head copies;
716716
struct task_struct *copy_task;
717717
refcount_t refcount;
718+
unsigned int cp_ttl;
718719

719720
struct nfsd4_ssc_umount_item *ss_nsui;
720721
struct nfs_fh c_fh;

0 commit comments

Comments
 (0)