2023-10-02 15:02:50

by Chuck Lever

[permalink] [raw]
Subject: [PATCH v1 0/4] Clean up XDR encoders for NFSv4.1 utility operations

Tidy up the server-side XDR encoders for CREATE_SESSION and
SEQUENCE results. Series applies to nfsd-next. See topic branch
"nfsd4-encoder-overhaul" in this repo:

https://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git

---

Chuck Lever (4):
NFSD: Add a utility function for encoding sessionid4 objects
NFSD: Add nfsd4_encode_channel_attr4()
NFSD: Restructure nfsd4_encode_create_session()
NFSD: Clean up nfsd4_encode_sequence()


fs/nfsd/nfs4xdr.c | 163 +++++++++++++++++++++++++++-------------------
fs/nfsd/xdr4.h | 2 +
2 files changed, 99 insertions(+), 66 deletions(-)

--
Chuck Lever


2023-10-02 15:03:53

by Chuck Lever

[permalink] [raw]
Subject: [PATCH v1 4/4] NFSD: Clean up nfsd4_encode_sequence()

From: Chuck Lever <[email protected]>

De-duplicate open-coded encoding of the sessionid, and convert the
rest of the function to use conventional XDR utility functions.

Signed-off-by: Chuck Lever <[email protected]>
---
fs/nfsd/nfs4xdr.c | 37 +++++++++++++++++++++++++------------
fs/nfsd/xdr4.h | 1 +
2 files changed, 26 insertions(+), 12 deletions(-)

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 505f397a6e5b..f1f0b707c7d9 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -4849,22 +4849,35 @@ nfsd4_encode_sequence(struct nfsd4_compoundres *resp, __be32 nfserr,
{
struct nfsd4_sequence *seq = &u->sequence;
struct xdr_stream *xdr = resp->xdr;
- __be32 *p;

- p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 20);
- if (!p)
- return nfserr_resource;
- p = xdr_encode_opaque_fixed(p, seq->sessionid.data,
- NFS4_MAX_SESSIONID_LEN);
- *p++ = cpu_to_be32(seq->seqid);
- *p++ = cpu_to_be32(seq->slotid);
+ /* sr_sessionid */
+ nfserr = nfsd4_encode_sessionid4(xdr, &seq->sessionid);
+ if (nfserr != nfs_ok)
+ return nfserr;
+ /* sr_sequenceid */
+ nfserr = nfsd4_encode_sequenceid4(xdr, seq->seqid);
+ if (nfserr != nfs_ok)
+ return nfserr;
+ /* sr_slotid */
+ nfserr = nfsd4_encode_slotid4(xdr, seq->slotid);
+ if (nfserr != nfs_ok)
+ return nfserr;
/* Note slotid's are numbered from zero: */
- *p++ = cpu_to_be32(seq->maxslots - 1); /* sr_highest_slotid */
- *p++ = cpu_to_be32(seq->maxslots - 1); /* sr_target_highest_slotid */
- *p++ = cpu_to_be32(seq->status_flags);
+ /* sr_highest_slotid */
+ nfserr = nfsd4_encode_slotid4(xdr, seq->maxslots - 1);
+ if (nfserr != nfs_ok)
+ return nfserr;
+ /* sr_target_highest_slotid */
+ nfserr = nfsd4_encode_slotid4(xdr, seq->maxslots - 1);
+ if (nfserr != nfs_ok)
+ return nfserr;
+ /* sr_status_flags */
+ nfserr = nfsd4_encode_uint32_t(xdr, seq->status_flags);
+ if (nfserr != nfs_ok)
+ return nfserr;

resp->cstate.data_offset = xdr->buf->len; /* DRC cache data pointer */
- return 0;
+ return nfs_ok;
}

static __be32
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 7983eb679ba7..cd124969589e 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -97,6 +97,7 @@ nfsd4_encode_uint32_t(struct xdr_stream *xdr, u32 val)
#define nfsd4_encode_mode4(x, v) nfsd4_encode_uint32_t(x, v)
#define nfsd4_encode_nfs_lease4(x, v) nfsd4_encode_uint32_t(x, v)
#define nfsd4_encode_sequenceid4(x, v) nfsd4_encode_uint32_t(x, v)
+#define nfsd4_encode_slotid4(x, v) nfsd4_encode_uint32_t(x, v)

