Commit 8955e7ce authored by Chuck Lever's avatar Chuck Lever Committed by Trond Myklebust
Browse files

NFS: Implement NFSv4.2's OFFLOAD_STATUS XDR



Add XDR encoding and decoding functions for the NFSv4.2
OFFLOAD_STATUS operation.

Reviewed-by: default avatarJeff Layton <jlayton@kernel.org>
Signed-off-by: default avatarChuck Lever <chuck.lever@oracle.com>
Reviewed-by: default avatarBenjamin Coddington <bcodding@redhat.com>
Link: https://lore.kernel.org/r/20250113153235.48706-13-cel@kernel.org


Signed-off-by: default avatarTrond Myklebust <trond.myklebust@hammerspace.com>
parent 43502f6e
Loading
Loading
Loading
Loading
+86 −0
Original line number Diff line number Diff line
@@ -35,6 +35,11 @@
#define encode_offload_cancel_maxsz	(op_encode_hdr_maxsz + \
					 XDR_QUADLEN(NFS4_STATEID_SIZE))
#define decode_offload_cancel_maxsz	(op_decode_hdr_maxsz)
#define encode_offload_status_maxsz	(op_encode_hdr_maxsz + \
					 XDR_QUADLEN(NFS4_STATEID_SIZE))
#define decode_offload_status_maxsz	(op_decode_hdr_maxsz + \
					 2 /* osr_count */ + \
					 2 /* osr_complete */)
#define encode_copy_notify_maxsz	(op_encode_hdr_maxsz + \
					 XDR_QUADLEN(NFS4_STATEID_SIZE) + \
					 1 + /* nl4_type */ \
@@ -143,6 +148,14 @@
					 decode_sequence_maxsz + \
					 decode_putfh_maxsz + \
					 decode_offload_cancel_maxsz)
#define NFS4_enc_offload_status_sz	(compound_encode_hdr_maxsz + \
					 encode_sequence_maxsz + \
					 encode_putfh_maxsz + \
					 encode_offload_status_maxsz)
#define NFS4_dec_offload_status_sz	(compound_decode_hdr_maxsz + \
					 decode_sequence_maxsz + \
					 decode_putfh_maxsz + \
					 decode_offload_status_maxsz)
#define NFS4_enc_copy_notify_sz		(compound_encode_hdr_maxsz + \
					 encode_sequence_maxsz + \
					 encode_putfh_maxsz + \
@@ -345,6 +358,14 @@ static void encode_offload_cancel(struct xdr_stream *xdr,
	encode_nfs4_stateid(xdr, &args->osa_stateid);
}

static void encode_offload_status(struct xdr_stream *xdr,
				  const struct nfs42_offload_status_args *args,
				  struct compound_hdr *hdr)
{
	encode_op_hdr(xdr, OP_OFFLOAD_STATUS, decode_offload_status_maxsz, hdr);
	encode_nfs4_stateid(xdr, &args->osa_stateid);
}

static void encode_copy_notify(struct xdr_stream *xdr,
			       const struct nfs42_copy_notify_args *args,
			       struct compound_hdr *hdr)
@@ -569,6 +590,25 @@ static void nfs4_xdr_enc_offload_cancel(struct rpc_rqst *req,
	encode_nops(&hdr);
}

/*
 * Encode OFFLOAD_STATUS request
 */
static void nfs4_xdr_enc_offload_status(struct rpc_rqst *req,
					struct xdr_stream *xdr,
					const void *data)
{
	const struct nfs42_offload_status_args *args = data;
	struct compound_hdr hdr = {
		.minorversion = nfs4_xdr_minorversion(&args->osa_seq_args),
	};

	encode_compound_hdr(xdr, req, &hdr);
	encode_sequence(xdr, &args->osa_seq_args, &hdr);
	encode_putfh(xdr, args->osa_src_fh, &hdr);
	encode_offload_status(xdr, args, &hdr);
	encode_nops(&hdr);
}

/*
 * Encode COPY_NOTIFY request
 */
@@ -921,6 +961,26 @@ static int decode_offload_cancel(struct xdr_stream *xdr,
	return decode_op_hdr(xdr, OP_OFFLOAD_CANCEL);
}

static int decode_offload_status(struct xdr_stream *xdr,
				 struct nfs42_offload_status_res *res)
{
	ssize_t result;
	int status;

	status = decode_op_hdr(xdr, OP_OFFLOAD_STATUS);
	if (status)
		return status;
	/* osr_count */
	if (xdr_stream_decode_u64(xdr, &res->osr_count) < 0)
		return -EIO;
	/* osr_complete<1> */
	result = xdr_stream_decode_uint32_array(xdr, &res->osr_complete, 1);
	if (result < 0)
		return -EIO;
	res->complete_count = result;
	return 0;
}

static int decode_copy_notify(struct xdr_stream *xdr,
			      struct nfs42_copy_notify_res *res)
{
@@ -1370,6 +1430,32 @@ static int nfs4_xdr_dec_offload_cancel(struct rpc_rqst *rqstp,
	return status;
}

/*
 * Decode OFFLOAD_STATUS response
 */
static int nfs4_xdr_dec_offload_status(struct rpc_rqst *rqstp,
				       struct xdr_stream *xdr,
				       void *data)
{
	struct nfs42_offload_status_res *res = data;
	struct compound_hdr hdr;
	int status;

	status = decode_compound_hdr(xdr, &hdr);
	if (status)
		goto out;
	status = decode_sequence(xdr, &res->osr_seq_res, rqstp);
	if (status)
		goto out;
	status = decode_putfh(xdr);
	if (status)
		goto out;
	status = decode_offload_status(xdr, res);

out:
	return status;
}

/*
 * Decode COPY_NOTIFY response
 */
+1 −0
Original line number Diff line number Diff line
@@ -7702,6 +7702,7 @@ const struct rpc_procinfo nfs4_procedures[] = {
	PROC42(CLONE,		enc_clone,		dec_clone),
	PROC42(COPY,		enc_copy,		dec_copy),
	PROC42(OFFLOAD_CANCEL,	enc_offload_cancel,	dec_offload_cancel),
	PROC42(OFFLOAD_STATUS,	enc_offload_status,	dec_offload_status),
	PROC42(COPY_NOTIFY,	enc_copy_notify,	dec_copy_notify),
	PROC(LOOKUPP,		enc_lookupp,		dec_lookupp),
	PROC42(LAYOUTERROR,	enc_layouterror,	dec_layouterror),
+1 −0
Original line number Diff line number Diff line
@@ -691,6 +691,7 @@ enum {
	NFSPROC4_CLNT_LISTXATTRS,
	NFSPROC4_CLNT_REMOVEXATTR,
	NFSPROC4_CLNT_READ_PLUS,
	NFSPROC4_CLNT_OFFLOAD_STATUS,
};

/* nfs41 types */
+3 −2
Original line number Diff line number Diff line
@@ -1515,8 +1515,9 @@ struct nfs42_offload_status_args {

struct nfs42_offload_status_res {
	struct nfs4_sequence_res	osr_seq_res;
	uint64_t			osr_count;
	int				osr_status;
	u64				osr_count;
	int				complete_count;
	u32				osr_complete;
};

struct nfs42_copy_notify_args {