From: cel@kernel.org
To: <linux-nfs@vger.kernel.org>
Cc: Olga Kornievskaia <okorniev@redhat.com>,
Dai Ngo <dai.ngo@oracle.com>, Jeff Layton <jlayton@kernel.org>,
Chuck Lever <chuck.lever@oracle.com>
Subject: [RFC PATCH 6/7] NFSD: Document callback stateid laundering
Date: Wed, 28 Aug 2024 13:40:08 -0400 [thread overview]
Message-ID: <20240828174001.322745-15-cel@kernel.org> (raw)
In-Reply-To: <20240828174001.322745-9-cel@kernel.org>
From: Chuck Lever <chuck.lever@oracle.com>
NFSD removes COPY callback stateids after once lease period. This
practice keeps the list of callback stateids limited to prevent a
DoS possibility, but doesn't comply with the spirit of RFC 7862
Section 4.8, which says:
> 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.
Note there are no BCP 14 compliance keywords in this text, so NFSD
is free to ignore this stateid lifetime guideline without becoming
non-compliant.
Nevertheless, this behavior variance should be explicitly documented
in the code.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/nfsd/nfs4state.c | 36 +++++++++++++++++++++++++-----------
1 file changed, 25 insertions(+), 11 deletions(-)
diff --git a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
index aaebc60cc77c..437b94beb115 100644
--- a/fs/nfsd/nfs4state.c
+++ b/fs/nfsd/nfs4state.c
@@ -6324,6 +6324,29 @@ static void nfsd4_ssc_expire_umount(struct nfsd_net *nn)
}
#endif
+/*
+ * RFC 7862 Section 4.8 says that, if the client hasn't replied to a
+ * CB_OFFLOAD, that COPY callback stateid will live until the client or
+ * server restarts. To prevent a DoS resulting from a pile of these
+ * stateids accruing over time, NFSD purges them after one lease period.
+ */
+static void nfs4_launder_cpntf_statelist(struct nfsd_net *nn,
+ struct laundry_time *lt)
+{
+ struct nfs4_cpntf_state *cps;
+ copy_stateid_t *cps_t;
+ int i;
+
+ spin_lock(&nn->s2s_cp_lock);
+ 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.cs_type == NFS4_COPYNOTIFY_STID &&
+ state_expired(lt, cps->cpntf_time))
+ _free_cpntf_state_locked(nn, cps);
+ }
+ spin_unlock(&nn->s2s_cp_lock);
+}
+
/* Check if any lock belonging to this lockowner has any blockers */
static bool
nfs4_lockowner_has_blockers(struct nfs4_lockowner *lo)
@@ -6495,9 +6518,6 @@ nfs4_laundromat(struct nfsd_net *nn)
.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)) {
lt.new_timeo = 0;
@@ -6505,14 +6525,8 @@ nfs4_laundromat(struct nfsd_net *nn)
}
nfsd4_end_grace(nn);
- spin_lock(&nn->s2s_cp_lock);
- 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.cs_type == NFS4_COPYNOTIFY_STID &&
- state_expired(<, cps->cpntf_time))
- _free_cpntf_state_locked(nn, cps);
- }
- spin_unlock(&nn->s2s_cp_lock);
+ nfs4_launder_cpntf_statelist(nn, <);
+
nfs4_get_client_reaplist(nn, &reaplist, <);
nfs4_process_client_reaplist(&reaplist);
--
2.46.0
next prev parent reply other threads:[~2024-08-28 17:40 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-08-28 17:40 [RFC PATCH 0/7] Possible NFSD COPY clean-ups cel
2024-08-28 17:40 ` [RFC PATCH 1/7] NFSD: Async COPY result needs to return a write verifier cel
2024-08-29 11:38 ` Jeff Layton
2024-08-28 17:40 ` [RFC PATCH 2/7] NFSD: Limit the number of concurrent async COPY operations cel
2024-08-29 11:45 ` Jeff Layton
2024-08-28 17:40 ` [RFC PATCH 3/7] NFSD: Display copy stateids with conventional print formatting cel
2024-08-28 17:40 ` [RFC PATCH 4/7] NFSD: Record the callback stateid in copy tracepoints cel
2024-08-28 17:40 ` [RFC PATCH 5/7] NFSD: Clean up extra whitespace in trace_nfsd_copy_done cel
2024-08-28 17:40 ` cel [this message]
2024-08-28 22:49 ` [RFC PATCH 6/7] NFSD: Document callback stateid laundering Olga Kornievskaia
2024-08-29 14:05 ` Chuck Lever III
2024-08-28 17:40 ` [RFC PATCH 7/7] NFSD: Wrap async copy operations with trace points cel
2024-08-29 12:48 ` [RFC PATCH 0/7] Possible NFSD COPY clean-ups Jeff Layton
2024-08-30 19:31 ` Chuck Lever III
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240828174001.322745-15-cel@kernel.org \
--to=cel@kernel.org \
--cc=chuck.lever@oracle.com \
--cc=dai.ngo@oracle.com \
--cc=jlayton@kernel.org \
--cc=linux-nfs@vger.kernel.org \
--cc=okorniev@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.