NFS: Implement NFSv4.2's OFFLOAD_STATUS XDR
authorChuck Lever <chuck.lever@oracle.com>
Mon, 13 Jan 2025 15:32:39 +0000 (10:32 -0500)
committerTrond Myklebust <trond.myklebust@hammerspace.com>
Mon, 17 Mar 2025 20:51:53 +0000 (16:51 -0400)
Add XDR encoding and decoding functions for the NFSv4.2
OFFLOAD_STATUS operation.

Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Reviewed-by: Benjamin Coddington <bcodding@redhat.com>
Link: https://lore.kernel.org/r/20250113153235.48706-13-cel@kernel.org
Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
fs/nfs/nfs42xdr.c
fs/nfs/nfs4xdr.c
include/linux/nfs4.h
include/linux/nfs_xdr.h

index 5072d7ea72e9e865f1f9f83f11a5deefb051b601..b1b663468249be0a8744b3794c718750fd8b8eb4 100644 (file)
 #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 */ \
                                         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 @@ out:
        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
  */
index 71f45cc0ca74d1600ee2bf70ded41ae958123d72..55bef5fbfa4778d39688658e2e7d4a3ea68b4c43 100644 (file)
@@ -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),
index 9ac83ca8832660d59b15605f39232b54de8db8e6..5fa60fe441b5f96e80429b1f3048588a86f78599 100644 (file)
@@ -691,6 +691,7 @@ enum {
        NFSPROC4_CLNT_LISTXATTRS,
        NFSPROC4_CLNT_REMOVEXATTR,
        NFSPROC4_CLNT_READ_PLUS,
+       NFSPROC4_CLNT_OFFLOAD_STATUS,
 };
 
 /* nfs41 types */
index 9155a6ffc3709e2adceaac0ee03488dc030209eb..dc5288111999c0bf14911c4bbba94480b1c5de06 100644 (file)
@@ -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 {