]> git.proxmox.com Git - mirror_ubuntu-jammy-kernel.git/commitdiff
NFSD: Have legacy NFSD WRITE decoders use xdr_stream_subsegment()
authorChuck Lever <chuck.lever@oracle.com>
Thu, 30 Sep 2021 21:06:21 +0000 (17:06 -0400)
committerPaolo Pisati <paolo.pisati@canonical.com>
Wed, 9 Mar 2022 14:17:45 +0000 (15:17 +0100)
BugLink: https://bugs.launchpad.net/bugs/1964361
[ Upstream commit dae9a6cab8009e526570e7477ce858dcdfeb256e ]

Refactor.

Now that the NFSv2 and NFSv3 XDR decoders have been converted to
use xdr_streams, the WRITE decoder functions can use
xdr_stream_subsegment() to extract the WRITE payload into its own
xdr_buf, just as the NFSv4 WRITE XDR decoder currently does.

That makes it possible to pass the first kvec, pages array + length,
page_base, and total payload length via a single function parameter.

The payload's page_base is not yet assigned or used, but will be in
subsequent patches.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Signed-off-by: J. Bruce Fields <bfields@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Paolo Pisati <paolo.pisati@canonical.com>
fs/nfsd/nfs3proc.c
fs/nfsd/nfs3xdr.c
fs/nfsd/nfs4proc.c
fs/nfsd/nfsproc.c
fs/nfsd/nfsxdr.c
fs/nfsd/xdr.h
fs/nfsd/xdr3.h
include/linux/sunrpc/svc.h
net/sunrpc/svc.c

index 9918d6ad23ec95c2d1b44e6844aa614a9ad08723..354bbfcd96aae47a0d16d406b307b08d2af71bfb 100644 (file)
@@ -210,8 +210,7 @@ nfsd3_proc_write(struct svc_rqst *rqstp)
 
        fh_copy(&resp->fh, &argp->fh);
        resp->committed = argp->stable;
-       nvecs = svc_fill_write_vector(rqstp, rqstp->rq_arg.pages,
-                                     &argp->first, cnt);
+       nvecs = svc_fill_write_vector(rqstp, &argp->payload);
        if (!nvecs) {
                resp->status = nfserr_io;
                goto out;
index 7a900131d20ca19be80e9abe32790405072bf8cf..0ee156b9c9d719263bfbf8120fd4961971637c0a 100644 (file)
@@ -621,9 +621,6 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
        struct xdr_stream *xdr = &rqstp->rq_arg_stream;
        struct nfsd3_writeargs *args = rqstp->rq_argp;
        u32 max_blocksize = svc_max_payload(rqstp);
-       struct kvec *head = rqstp->rq_arg.head;
-       struct kvec *tail = rqstp->rq_arg.tail;
-       size_t remaining;
 
        if (!svcxdr_decode_nfs_fh3(xdr, &args->fh))
                return 0;
@@ -641,17 +638,12 @@ nfs3svc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
        /* request sanity */
        if (args->count != args->len)
                return 0;
-       remaining = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len;
-       remaining -= xdr_stream_pos(xdr);
-       if (remaining < xdr_align_size(args->len))
-               return 0;
        if (args->count > max_blocksize) {
                args->count = max_blocksize;
                args->len = max_blocksize;
        }
-
-       args->first.iov_base = xdr->p;
-       args->first.iov_len = head->iov_len - xdr_stream_pos(xdr);
+       if (!xdr_stream_subsegment(xdr, &args->payload, args->count))
+               return 0;
 
        return 1;
 }
