summaryrefslogtreecommitdiff
path: root/fs/nfsd
diff options
context:
space:
mode:
authorChuck Lever <chuck.lever@oracle.com>2023-09-25 09:27:58 -0400
committerChuck Lever <chuck.lever@oracle.com>2023-10-16 12:44:28 -0400
commit69f5f0194a7f0f6bb22676a75dc81357a6d22698 (patch)
tree1af93e33c3de9d02b29372deea9a0c060f2a8916 /fs/nfsd
parent73debe47df8e7535e3ca86a050cfd988133fea77 (diff)
downloadlwn-69f5f0194a7f0f6bb22676a75dc81357a6d22698.tar.gz
lwn-69f5f0194a7f0f6bb22676a75dc81357a6d22698.zip
NFSD: Clean up nfsd4_encode_layoutget()
De-duplicate the open-coded stateid4 encoder. Adopt the use of the conventional current XDR encoding helpers. Refactor the encoder to align with the XDR specification. Reviewed-by: Jeff Layton <jlayton@kernel.org> Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Diffstat (limited to 'fs/nfsd')
-rw-r--r--fs/nfsd/nfs4xdr.c52
-rw-r--r--fs/nfsd/xdr4.h2
2 files changed, 36 insertions, 18 deletions
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index d42556bf8f95..8839788b268d 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -4865,31 +4865,47 @@ toosmall:
}
static __be32
+nfsd4_encode_layout4(struct xdr_stream *xdr, const struct nfsd4_layoutget *lgp)
+{
+ const struct nfsd4_layout_ops *ops = nfsd4_layout_ops[lgp->lg_layout_type];
+ __be32 status;
+
+ /* lo_offset */
+ status = nfsd4_encode_offset4(xdr, lgp->lg_seg.offset);
+ if (status != nfs_ok)
+ return status;
+ /* lo_length */
+ status = nfsd4_encode_length4(xdr, lgp->lg_seg.length);
+ if (status != nfs_ok)
+ return status;
+ /* lo_iomode */
+ if (xdr_stream_encode_u32(xdr, lgp->lg_seg.iomode) != XDR_UNIT)
+ return nfserr_resource;
+ /* lo_content */
+ if (xdr_stream_encode_u32(xdr, lgp->lg_layout_type) != XDR_UNIT)
+ return nfserr_resource;
+ return ops->encode_layoutget(xdr, lgp);
+}
+
+static __be32
nfsd4_encode_layoutget(struct nfsd4_compoundres *resp, __be32 nfserr,
union nfsd4_op_u *u)
{
struct nfsd4_layoutget *lgp = &u->layoutget;
struct xdr_stream *xdr = resp->xdr;
- const struct nfsd4_layout_ops *ops;
- __be32 *p;
- p = xdr_reserve_space(xdr, 36 + sizeof(stateid_opaque_t));
- if (!p)
+ /* logr_return_on_close */
+ nfserr = nfsd4_encode_bool(xdr, true);
+ if (nfserr != nfs_ok)
+ return nfserr;
+ /* logr_stateid */
+ nfserr = nfsd4_encode_stateid4(xdr, &lgp->lg_sid);
+ if (nfserr != nfs_ok)
+ return nfserr;
+ /* logr_layout<> */
+ if (xdr_stream_encode_u32(xdr, 1) != XDR_UNIT)
return nfserr_resource;
-
- *p++ = cpu_to_be32(1); /* we always set return-on-close */
- *p++ = cpu_to_be32(lgp->lg_sid.si_generation);
- p = xdr_encode_opaque_fixed(p, &lgp->lg_sid.si_opaque,
- sizeof(stateid_opaque_t));
-
- *p++ = cpu_to_be32(1); /* we always return a single layout */
- p = xdr_encode_hyper(p, lgp->lg_seg.offset);
- p = xdr_encode_hyper(p, lgp->lg_seg.length);
- *p++ = cpu_to_be32(lgp->lg_seg.iomode);
- *p++ = cpu_to_be32(lgp->lg_layout_type);
-
- ops = nfsd4_layout_ops[lgp->lg_layout_type];
- return ops->encode_layoutget(xdr, lgp);
+ return nfsd4_encode_layout4(xdr, lgp);
}
static __be32
diff --git a/fs/nfsd/xdr4.h b/fs/nfsd/xdr4.h
index 43b9c53b7795..1a99db22b25c 100644
--- a/fs/nfsd/xdr4.h
+++ b/fs/nfsd/xdr4.h
@@ -118,6 +118,8 @@ nfsd4_encode_uint64_t(struct xdr_stream *xdr, u64 val)
}
#define nfsd4_encode_changeid4(x, v) nfsd4_encode_uint64_t(x, v)
+#define nfsd4_encode_length4(x, v) nfsd4_encode_uint64_t(x, v)
+#define nfsd4_encode_offset4(x, v) nfsd4_encode_uint64_t(x, v)
/**
* nfsd4_encode_opaque_fixed - Encode a fixed-length XDR opaque type result