/**
* nfsd4_encode_uint64_t - Encode an XDR uint64_t type result


2023-10-02 15:04:04

by Chuck Lever

[permalink] [raw]
Subject: [PATCH v1 3/4] NFSD: Restructure nfsd4_encode_create_session()

From: Chuck Lever <[email protected]>

Convert nfsd4_encode_create_session() to use the conventional XDR
encoding utilities.

Signed-off-by: Chuck Lever <[email protected]>
---
fs/nfsd/nfs4xdr.c | 21 ++++++++++++---------
fs/nfsd/xdr4.h | 1 +
2 files changed, 13 insertions(+), 9 deletions(-)

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 01820492c013..505f397a6e5b 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -4822,16 +4822,19 @@ nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
{
struct nfsd4_create_session *sess = &u->create_session;
struct xdr_stream *xdr = resp->xdr;
- __be32 *p;
-
- p = xdr_reserve_space(xdr, 24);
- if (!p)
- return nfserr_resource;
- p = xdr_encode_opaque_fixed(p, sess->sessionid.data,
- NFS4_MAX_SESSIONID_LEN);
- *p++ = cpu_to_be32(sess->seqid);
- *p++ = cpu_to_be32(sess->flags);

+ /* csr_sessionid */
+ nfserr = nfsd4_encode_sessionid4(xdr, &sess->sessionid);
+ if (nfserr != nfs_ok)
+ return nfserr;
+ /* csr_sequence */
+ nfserr = nfsd4_encode_sequenceid4(xdr, sess->seqid);
+ if (nfserr != nfs_ok)
+ return nfserr;
+ /* csr_flags */
+ nfserr = nfsd4_encode_uint32_t(xdr, sess->flags);
+ if (nfserr != nfs_ok)
+ return nfserr;
/* csr_fore_chan_attrs */
nfserr = nfsd4_encode_channel_attrs4(xdr, &sess->fore_channel);
if (nfserr != nfs_ok)
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index a9ff01034ac1..7983eb679ba7 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -96,6 +96,7 @@ nfsd4_encode_uint32_t(struct xdr_stream *xdr, u32 val)
#define nfsd4_encode_count4(x, v) nfsd4_encode_uint32_t(x, v)
#define nfsd4_encode_mode4(x, v) nfsd4_encode_uint32_t(x, v)
#define nfsd4_encode_nfs_lease4(x, v) nfsd4_encode_uint32_t(x, v)
+#define nfsd4_encode_sequenceid4(x, v) nfsd4_encode_uint32_t(x, v)

/**
* nfsd4_encode_uint64_t - Encode an XDR uint64_t type result


2023-10-02 15:04:04

by Chuck Lever

[permalink] [raw]
Subject: [PATCH v1 2/4] NFSD: Add nfsd4_encode_channel_attr4()

From: Chuck Lever <[email protected]>

De-duplicate the encoding of the fore channel and backchannel
attributes.

Signed-off-by: Chuck Lever <[email protected]>
---
fs/nfsd/nfs4xdr.c | 80 +++++++++++++++++++++++++++++------------------------
1 file changed, 44 insertions(+), 36 deletions(-)

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index e41e46213444..01820492c013 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -4778,6 +4778,44 @@ nfsd4_encode_exchange_id(struct nfsd4_compoundres *resp, __be32 nfserr,
return 0;
}

+static __be32
+nfsd4_encode_channel_attrs4(struct xdr_stream *xdr,
+ const struct nfsd4_channel_attrs *attrs)
+{
+ __be32 status;
+
+ /* ca_headerpadsize */
+ status = nfsd4_encode_count4(xdr, 0);
+ if (status != nfs_ok)
+ return status;
+ /* ca_maxrequestsize */
+ status = nfsd4_encode_count4(xdr, attrs->maxreq_sz);
+ if (status != nfs_ok)
+ return status;
+ /* ca_maxresponsesize */
+ status = nfsd4_encode_count4(xdr, attrs->maxresp_sz);
+ if (status != nfs_ok)
+ return status;
+ /* ca_maxresponsesize_cached */
+ status = nfsd4_encode_count4(xdr, attrs->maxresp_cached);
+ if (status != nfs_ok)
+ return status;
+ /* ca_maxoperations */
+ status = nfsd4_encode_count4(xdr, attrs->maxops);
+ if (status != nfs_ok)
+ return status;
+ /* ca_maxrequests */
+ status = nfsd4_encode_count4(xdr, attrs->maxreqs);
+ if (status != nfs_ok)
+ return status;
+ /* ca_rdma_ird<1> */
+ if (xdr_stream_encode_u32(xdr, attrs->nr_rdma_attrs) != XDR_UNIT)
+ return nfserr_resource;
+ if (attrs->nr_rdma_attrs)
+ return nfsd4_encode_uint32_t(xdr, attrs->rdma_attrs);
+ return nfs_ok;
+}
+
static __be32
nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
union nfsd4_op_u *u)
@@ -4794,42 +4832,12 @@ nfsd4_encode_create_session(struct nfsd4_compoundres *resp, __be32 nfserr,
*p++ = cpu_to_be32(sess->seqid);
*p++ = cpu_to_be32(sess->flags);

- p = xdr_reserve_space(xdr, 28);
- if (!p)
- return nfserr_resource;
- *p++ = cpu_to_be32(0); /* headerpadsz */
- *p++ = cpu_to_be32(sess->fore_channel.maxreq_sz);
- *p++ = cpu_to_be32(sess->fore_channel.maxresp_sz);
- *p++ = cpu_to_be32(sess->fore_channel.maxresp_cached);
- *p++ = cpu_to_be32(sess->fore_channel.maxops);
- *p++ = cpu_to_be32(sess->fore_channel.maxreqs);
- *p++ = cpu_to_be32(sess->fore_channel.nr_rdma_attrs);
-
- if (sess->fore_channel.nr_rdma_attrs) {
- p = xdr_reserve_space(xdr, 4);
- if (!p)
- return nfserr_resource;
- *p++ = cpu_to_be32(sess->fore_channel.rdma_attrs);
- }
-
- p = xdr_reserve_space(xdr, 28);
- if (!p)
- return nfserr_resource;
- *p++ = cpu_to_be32(0); /* headerpadsz */
- *p++ = cpu_to_be32(sess->back_channel.maxreq_sz);
- *p++ = cpu_to_be32(sess->back_channel.maxresp_sz);
- *p++ = cpu_to_be32(sess->back_channel.maxresp_cached);
- *p++ = cpu_to_be32(sess->back_channel.maxops);
- *p++ = cpu_to_be32(sess->back_channel.maxreqs);
- *p++ = cpu_to_be32(sess->back_channel.nr_rdma_attrs);
-
- if (sess->back_channel.nr_rdma_attrs) {
- p = xdr_reserve_space(xdr, 4);
- if (!p)
- return nfserr_resource;
- *p++ = cpu_to_be32(sess->back_channel.rdma_attrs);
- }
- return 0;
+ /* csr_fore_chan_attrs */
+ nfserr = nfsd4_encode_channel_attrs4(xdr, &sess->fore_channel);
+ if (nfserr != nfs_ok)
+ return nfserr;
+ /* csr_back_chan_attrs */
+ return nfsd4_encode_channel_attrs4(xdr, &sess->back_channel);
}

