* [RFC PATCH 0/2] NFSD: expand the implementation of OFFLOAD_STATUS
@ 2024-04-30 20:05 cel
2024-04-30 20:05 ` [RFC PATCH 1/2] NFSD: Record status of async copy operation in struct nfsd4_copy cel
2024-04-30 20:05 ` [RFC PATCH 2/2] NFSD: Add COPY status code to OFFLOAD_STATUS response cel
0 siblings, 2 replies; 3+ messages in thread
From: cel @ 2024-04-30 20:05 UTC (permalink / raw)
To: linux-nfs; +Cc: Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
I'm looking at RFC 7862 to try to understand what the various
OFFLOAD_STATUS responses mean.
> 15.9.3. DESCRIPTION
>
> OFFLOAD_STATUS can be used by the client to query the progress of an
> asynchronous operation, which is identified by both CURRENT_FH and
> the osa_stateid. If this operation is successful, the number of
> bytes processed is returned to the client in the osr_count field.
NFSD returns only the byte count today.
> If the optional osr_complete field is present, the asynchronous
> operation has completed. In this case, the status value indicates
> the result of the asynchronous operation.
NFSD currently never returns the status code -- NFSD's response XDR
encoder always stuffs "zero" in the array count for the osr_complete
array. IMO, zero is OK, but only for the “COPY is still running”
case.
Once the async COPY has completed, a subsequent OFFLOAD_STATUS
should show that the COPY succeeded (or failed), until the server
receives the client’s CB_OFFLOAD reply, or until the client’s lease
expires.
For the "COPY has completed successfully" case, the above text
suggests that OFFLOAD_STATUS returns NFS4_OK, and needs to return a
proper status code in the osr_complete array: Probably NFS4_OK.
A "COPY has completed but failed" status can be reported by
OFFLOAD_STATUS returning NFS4_OK and setting the osr_complete field
to the failing COPY status code.
The two patches here change NFSD in that direction.
Chuck Lever (2):
NFSD: Record status of async copy operation in struct nfsd4_copy
NFSD: Add COPY status code to OFFLOAD_STATUS response
fs/nfsd/nfs4proc.c | 31 ++++++++++++++++++-------------
fs/nfsd/nfs4xdr.c | 7 ++++++-
fs/nfsd/xdr4.h | 5 ++++-
3 files changed, 28 insertions(+), 15 deletions(-)
base-commit: 06cd86b25b980a58e5584e9cd38c080467b24c25
--
2.44.0
^ permalink raw reply [flat|nested] 3+ messages in thread
* [RFC PATCH 1/2] NFSD: Record status of async copy operation in struct nfsd4_copy
2024-04-30 20:05 [RFC PATCH 0/2] NFSD: expand the implementation of OFFLOAD_STATUS cel
@ 2024-04-30 20:05 ` cel
2024-04-30 20:05 ` [RFC PATCH 2/2] NFSD: Add COPY status code to OFFLOAD_STATUS response cel
1 sibling, 0 replies; 3+ messages in thread
From: cel @ 2024-04-30 20:05 UTC (permalink / raw)
To: linux-nfs; +Cc: Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
After a client has started an asynchronous COPY operation, a
subsequent OFFLOAD_STATUS operation will need to report the status
code once that COPY operation has completed. The recorded status
record will be used by a subsequent patch.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/nfsd/nfs4proc.c | 21 ++++++++++-----------
fs/nfsd/xdr4.h | 1 +
2 files changed, 11 insertions(+), 11 deletions(-)
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 3dc173b29803..7e6580384cdb 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1737,7 +1737,7 @@ static void cleanup_async_copy(struct nfsd4_copy *copy)
nfs4_put_copy(copy);
}
-static void nfsd4_send_cb_offload(struct nfsd4_copy *copy, __be32 nfserr)
+static void nfsd4_send_cb_offload(struct nfsd4_copy *copy)
{
struct nfsd4_cb_offload *cbo;
@@ -1747,12 +1747,12 @@ static void nfsd4_send_cb_offload(struct nfsd4_copy *copy, __be32 nfserr)
memcpy(&cbo->co_res, ©->cp_res, sizeof(copy->cp_res));
memcpy(&cbo->co_fh, ©->fh, sizeof(copy->fh));
- cbo->co_nfserr = nfserr;
+ cbo->co_nfserr = copy->nfserr;
nfsd4_init_cb(&cbo->co_cb, copy->cp_clp, &nfsd4_cb_offload_ops,
NFSPROC4_CLNT_CB_OFFLOAD);
trace_nfsd_cb_offload(copy->cp_clp, &cbo->co_res.cb_stateid,
- &cbo->co_fh, copy->cp_count, nfserr);
+ &cbo->co_fh, copy->cp_count, copy->nfserr);
nfsd4_run_cb(&cbo->co_cb);
}
@@ -1766,7 +1766,6 @@ static void nfsd4_send_cb_offload(struct nfsd4_copy *copy, __be32 nfserr)
static int nfsd4_do_async_copy(void *data)
{
struct nfsd4_copy *copy = (struct nfsd4_copy *)data;
- __be32 nfserr;
trace_nfsd_copy_do_async(copy);
if (nfsd4_ssc_is_inter(copy)) {
@@ -1777,24 +1776,24 @@ static int nfsd4_do_async_copy(void *data)
if (IS_ERR(filp)) {
switch (PTR_ERR(filp)) {
case -EBADF:
- nfserr = nfserr_wrong_type;
+ copy->nfserr = nfserr_wrong_type;
break;
default:
- nfserr = nfserr_offload_denied;
+ copy->nfserr = nfserr_offload_denied;
}
/* ss_mnt will be unmounted by the laundromat */
goto do_callback;
}
- nfserr = nfsd4_do_copy(copy, filp, copy->nf_dst->nf_file,
- false);
+ copy->nfserr = nfsd4_do_copy(copy, filp, copy->nf_dst->nf_file,
+ false);
nfsd4_cleanup_inter_ssc(copy->ss_nsui, filp, copy->nf_dst);
} else {
- nfserr = nfsd4_do_copy(copy, copy->nf_src->nf_file,
- copy->nf_dst->nf_file, false);
+ copy->nfserr = nfsd4_do_copy(copy, copy->nf_src->nf_file,
+ copy->nf_dst->nf_file, false);
}
do_callback:
- nfsd4_send_cb_offload(copy, nfserr);
+ nfsd4_send_cb_offload(copy);
cleanup_async_copy(copy);
return 0;
}
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 446e72b0385e..62805931e857 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -694,6 +694,7 @@ struct nfsd4_copy {
#define NFSD4_COPY_F_COMMITTED (3)
/* response */
+ __be32 nfserr;
struct nfsd42_write_res cp_res;
struct knfsd_fh fh;
--
2.44.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* [RFC PATCH 2/2] NFSD: Add COPY status code to OFFLOAD_STATUS response
2024-04-30 20:05 [RFC PATCH 0/2] NFSD: expand the implementation of OFFLOAD_STATUS cel
2024-04-30 20:05 ` [RFC PATCH 1/2] NFSD: Record status of async copy operation in struct nfsd4_copy cel
@ 2024-04-30 20:05 ` cel
1 sibling, 0 replies; 3+ messages in thread
From: cel @ 2024-04-30 20:05 UTC (permalink / raw)
To: linux-nfs; +Cc: Chuck Lever
From: Chuck Lever <chuck.lever@oracle.com>
Clients that send an OFFLOAD_STATUS might want to distinguish
between an async COPY operation that is still running, has
completed successfully, or that has failed.
The intention of this patch is to make NFSD behave like this:
* Copy still running:
OFFLOAD_STATUS returns NFS4_OK, the number of bytes copied
so far, and an empty osr_status array
* Copy completed successfully:
OFFLOAD_STATUS returns NFS4_OK, the number of bytes copied,
and an osr_status of NFS4_OK
* Copy failed:
OFFLOAD_STATUS returns NFS4_OK, the number of bytes copied,
and an osr_status other than NFS4_OK
* Copy operation lost, canceled, or otherwise unrecognized:
OFFLOAD_STATUS returns NFS4ERR_BAD_STATEID
NB: Though RFC 7862 Section 11.2 lists a small set of NFS status
codes that are valid for OFFLOAD_STATUS, there do not seem to be any
explicit spec limits on the status codes that may be returned in the
osr_status field.
At this time we have no unit tests for COPY and its brethren, as
pynfs does not yet implement support for NFSv4.2.
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---
fs/nfsd/nfs4proc.c | 10 ++++++++--
fs/nfsd/nfs4xdr.c | 7 ++++++-
fs/nfsd/xdr4.h | 4 +++-
3 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 7e6580384cdb..ea3cc3e870a7 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -1793,6 +1793,7 @@ static int nfsd4_do_async_copy(void *data)
}
do_callback:
+ set_bit(NFSD4_COPY_F_COMPLETED, ©->cp_flags);
nfsd4_send_cb_offload(copy);
cleanup_async_copy(copy);
return 0;
@@ -2002,11 +2003,16 @@ nfsd4_offload_status(struct svc_rqst *rqstp,
struct nfsd4_copy *copy;
struct nfs4_client *clp = cstate->clp;
+ os->completed = false;
spin_lock(&clp->async_lock);
copy = find_async_copy_locked(clp, &os->stateid);
- if (copy)
+ if (copy) {
os->count = copy->cp_res.wr_bytes_written;
- else
+ if (test_bit(NFSD4_COPY_F_COMPLETED, ©->cp_flags)) {
+ os->completed = true;
+ os->status = copy->nfserr;
+ }
+ } else
status = nfserr_bad_stateid;
spin_unlock(&clp->async_lock);
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 85d43b3249f9..b1312312b99f 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -5271,7 +5271,12 @@ nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr,
if (nfserr != nfs_ok)
return nfserr;
/* osr_complete<1> */
- if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT)
+ if (os->completed) {
+ if (xdr_stream_encode_u32(xdr, 1) != XDR_UNIT)
+ return nfserr_resource;
+ if (xdr_stream_encode_be32(xdr, os->status) != XDR_UNIT)
+ return nfserr_resource;
+ } else if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT)
return nfserr_resource;
return nfs_ok;
}
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 62805931e857..fbdd42cde1fa 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -692,6 +692,7 @@ struct nfsd4_copy {
#define NFSD4_COPY_F_INTRA (1)
#define NFSD4_COPY_F_SYNCHRONOUS (2)
#define NFSD4_COPY_F_COMMITTED (3)
+#define NFSD4_COPY_F_COMPLETED (4)
/* response */
__be32 nfserr;
@@ -754,7 +755,8 @@ struct nfsd4_offload_status {
/* response */
u64 count;
- u32 status;
+ __be32 status;
+ bool completed;
};
struct nfsd4_copy_notify {
--
2.44.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
end of thread, other threads:[~2024-04-30 20:05 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-04-30 20:05 [RFC PATCH 0/2] NFSD: expand the implementation of OFFLOAD_STATUS cel
2024-04-30 20:05 ` [RFC PATCH 1/2] NFSD: Record status of async copy operation in struct nfsd4_copy cel
2024-04-30 20:05 ` [RFC PATCH 2/2] NFSD: Add COPY status code to OFFLOAD_STATUS response cel
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox