Skip to content

Commit

Permalink
NFSD: Add nfsd4_copy time-to-live
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
chucklever committed Nov 19, 2024
1 parent ac0514f commit aa0ebd2
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 2 deletions.
7 changes: 5 additions & 2 deletions fs/nfsd/nfs4proc.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down Expand Up @@ -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)
Expand Down
15 changes: 15 additions & 0 deletions fs/nfsd/state.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
1 change: 1 addition & 0 deletions fs/nfsd/xdr4.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit aa0ebd2

Please sign in to comment.