Skip to content

Commit cc63c21

Browse files
committed
NFSD: Add COPY status code to OFFLOAD_STATUS response
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>
1 parent a8483b9 commit cc63c21

File tree

3 files changed

+17
-4
lines changed

3 files changed

+17
-4
lines changed

fs/nfsd/nfs4proc.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1793,6 +1793,7 @@ static int nfsd4_do_async_copy(void *data)
17931793
}
17941794

17951795
do_callback:
1796+
set_bit(NFSD4_COPY_F_COMPLETED, &copy->cp_flags);
17961797
nfsd4_send_cb_offload(copy);
17971798
cleanup_async_copy(copy);
17981799
return 0;
@@ -2002,11 +2003,16 @@ nfsd4_offload_status(struct svc_rqst *rqstp,
20022003
struct nfsd4_copy *copy;
20032004
struct nfs4_client *clp = cstate->clp;
20042005

2006+
os->completed = false;
20052007
spin_lock(&clp->async_lock);
20062008
copy = find_async_copy_locked(clp, &os->stateid);
2007-
if (copy)
2009+
if (copy) {
20082010
os->count = copy->cp_res.wr_bytes_written;
2009-
else
2011+
if (test_bit(NFSD4_COPY_F_COMPLETED, &copy->cp_flags)) {
2012+
os->completed = true;
2013+
os->status = copy->nfserr;
2014+
}
2015+
} else
20102016
status = nfserr_bad_stateid;
20112017
spin_unlock(&clp->async_lock);
20122018

fs/nfsd/nfs4xdr.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5271,7 +5271,12 @@ nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr,
52715271
if (nfserr != nfs_ok)
52725272
return nfserr;
52735273
/* osr_complete<1> */
5274-
if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT)
5274+
if (os->completed) {
5275+
if (xdr_stream_encode_u32(xdr, 1) != XDR_UNIT)
5276+
return nfserr_resource;
5277+
if (xdr_stream_encode_be32(xdr, os->status) != XDR_UNIT)
5278+
return nfserr_resource;
5279+
} else if (xdr_stream_encode_u32(xdr, 0) != XDR_UNIT)
52755280
return nfserr_resource;
52765281
return nfs_ok;
52775282
}

fs/nfsd/xdr4.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -692,6 +692,7 @@ struct nfsd4_copy {
692692
#define NFSD4_COPY_F_INTRA (1)
693693
#define NFSD4_COPY_F_SYNCHRONOUS (2)
694694
#define NFSD4_COPY_F_COMMITTED (3)
695+
#define NFSD4_COPY_F_COMPLETED (4)
695696

696697
/* response */
697698
__be32 nfserr;
@@ -754,7 +755,8 @@ struct nfsd4_offload_status {
754755

755756
/* response */
756757
u64 count;
757-
u32 status;
758+
__be32 status;
759+
bool completed;
758760
};
759761

760762
struct nfsd4_copy_notify {

0 commit comments

Comments
 (0)