index 4b9a3b90a41ff357b3d16a67a0b738d9e6ae5fe3..65200910107f3874fa5019da01c4a95ce91c7698 100644 (file)
@@ -1038,8 +1038,7 @@ nfsd4_write(struct svc_rqst *rqstp, struct nfsd4_compound_state *cstate,
 
        write->wr_how_written = write->wr_stable_how;
 
-       nvecs = svc_fill_write_vector(rqstp, write->wr_payload.pages,
-                                     write->wr_payload.head, write->wr_buflen);
+       nvecs = svc_fill_write_vector(rqstp, &write->wr_payload);
        WARN_ON_ONCE(nvecs > ARRAY_SIZE(rqstp->rq_vec));
 
        status = nfsd_vfs_write(rqstp, &cstate->current_fh, nf,
index 19c568b8a527fdf4573ddc338dd58060bcf97e2a..de282f3273c501bd51a1991e83a8069123e10532 100644 (file)
@@ -234,8 +234,7 @@ nfsd_proc_write(struct svc_rqst *rqstp)
                SVCFH_fmt(&argp->fh),
                argp->len, argp->offset);
 
-       nvecs = svc_fill_write_vector(rqstp, rqstp->rq_arg.pages,
-                                     &argp->first, cnt);
+       nvecs = svc_fill_write_vector(rqstp, &argp->payload);
        if (!nvecs) {
                resp->status = nfserr_io;
                goto out;
index a06c05fe3b421895a13d2ed1c7ac11794c1ba67d..26a42f87c24093cd9f3f38fb811d3ecbf69cbd3f 100644 (file)
@@ -325,10 +325,7 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
 {
        struct xdr_stream *xdr = &rqstp->rq_arg_stream;
        struct nfsd_writeargs *args = rqstp->rq_argp;
-       struct kvec *head = rqstp->rq_arg.head;
-       struct kvec *tail = rqstp->rq_arg.tail;
        u32 beginoffset, totalcount;
-       size_t remaining;
 
        if (!svcxdr_decode_fhandle(xdr, &args->fh))
                return 0;
@@ -346,12 +343,8 @@ nfssvc_decode_writeargs(struct svc_rqst *rqstp, __be32 *p)
                return 0;
        if (args->len > NFSSVC_MAXBLKSIZE_V2)
                return 0;
-       remaining = head->iov_len + rqstp->rq_arg.page_len + tail->iov_len;
-       remaining -= xdr_stream_pos(xdr);
-       if (remaining < xdr_align_size(args->len))
+       if (!xdr_stream_subsegment(xdr, &args->payload, args->len))
                return 0;
-       args->first.iov_base = xdr->p;
-       args->first.iov_len = head->iov_len - xdr_stream_pos(xdr);
 
        return 1;
 }
index f45b4bc93f527da80d01d26616275d953e7ea18d..80fd6d7f3404a6fde68860c23ecadadde34e772e 100644 (file)
@@ -33,7 +33,7 @@ struct nfsd_writeargs {
        svc_fh                  fh;
        __u32                   offset;
        int                     len;
-       struct kvec             first;
+       struct xdr_buf          payload;
 };
 
 struct nfsd_createargs {
index 933008382bbeb09348bcdb6ac20c493cdf4c951e..712c117300cb746ef3e199ff1f52ccbdd98f2278 100644 (file)
@@ -40,7 +40,7 @@ struct nfsd3_writeargs {
        __u32                   count;
        int                     stable;
        __u32                   len;
-       struct kvec             first;
+       struct xdr_buf          payload;
 };
 
 struct nfsd3_createargs {
index 064c96157d1f0b6a8444a233c9cd9469813eeaf7..6263410c948a088e179f6a31aac47ab2a6e00540 100644 (file)
@@ -532,8 +532,7 @@ int            svc_encode_result_payload(struct svc_rqst *rqstp,
                                             unsigned int offset,
                                             unsigned int length);
 unsigned int      svc_fill_write_vector(struct svc_rqst *rqstp,
-                                        struct page **pages,
-                                        struct kvec *first, size_t total);
+                                        struct xdr_buf *payload);
 char             *svc_fill_symlink_pathname(struct svc_rqst *rqstp,
                                             struct kvec *first, void *p,
                                             size_t total);
index a3bbe5ce4570fb7d7cdefd7bc8c24cff00d3f5c0..08ca797bb8a46346c1204f8e868ca6a8e621529f 100644 (file)
@@ -1676,16 +1676,17 @@ EXPORT_SYMBOL_GPL(svc_encode_result_payload);
 /**
  * svc_fill_write_vector - Construct data argument for VFS write call
  * @rqstp: svc_rqst to operate on
- * @pages: list of pages containing data payload
- * @first: buffer containing first section of write payload
- * @total: total number of bytes of write payload
+ * @payload: xdr_buf containing only the write data payload
  *
  * Fills in rqstp::rq_vec, and returns the number of elements.
  */
-unsigned int svc_fill_write_vector(struct svc_rqst *rqstp, struct page **pages,
-                                  struct kvec *first, size_t total)
+unsigned int svc_fill_write_vector(struct svc_rqst *rqstp,
+                                  struct xdr_buf *payload)
 {
+       struct page **pages = payload->pages;
+       struct kvec *first = payload->head;
        struct kvec *vec = rqstp->rq_vec;
+       size_t total = payload->len;
        unsigned int i;
 
        /* Some types of transport can present the write payload