static __be32


2023-10-02 15:13:21

by Chuck Lever

[permalink] [raw]
Subject: [PATCH v1 1/4] NFSD: Add a utility function for encoding sessionid4 objects

From: Chuck Lever <[email protected]>

There is more than one NFSv4 operation that needs to encode a
sessionid4, so extract that data type into a separate helper.

Signed-off-by: Chuck Lever <[email protected]>
---
fs/nfsd/nfs4xdr.c | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)

diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 59ac16985775..e41e46213444 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -3881,6 +3881,14 @@ nfsd4_encode_stateid4(struct xdr_stream *xdr, const stateid_t *sid)
return nfs_ok;
}

+static __be32
+nfsd4_encode_sessionid4(struct xdr_stream *xdr,
+ const struct nfs4_sessionid *sessionid)
+{
+ return nfsd4_encode_opaque_fixed(xdr, sessionid->data,
+ NFS4_MAX_SESSIONID_LEN);
+}
+
static __be32
nfsd4_encode_access(struct nfsd4_compoundres *resp, __be32 nfserr,
union nfsd4_op_u *u)
@@ -3902,17 +3910,16 @@ static __be32 nfsd4_encode_bind_conn_to_session(struct nfsd4_compoundres *resp,
{
struct nfsd4_bind_conn_to_session *bcts = &u->bind_conn_to_session;
struct xdr_stream *xdr = resp->xdr;
- __be32 *p;

- p = xdr_reserve_space(xdr, NFS4_MAX_SESSIONID_LEN + 8);
- if (!p)
+ /* bctsr_sessid */
+ nfserr = nfsd4_encode_sessionid4(xdr, &bcts->sessionid);
+ if (nfserr != nfs_ok)
+ return nfserr;
+ /* bctsr_dir */
+ if (xdr_stream_encode_u32(xdr, bcts->dir) != XDR_UNIT)
return nfserr_resource;
- p = xdr_encode_opaque_fixed(p, bcts->sessionid.data,
- NFS4_MAX_SESSIONID_LEN);
- *p++ = cpu_to_be32(bcts->dir);
- /* Upshifting from TCP to RDMA is not supported */
- *p++ = cpu_to_be32(0);
- return 0;
+ /* bctsr_use_conn_in_rdma_mode */
+ return nfsd4_encode_bool(xdr, false);
}

static __be32


2023-10-04 12:56:04

by Jeff Layton

[permalink] [raw]
Subject: Re: [PATCH v1 0/4] Clean up XDR encoders for NFSv4.1 utility operations

On Mon, 2023-10-02 at 10:51 -0400, Chuck Lever wrote:
> Tidy up the server-side XDR encoders for CREATE_SESSION and
> SEQUENCE results. Series applies to nfsd-next. See topic branch
> "nfsd4-encoder-overhaul" in this repo:
>
> https://git.kernel.org/pub/scm/linux/kernel/git/cel/linux.git
>
> ---
>
> Chuck Lever (4):
> NFSD: Add a utility function for encoding sessionid4 objects
> NFSD: Add nfsd4_encode_channel_attr4()
> NFSD: Restructure nfsd4_encode_create_session()
> NFSD: Clean up nfsd4_encode_sequence()
>
>
> fs/nfsd/nfs4xdr.c | 163 +++++++++++++++++++++++++++-------------------
> fs/nfsd/xdr4.h | 2 +
> 2 files changed, 99 insertions(+), 66 deletions(-)
>
> --
> Chuck Lever
>

Reviewed-by: Jeff Layton <[email protected]>