From: schumaker.anna@gmail.com
To: bfields@redhat.com, linux-nfs@vger.kernel.org
Cc: Anna.Schumaker@Netapp.com
Subject: [PATCH 3/4] NFSD: Add READ_PLUS hole segment encoding
Date: Fri, 10 Jan 2020 17:35:37 -0500 [thread overview]
Message-ID: <20200110223538.528560-4-Anna.Schumaker@Netapp.com> (raw)
In-Reply-To: <20200110223538.528560-1-Anna.Schumaker@Netapp.com>
From: Anna Schumaker <Anna.Schumaker@Netapp.com>
However, we only encode the hole if it is at the beginning of the range
and treat everything else as data to keep things simple.
Signed-off-by: Anna Schumaker <Anna.Schumaker@Netapp.com>
---
fs/nfsd/nfs4proc.c | 2 +-
fs/nfsd/nfs4xdr.c | 47 ++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 46 insertions(+), 3 deletions(-)
diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
index 3c11ca9bd5d7..fc8c821eda8b 100644
--- a/fs/nfsd/nfs4proc.c
+++ b/fs/nfsd/nfs4proc.c
@@ -2184,7 +2184,7 @@ static inline u32 nfsd4_read_plus_rsize(struct svc_rqst *rqstp, struct nfsd4_op
u32 maxcount = svc_max_payload(rqstp);
u32 rlen = min(op->u.read.rd_length, maxcount);
/* enough extra xdr space for encoding either a hole or data segment. */
- u32 segments = 1 + 2 + 2;
+ u32 segments = 2 * (1 + 2 + 2);
return (op_encode_hdr_size + 2 + segments + XDR_QUADLEN(rlen)) * sizeof(__be32);
}
diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
index 014e05365c17..552972b35547 100644
--- a/fs/nfsd/nfs4xdr.c
+++ b/fs/nfsd/nfs4xdr.c
@@ -4302,6 +4302,31 @@ nfsd4_encode_read_plus_data(struct nfsd4_compoundres *resp,
return nfserr;
}
+static __be32
+nfsd4_encode_read_plus_hole(struct nfsd4_compoundres *resp, struct nfsd4_read *read,
+ unsigned long maxcount, u32 *eof)
+{
+ struct file *file = read->rd_nf->nf_file;
+ __be32 *p;
+
+ /* Content type, offset, byte count */
+ p = xdr_reserve_space(&resp->xdr, 4 + 8 + 8);
+ if (!p)
+ return nfserr_resource;
+
+ maxcount = min_t(unsigned long, maxcount, read->rd_length);
+
+ *p++ = cpu_to_be32(NFS4_CONTENT_HOLE);
+ p = xdr_encode_hyper(p, read->rd_offset);
+ p = xdr_encode_hyper(p, maxcount);
+
+ *eof = (read->rd_offset + maxcount) >= i_size_read(file_inode(file));
+
+ read->rd_offset += maxcount;
+ read->rd_length = (maxcount > 0) ? read->rd_length - maxcount : 0;
+ return nfs_ok;
+}
+
static __be32
nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr,
struct nfsd4_read *read)
@@ -4311,6 +4336,8 @@ nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr,
struct xdr_stream *xdr = &resp->xdr;
struct file *file;
int starting_len = xdr->buf->len;
+ unsigned int segments = 0;
+ loff_t data_pos;
__be32 *p;
if (nfserr)
@@ -4335,12 +4362,28 @@ nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr,
(xdr->buf->buflen - xdr->buf->len));
maxcount = min_t(unsigned long, maxcount, read->rd_length);
- nfserr = nfsd4_encode_read_plus_data(resp, read, maxcount, &eof);
+ data_pos = vfs_llseek(file, read->rd_offset, SEEK_DATA);
+ if (data_pos == -ENXIO)
+ data_pos = i_size_read(file_inode(file));
+ else if (data_pos < 0)
+ data_pos = read->rd_offset;
+
+ if (data_pos > read->rd_offset) {
+ nfserr = nfsd4_encode_read_plus_hole(resp, read,
+ data_pos - read->rd_offset, &eof);
+ segments++;
+ }
+
+ if (!nfserr && !eof && read->rd_length > 0) {
+ nfserr = nfsd4_encode_read_plus_data(resp, read, maxcount, &eof);
+ segments++;
+ }
+
if (nfserr)
xdr_truncate_encode(xdr, starting_len);
else {
*p++ = htonl(eof);
- *p++ = htonl(1);
+ *p++ = htonl(segments);
}
return nfserr;
--
2.24.1
next prev parent reply other threads:[~2020-01-10 22:35 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-01-10 22:35 [PATCH 0/4] NFSD: Add support for the v4.2 READ_PLUS operation schumaker.anna
2020-01-10 22:35 ` [PATCH 1/4] NFSD: Return eof and maxcount to nfsd4_encode_read() schumaker.anna
2020-01-10 22:35 ` [PATCH 2/4] NFSD: Add READ_PLUS data support schumaker.anna
2020-01-10 22:35 ` schumaker.anna [this message]
2020-01-10 22:35 ` [PATCH 4/4] NFSD: Encode a full READ_PLUS reply schumaker.anna
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=20200110223538.528560-4-Anna.Schumaker@Netapp.com \
--to=schumaker.anna@gmail.com \
--cc=Anna.Schumaker@Netapp.com \
--cc=bfields@redhat.com \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox