On Wed, Sep 09, 2020 at 04:25:34PM -0400, bfields wrote: > On Wed, Sep 09, 2020 at 12:53:18PM -0400, Anna Schumaker wrote: > > On Tue, Sep 8, 2020 at 3:42 PM J. Bruce Fields <bfields@xxxxxxxxxx> wrote: > > > > > > On Tue, Sep 08, 2020 at 12:25:56PM -0400, schumaker.anna@xxxxxxxxx wrote: > > > > From: Anna Schumaker <Anna.Schumaker@xxxxxxxxxx> > > > > > > > > This patch adds READ_PLUS support for returning a single > > > > NFS4_CONTENT_DATA segment to the client. This is basically the same as > > > > the READ operation, only with the extra information about data segments. > > > > > > > > Signed-off-by: Anna Schumaker <Anna.Schumaker@xxxxxxxxxx> > > > > > > > > --- > > > > v5: Fix up nfsd4_read_plus_rsize() calculation > > > > --- > > > > fs/nfsd/nfs4proc.c | 20 +++++++++++ > > > > fs/nfsd/nfs4xdr.c | 83 ++++++++++++++++++++++++++++++++++++++++++++-- > > > > 2 files changed, 101 insertions(+), 2 deletions(-) > > > > > > > > diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c > > > > index eaf50eafa935..0a3df5f10501 100644 > > > > --- a/fs/nfsd/nfs4proc.c > > > > +++ b/fs/nfsd/nfs4proc.c > > > > @@ -2591,6 +2591,19 @@ static inline u32 nfsd4_read_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) > > > > return (op_encode_hdr_size + 2 + XDR_QUADLEN(rlen)) * sizeof(__be32); > > > > } > > > > > > > > +static inline u32 nfsd4_read_plus_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) > > > > +{ > > > > + u32 maxcount = svc_max_payload(rqstp); > > > > + u32 rlen = min(op->u.read.rd_length, maxcount); > > > > + /* > > > > + * Worst case is a single large data segment, so make > > > > + * sure we have enough room to encode that > > > > + */ > > > > > > After the last patch we allow an unlimited number of segments. So a > > > zillion 1-byte segments is also possible, and is a worse case. > > > > > > Possible ways to avoid that kind of thing: > > > > > > - when encoding, stop and return a short read if the xdr-encoded > > > result would exceed the limit calculated here. > > > > Doesn't this happen automatically through calls to xdr_reserve_space()? > > No, xdr_reserve_space() will keep us from running out of buffer > completely, but it won't check that ops come in under the estimates made > in read_plus_rsize(). If it's easier, another option might be just: if we ever get a "small" hole (say, less than 512 bytes), just give up and encode the rest of the result as a single big data segment. --b.