All of lore.kernel.org
 help / color / mirror / Atom feed
From: trondmy@kernel.org
To: linux-nfs@vger.kernel.org
Subject: [PATCH v2 11/15] NFSv4.2: decode_read_plus_hole() needs to check the extent offset
Date: Fri, 11 Dec 2020 12:25:17 -0500	[thread overview]
Message-ID: <20201211172521.5567-12-trondmy@kernel.org> (raw)
In-Reply-To: <20201211172521.5567-11-trondmy@kernel.org>

From: Trond Myklebust <trond.myklebust@hammerspace.com>

The server is allowed to return a hole extent with an offset that starts
before the offset supplied in the READ_PLUS argument. Ensure that we
support that case too.

Signed-off-by: Trond Myklebust <trond.myklebust@hammerspace.com>
---
 fs/nfs/nfs42xdr.c | 24 +++++++++++++++++++++---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/fs/nfs/nfs42xdr.c b/fs/nfs/nfs42xdr.c
index 4c6bce3dbaeb..f9faa131a4f5 100644
--- a/fs/nfs/nfs42xdr.c
+++ b/fs/nfs/nfs42xdr.c
@@ -1053,8 +1053,9 @@ static int decode_read_plus_data(struct xdr_stream *xdr, struct nfs_pgio_res *re
 	return 0;
 }
 
-static int decode_read_plus_hole(struct xdr_stream *xdr, struct nfs_pgio_res *res,
-				 uint32_t *eof)
+static int decode_read_plus_hole(struct xdr_stream *xdr,
+				 struct nfs_pgio_args *args,
+				 struct nfs_pgio_res *res, uint32_t *eof)
 {
 	uint64_t offset, length, recvd;
 	__be32 *p;
@@ -1065,6 +1066,20 @@ static int decode_read_plus_hole(struct xdr_stream *xdr, struct nfs_pgio_res *re
 
 	p = xdr_decode_hyper(p, &offset);
 	p = xdr_decode_hyper(p, &length);
+	if (offset != args->offset + res->count) {
+		/* Server returned an out-of-sequence extent */
+		if (offset > args->offset + res->count ||
+		    offset + length < args->offset + res->count) {
+			dprintk("NFS: server returned out of sequence extent: "
+				"offset/size = %llu/%llu != expected %llu\n",
+				(unsigned long long)offset,
+				(unsigned long long)length,
+				(unsigned long long)(args->offset +
+						     res->count));
+			return 1;
+		}
+		length -= args->offset + res->count - offset;
+	}
 	recvd = xdr_expand_hole(xdr, res->count, length);
 	res->count += recvd;
 
@@ -1077,6 +1092,9 @@ static int decode_read_plus_hole(struct xdr_stream *xdr, struct nfs_pgio_res *re
 
 static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
 {
+	struct nfs_pgio_header *hdr =
+		container_of(res, struct nfs_pgio_header, res);
+	struct nfs_pgio_args *args = &hdr->args;
 	uint32_t eof, segments, type;
 	int status, i;
 	__be32 *p;
@@ -1104,7 +1122,7 @@ static int decode_read_plus(struct xdr_stream *xdr, struct nfs_pgio_res *res)
 		if (type == NFS4_CONTENT_DATA)
 			status = decode_read_plus_data(xdr, res, &eof);
 		else if (type == NFS4_CONTENT_HOLE)
-			status = decode_read_plus_hole(xdr, res, &eof);
+			status = decode_read_plus_hole(xdr, args, res, &eof);
 		else
 			return -EINVAL;
 
-- 
2.29.2


  reply	other threads:[~2020-12-11 19:10 UTC|newest]

Thread overview: 16+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-12-11 17:25 [PATCH v2 00/15] Fixes for the NFSv4.2 READ_PLUS operation trondmy
2020-12-11 17:25 ` [PATCH v2 01/15] SUNRPC: _shift_data_left/right_pages should check the shift length trondmy
2020-12-11 17:25   ` [PATCH v2 02/15] SUNRPC: Fixes for xdr_align_data() trondmy
2020-12-11 17:25     ` [PATCH v2 03/15] SUNRPC: Fix xdr_expand_hole() trondmy
2020-12-11 17:25       ` [PATCH v2 04/15] SUNRPC: Cleanup xdr_shrink_bufhead() trondmy
2020-12-11 17:25         ` [PATCH v2 05/15] SUNRPC: _copy_to/from_pages() now check for zero length trondmy
2020-12-11 17:25           ` [PATCH v2 06/15] SUNRPC: Clean up open coded setting of the xdr_stream 'nwords' field trondmy
2020-12-11 17:25             ` [PATCH v2 07/15] SUNRPC: Cleanup - constify a number of xdr_buf helpers trondmy
2020-12-11 17:25               ` [PATCH v2 08/15] SUNRPC: When expanding the buffer, we may need grow the sparse pages trondmy
2020-12-11 17:25                 ` [PATCH v2 09/15] NFSv4.2: Ensure we always reset the result->count in decode_read_plus() trondmy
2020-12-11 17:25                   ` [PATCH v2 10/15] NFSv4.2: decode_read_plus_data() must skip padding after data segment trondmy
2020-12-11 17:25                     ` trondmy [this message]
2020-12-11 17:25                       ` [PATCH v2 12/15] NFSv4.2: Handle hole lengths that exceed the READ_PLUS read buffer trondmy
2020-12-11 17:25                         ` [PATCH v2 13/15] NFSv4.2: Don't error when exiting early on a READ_PLUS buffer overflow trondmy
2020-12-11 17:25                           ` [PATCH v2 14/15] NFSv4.2: Deal with potential READ_PLUS data extent " trondmy
2020-12-11 17:25                             ` [PATCH v2 15/15] NFSv4.2/pnfs: Don't use READ_PLUS with pNFS yet trondmy

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20201211172521.5567-12-trondmy@kernel.org \
    --to=trondmy@kernel.org \
    --cc=linux-nfs@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.