From patchwork Mon Aug 17 16:53:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11718971 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 45CFE15E6 for ; Mon, 17 Aug 2020 17:33:43 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 29AEC20716 for ; Mon, 17 Aug 2020 17:33:43 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="eutV8oXG" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2388537AbgHQRdm (ORCPT ); Mon, 17 Aug 2020 13:33:42 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46716 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389099AbgHQQxP (ORCPT ); Mon, 17 Aug 2020 12:53:15 -0400 Received: from mail-io1-xd41.google.com (mail-io1-xd41.google.com [IPv6:2607:f8b0:4864:20::d41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 80B18C061344 for ; Mon, 17 Aug 2020 09:53:13 -0700 (PDT) Received: by mail-io1-xd41.google.com with SMTP id g19so18289617ioh.8 for ; Mon, 17 Aug 2020 09:53:13 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=/SxUNl+jSH6Huy97tnl5zQzeoQGswbqbvVa0pe7sWZQ=; b=eutV8oXGsB32bc/7mIbre4yAY5qRTQHd8wGNVf4H8485rQ7F4mTFtkoSld+ZBvzAz2 TzQsFISgDNC5k/i5frpRQFBrR+4XsKfJ9cxC++QHG3aesRpxECrA2zKxbM6UR0Tl8zLa OZiBeXrZCT6KFw1L3vTYp2DN82aJ/LbaVYnRQfR7tSTVmV6A1hCgiO98SAvlQIIRE8Qx ybvKiBUMTgg00UlH3nMkjQKxnpogabFqFPtg2d9eUoDbkJku23BKfaYl9shogsJCrCcM V1hLjJytsZtEQ0UwSOUbtOlOpZZ/kNrvU6sDDiR5L+tDPtZe10OQsGt25Oij/FU+uBCH O14Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=/SxUNl+jSH6Huy97tnl5zQzeoQGswbqbvVa0pe7sWZQ=; b=fVepb+1rX7MjuB76QJe2aNrVUypWlZKdWusscm6VVQ3xluwvhXZ9Thj0AzwVXFqCfr GmNJMMiNhLIdm6LMOcEfWOMgYoS/k/+nMu3dc5ho3HyQrXJB9ImRKNTMv+b/trR2Zpan xuO1ss1xkH8wU9EPteG53yA78LQHv/QKQDXOkn0bVa5fy8FBsYtdUg0k7ztyaGWpm4oQ 1/DTTjSs5B2K1nLum+KEA0HlOLbi3fMQDeT1UuDeIzkQCDYZzG27HefPrUhBnWiLORQ3 eQb5+alR1QQMZV7b9GcMfa/Sff7REovXOoLvyPvvQFGlTPeWWdm/Bpuz2QY3yzx2Urz6 n3BQ== X-Gm-Message-State: AOAM531AMuO2LMPdYrqTiDUrYCpl72eIlx9TwBx7mTFTxd09H7oj6A2g lz+b/AuKtEAp2wNiR3ZKmAw= X-Google-Smtp-Source: ABdhPJx1cLuKtOxKAx3rmidxB8wpOTYUrdz3NjcBA3YJ8I8EwTzB66LKB1mvLL0fzDn16+dSxH/MqQ== X-Received: by 2002:a02:7691:: with SMTP id z139mr15877294jab.6.1597683192843; Mon, 17 Aug 2020 09:53:12 -0700 (PDT) Received: from gouda.nowheycreamery.com (c-68-32-74-190.hsd1.mi.comcast.net. [68.32.74.190]) by smtp.gmail.com with ESMTPSA id s3sm9410039iol.49.2020.08.17.09.53.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2020 09:53:12 -0700 (PDT) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: bfields@redhat.com, chuck.lever@oracle.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH v4 1/5] SUNRPC/NFSD: Implement xdr_reserve_space_vec() Date: Mon, 17 Aug 2020 12:53:06 -0400 Message-Id: <20200817165310.354092-2-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200817165310.354092-1-Anna.Schumaker@Netapp.com> References: <20200817165310.354092-1-Anna.Schumaker@Netapp.com> MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Anna Schumaker Reserving space for a large READ payload requires special handling when reserving space in the xdr buffer pages. One problem we can have is use of the scratch buffer, which is used to get a pointer to a contiguous region of data up to PAGE_SIZE. When using the scratch buffer, calls to xdr_commit_encode() shift the data to it's proper alignment in the xdr buffer. If we've reserved several pages in a vector, then this could potentially invalidate earlier pointers and result in incorrect READ data being sent to the client. I get around this by looking at the amount of space left in the current page, and never reserve more than that for each entry in the read vector. This lets us place data directly where it needs to go in the buffer pages. Signed-off-by: Anna Schumaker --- fs/nfsd/nfs4xdr.c | 28 +++--------------------- include/linux/sunrpc/xdr.h | 2 ++ net/sunrpc/xdr.c | 45 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 25 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 996ac01ee977..6a1c0a7fae05 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -3584,36 +3584,14 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp, { struct xdr_stream *xdr = &resp->xdr; u32 eof; - int v; int starting_len = xdr->buf->len - 8; - long len; - int thislen; __be32 nfserr; __be32 tmp; - __be32 *p; int pad; - /* - * svcrdma requires every READ payload to start somewhere - * in xdr->pages. - */ - if (xdr->iov == xdr->buf->head) { - xdr->iov = NULL; - xdr->end = xdr->p; - } - - len = maxcount; - v = 0; - while (len) { - thislen = min_t(long, len, PAGE_SIZE); - p = xdr_reserve_space(xdr, thislen); - WARN_ON_ONCE(!p); - resp->rqstp->rq_vec[v].iov_base = p; - resp->rqstp->rq_vec[v].iov_len = thislen; - v++; - len -= thislen; - } - read->rd_vlen = v; + read->rd_vlen = xdr_reserve_space_vec(xdr, resp->rqstp->rq_vec, maxcount); + if (read->rd_vlen < 0) + return nfserr_resource; nfserr = nfsd_readv(resp->rqstp, read->rd_fhp, file, read->rd_offset, resp->rqstp->rq_vec, read->rd_vlen, &maxcount, diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 22c207b2425f..bac459584dd0 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -234,6 +234,8 @@ typedef int (*kxdrdproc_t)(struct rpc_rqst *rqstp, struct xdr_stream *xdr, extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, __be32 *p, struct rpc_rqst *rqst); extern __be32 *xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes); +extern int xdr_reserve_space_vec(struct xdr_stream *xdr, struct kvec *vec, + size_t nbytes); extern void xdr_commit_encode(struct xdr_stream *xdr); extern void xdr_truncate_encode(struct xdr_stream *xdr, size_t len); extern int xdr_restrict_buflen(struct xdr_stream *xdr, int newbuflen); diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index be11d672b5b9..6dfe5dc8b35f 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -648,6 +648,51 @@ __be32 * xdr_reserve_space(struct xdr_stream *xdr, size_t nbytes) } EXPORT_SYMBOL_GPL(xdr_reserve_space); + +/** + * xdr_reserve_space_vec - Reserves a large amount of buffer space for sending + * @xdr: pointer to xdr_stream + * @vec: pointer to a kvec array + * @nbytes: number of bytes to reserve + * + * Reserves enough buffer space to encode 'nbytes' of data and stores the + * pointers in 'vec'. The size argument passed to xdr_reserve_space() is + * determined based on the number of bytes remaining in the current page to + * avoid invalidating iov_base pointers when xdr_commit_encode() is called. + */ +int xdr_reserve_space_vec(struct xdr_stream *xdr, struct kvec *vec, size_t nbytes) +{ + int thislen; + int v = 0; + __be32 *p; + + /* + * svcrdma requires every READ payload to start somewhere + * in xdr->pages. + */ + if (xdr->iov == xdr->buf->head) { + xdr->iov = NULL; + xdr->end = xdr->p; + } + + while (nbytes) { + thislen = xdr->buf->page_len % PAGE_SIZE; + thislen = min_t(size_t, nbytes, PAGE_SIZE - thislen); + + p = xdr_reserve_space(xdr, thislen); + if (!p) + return -EIO; + + vec[v].iov_base = p; + vec[v].iov_len = thislen; + v++; + nbytes -= thislen; + } + + return v; +} +EXPORT_SYMBOL_GPL(xdr_reserve_space_vec); + /** * xdr_truncate_encode - truncate an encode buffer * @xdr: pointer to xdr_stream From patchwork Mon Aug 17 16:53:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11718967 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id C358C14F6 for ; Mon, 17 Aug 2020 17:33:39 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id A0D3F2063A for ; Mon, 17 Aug 2020 17:33:39 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="Y/7D6vZH" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389098AbgHQRdh (ORCPT ); Mon, 17 Aug 2020 13:33:37 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46718 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389100AbgHQQxP (ORCPT ); Mon, 17 Aug 2020 12:53:15 -0400 Received: from mail-il1-x141.google.com (mail-il1-x141.google.com [IPv6:2607:f8b0:4864:20::141]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 50AD1C061345 for ; Mon, 17 Aug 2020 09:53:14 -0700 (PDT) Received: by mail-il1-x141.google.com with SMTP id k4so15112620ilr.12 for ; Mon, 17 Aug 2020 09:53:14 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=EHcR4jC1j2anjFCBSvkhULjFcz+6UCYLyghMDTwoNBI=; b=Y/7D6vZHCCwkq45rdmek00EJj0KWvkYiMCK5kpPayDs3lvYd4fXFWvqUP/6bttmklR yWiXedaIt7gx8b/tvIkSqp04RPNEctfHjdRxFQH7J6JZ/qXOt9nOhLxG0WtCLTH49mG5 jmRAWntD/fEl/TVPxmETubPMedMeHZj/RAbIqYBSImZqlZ1RrhyoQ0ALvqghmmK/OB85 BNO8e6Mv+p11BkkYRyCK0XmD4ZshUDjrg+TRgvw6rj6UKxbqIi5ESYGt3guJHHc2J+Fc PiM0O8Jy654bB4wv4I7wTSu0xUxFk6uLZ8bq+1S8GHHq2REIHfL4yByxb9WbkJlJr31m 03Xg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=EHcR4jC1j2anjFCBSvkhULjFcz+6UCYLyghMDTwoNBI=; b=QRYHK4Bi+mGeBMMag6HigeZfDBi9IEDE8bqDyODIRYgo4SzjgnWoTg71vu4boOZTGa D13Uq5tIU6G6M3iSZxHcSlPji8bOSAkqek3ezR/OEvCGLt6n//RBPCmGhmcvALOrt9J0 Sp4Y7fgWuOqmkTqTjW4AjI38B8c5t4ouS//aH14d1syWBKhfYoX3wB84uCvvgGPgke8Q cYYRZPkH/b+QbGS4LpbKl/EMzlpjCFOwGsiQRhY9CRsLFnYU0p7mZVxQI5Pu3XHdwVTH NFiFhdd8vC0bbMMH3WsiKXvqiFPCDubr5k99m6m4qydD23F3uidgvsYPv8+iRBQgEv7k DH7g== X-Gm-Message-State: AOAM530Tfjdy8ONO55F3npTHi4Jb5nr5fb2RpP0bn49wmQgcvQhf38ir +Sck2DPQpbcnB/+cvrXKd54= X-Google-Smtp-Source: ABdhPJw2E/+W7vBgAgcO1lEh8jKLRXr9WwtzJ82xS5UXKa6dgZu3snwG0wYcOonwSKl9TXMUOeemrA== X-Received: by 2002:a92:d089:: with SMTP id h9mr12046437ilh.60.1597683193861; Mon, 17 Aug 2020 09:53:13 -0700 (PDT) Received: from gouda.nowheycreamery.com (c-68-32-74-190.hsd1.mi.comcast.net. [68.32.74.190]) by smtp.gmail.com with ESMTPSA id s3sm9410039iol.49.2020.08.17.09.53.12 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2020 09:53:13 -0700 (PDT) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: bfields@redhat.com, chuck.lever@oracle.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH v4 2/5] NFSD: Add READ_PLUS data support Date: Mon, 17 Aug 2020 12:53:07 -0400 Message-Id: <20200817165310.354092-3-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200817165310.354092-1-Anna.Schumaker@Netapp.com> References: <20200817165310.354092-1-Anna.Schumaker@Netapp.com> MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Anna Schumaker 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 --- fs/nfsd/nfs4proc.c | 17 ++++++++++ fs/nfsd/nfs4xdr.c | 83 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 98 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index a09c35f0f6f0..9630d33211f2 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -2523,6 +2523,16 @@ 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); + /* enough extra xdr space for encoding either a hole or data segment. */ + u32 segments = 1 + 2 + 2; + + return (op_encode_hdr_size + 2 + segments + XDR_QUADLEN(rlen)) * sizeof(__be32); +} + static inline u32 nfsd4_readdir_rsize(struct svc_rqst *rqstp, struct nfsd4_op *op) { u32 maxcount = 0, rlen = 0; @@ -3059,6 +3069,13 @@ static const struct nfsd4_operation nfsd4_ops[] = { .op_name = "OP_COPY", .op_rsize_bop = nfsd4_copy_rsize, }, + [OP_READ_PLUS] = { + .op_func = nfsd4_read, + .op_release = nfsd4_read_release, + .op_name = "OP_READ_PLUS", + .op_rsize_bop = nfsd4_read_plus_rsize, + .op_get_currentstateid = nfsd4_get_readstateid, + }, [OP_SEEK] = { .op_func = nfsd4_seek, .op_name = "OP_SEEK", diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 6a1c0a7fae05..9af92f538000 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -1957,7 +1957,7 @@ static const nfsd4_dec nfsd4_dec_ops[] = { [OP_LAYOUTSTATS] = (nfsd4_dec)nfsd4_decode_notsupp, [OP_OFFLOAD_CANCEL] = (nfsd4_dec)nfsd4_decode_offload_status, [OP_OFFLOAD_STATUS] = (nfsd4_dec)nfsd4_decode_offload_status, - [OP_READ_PLUS] = (nfsd4_dec)nfsd4_decode_notsupp, + [OP_READ_PLUS] = (nfsd4_dec)nfsd4_decode_read, [OP_SEEK] = (nfsd4_dec)nfsd4_decode_seek, [OP_WRITE_SAME] = (nfsd4_dec)nfsd4_decode_notsupp, [OP_CLONE] = (nfsd4_dec)nfsd4_decode_clone, @@ -4367,6 +4367,85 @@ nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr, return nfserr_resource; p = xdr_encode_hyper(p, os->count); *p++ = cpu_to_be32(0); + return nfserr; +} + +static __be32 +nfsd4_encode_read_plus_data(struct nfsd4_compoundres *resp, + struct nfsd4_read *read, + unsigned long maxcount, u32 *eof) +{ + struct xdr_stream *xdr = &resp->xdr; + struct file *file = read->rd_nf->nf_file; + int starting_len = xdr->buf->len; + __be32 nfserr; + __be32 *p, tmp; + __be64 tmp64; + + /* Content type, offset, byte count */ + p = xdr_reserve_space(xdr, 4 + 8 + 4); + if (!p) + return nfserr_resource; + + read->rd_vlen = xdr_reserve_space_vec(xdr, resp->rqstp->rq_vec, maxcount); + if (read->rd_vlen < 0) + return nfserr_resource; + + nfserr = nfsd_readv(resp->rqstp, read->rd_fhp, file, read->rd_offset, + resp->rqstp->rq_vec, read->rd_vlen, &maxcount, eof); + if (nfserr) + return nfserr; + + tmp = htonl(NFS4_CONTENT_DATA); + write_bytes_to_xdr_buf(xdr->buf, starting_len, &tmp, 4); + tmp64 = cpu_to_be64(read->rd_offset); + write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp64, 8); + tmp = htonl(maxcount); + write_bytes_to_xdr_buf(xdr->buf, starting_len + 12, &tmp, 4); + return nfs_ok; +} + +static __be32 +nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr, + struct nfsd4_read *read) +{ + unsigned long maxcount; + struct xdr_stream *xdr = &resp->xdr; + struct file *file; + int starting_len = xdr->buf->len; + int segments = 0; + __be32 *p, tmp; + u32 eof; + + if (nfserr) + return nfserr; + file = read->rd_nf->nf_file; + + /* eof flag, segment count */ + p = xdr_reserve_space(xdr, 4 + 4); + if (!p) + return nfserr_resource; + xdr_commit_encode(xdr); + + maxcount = svc_max_payload(resp->rqstp); + maxcount = min_t(unsigned long, maxcount, + (xdr->buf->buflen - xdr->buf->len)); + maxcount = min_t(unsigned long, maxcount, read->rd_length); + + eof = read->rd_offset >= i_size_read(file_inode(file)); + if (!eof) { + nfserr = nfsd4_encode_read_plus_data(resp, read, maxcount, &eof); + segments++; + } + + if (nfserr) + xdr_truncate_encode(xdr, starting_len); + else { + tmp = htonl(eof); + write_bytes_to_xdr_buf(xdr->buf, starting_len, &tmp, 4); + tmp = htonl(segments); + write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp, 4); + } return nfserr; } @@ -4509,7 +4588,7 @@ static const nfsd4_enc nfsd4_enc_ops[] = { [OP_LAYOUTSTATS] = (nfsd4_enc)nfsd4_encode_noop, [OP_OFFLOAD_CANCEL] = (nfsd4_enc)nfsd4_encode_noop, [OP_OFFLOAD_STATUS] = (nfsd4_enc)nfsd4_encode_offload_status, - [OP_READ_PLUS] = (nfsd4_enc)nfsd4_encode_noop, + [OP_READ_PLUS] = (nfsd4_enc)nfsd4_encode_read_plus, [OP_SEEK] = (nfsd4_enc)nfsd4_encode_seek, [OP_WRITE_SAME] = (nfsd4_enc)nfsd4_encode_noop, [OP_CLONE] = (nfsd4_enc)nfsd4_encode_noop, From patchwork Mon Aug 17 16:53:08 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11718963 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 5AB9F15E6 for ; Mon, 17 Aug 2020 17:33:37 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 3ED862075B for ; Mon, 17 Aug 2020 17:33:37 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="sTd4EBdi" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389352AbgHQRdg (ORCPT ); Mon, 17 Aug 2020 13:33:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46766 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389102AbgHQQxd (ORCPT ); Mon, 17 Aug 2020 12:53:33 -0400 Received: from mail-io1-xd41.google.com (mail-io1-xd41.google.com [IPv6:2607:f8b0:4864:20::d41]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A8C3CC061347 for ; Mon, 17 Aug 2020 09:53:15 -0700 (PDT) Received: by mail-io1-xd41.google.com with SMTP id v6so18208180iow.11 for ; Mon, 17 Aug 2020 09:53:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=OVQTTMCLpOrm/KIIbHgKLRkACNrFNu799Qop2hNiKpI=; b=sTd4EBdidXOkMHwfQDwH8F+JCgT75ECRvideQDg7pdY6jGviJLPkjZBPIVC0I/hdXQ 3PMbPsacPGzkdV3dDqesPzDhWScR2XxjoiZaInpPZERqGuZ/QWPcOoljjp+HJtX5MDDm 635qTnQ2aQMr5DhmAGOE4yvdEWMhxrFlQc1Ox2xE+mYRYhrafF4lyLNIpSfq1RLTcpph ZpHKixRoXRhplJDOwoIfgMDOZ5q+Vmjn6whZvT1Mbz3SbDRqsAGPbxT3v5JZO1nulnCL vAC8aAKf8cxL7CThHSYyg9BJZBNisv1bMrr9am+F+aSZZ7zONutFwvo33x2Rmf99RRQa eT8A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=OVQTTMCLpOrm/KIIbHgKLRkACNrFNu799Qop2hNiKpI=; b=o5BpFZ+VaN9iKdGWJ+pgi1NZvcAI24QJJwjxZF2U3kbTTuzd6Kz5cTYjIFB5rfTDhu W5Wj/uQtPRd+4+N60PUOAOcGFM6oBXpk1NQ0sTjaKQTQzdtWDngm+5TU24qYLklKv8Ta uIc0IE8d83rz18QTUV8nYWS8sAbUKSgmBSU3chveiOAb3ke+I4UxvfLFF2vE79z3QoNr 2w61p1oW2xoLqAybNbphfeKZeHwn3qcNIF/D/qRf9M8CGZc09LXE080D8vLmzh9vct6t VlAVGm7JCNEk149t7EM/gnEHhvlywfKFLGHMUIbqstkbwaeKlecVQQu5SQ+hxXRCBUYl XznQ== X-Gm-Message-State: AOAM531EoUZ1hXRnuIi5IdIRqUCNVL0679UIJpnmo+NGkcP24bQWfUuL 05CoGPd+ix/V1z1UmQdIHTY= X-Google-Smtp-Source: ABdhPJzhjAQqSY5QsInLkrP2aUDuoIk247aHTWHqYYiLCqRPs6iB73kKxIVKldMd4eeTBuLwf1cnLA== X-Received: by 2002:a6b:b888:: with SMTP id i130mr13058609iof.182.1597683195078; Mon, 17 Aug 2020 09:53:15 -0700 (PDT) Received: from gouda.nowheycreamery.com (c-68-32-74-190.hsd1.mi.comcast.net. [68.32.74.190]) by smtp.gmail.com with ESMTPSA id s3sm9410039iol.49.2020.08.17.09.53.13 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2020 09:53:14 -0700 (PDT) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: bfields@redhat.com, chuck.lever@oracle.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH v4 3/5] NFSD: Add READ_PLUS hole segment encoding Date: Mon, 17 Aug 2020 12:53:08 -0400 Message-Id: <20200817165310.354092-4-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200817165310.354092-1-Anna.Schumaker@Netapp.com> References: <20200817165310.354092-1-Anna.Schumaker@Netapp.com> MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Anna Schumaker However, we still only reply to the READ_PLUS call with a single segment at this time. Signed-off-by: Anna Schumaker --- fs/nfsd/nfs4proc.c | 2 +- fs/nfsd/nfs4xdr.c | 40 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 40 insertions(+), 2 deletions(-) diff --git a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c index 9630d33211f2..36305b846f5a 100644 --- a/fs/nfsd/nfs4proc.c +++ b/fs/nfsd/nfs4proc.c @@ -2528,7 +2528,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 9af92f538000..2fa39217c256 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -4378,10 +4378,14 @@ nfsd4_encode_read_plus_data(struct nfsd4_compoundres *resp, struct xdr_stream *xdr = &resp->xdr; struct file *file = read->rd_nf->nf_file; int starting_len = xdr->buf->len; + loff_t hole_pos = vfs_llseek(file, read->rd_offset, SEEK_HOLE); __be32 nfserr; __be32 *p, tmp; __be64 tmp64; + if (hole_pos > read->rd_offset) + maxcount = min_t(unsigned long, maxcount, hole_pos - read->rd_offset); + /* Content type, offset, byte count */ p = xdr_reserve_space(xdr, 4 + 8 + 4); if (!p) @@ -4405,6 +4409,27 @@ nfsd4_encode_read_plus_data(struct nfsd4_compoundres *resp, return nfs_ok; } +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; + + *p++ = htonl(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)); + return nfs_ok; +} + static __be32 nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_read *read) @@ -4415,6 +4440,7 @@ nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr, int starting_len = xdr->buf->len; int segments = 0; __be32 *p, tmp; + loff_t pos; u32 eof; if (nfserr) @@ -4433,11 +4459,23 @@ nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr, maxcount = min_t(unsigned long, maxcount, read->rd_length); eof = read->rd_offset >= i_size_read(file_inode(file)); - if (!eof) { + if (eof) + goto out; + + pos = vfs_llseek(file, read->rd_offset, SEEK_DATA); + if (pos == -ENXIO) + pos = i_size_read(file_inode(file)); + + if (pos > read->rd_offset) { + maxcount = pos - read->rd_offset; + nfserr = nfsd4_encode_read_plus_hole(resp, read, maxcount, &eof); + segments++; + } else { nfserr = nfsd4_encode_read_plus_data(resp, read, maxcount, &eof); segments++; } +out: if (nfserr) xdr_truncate_encode(xdr, starting_len); else { From patchwork Mon Aug 17 16:53:09 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11718831 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 2D8B215E4 for ; Mon, 17 Aug 2020 16:54:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 0E1C62072E for ; Mon, 17 Aug 2020 16:54:00 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="qUPOgDt3" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389128AbgHQQx6 (ORCPT ); Mon, 17 Aug 2020 12:53:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46768 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389103AbgHQQxd (ORCPT ); Mon, 17 Aug 2020 12:53:33 -0400 Received: from mail-il1-x142.google.com (mail-il1-x142.google.com [IPv6:2607:f8b0:4864:20::142]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B65BCC061348 for ; Mon, 17 Aug 2020 09:53:16 -0700 (PDT) Received: by mail-il1-x142.google.com with SMTP id z3so15125049ilh.3 for ; Mon, 17 Aug 2020 09:53:16 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=RtwFYKDGf1W/tp3xEFF0blS9Fjq7SLSWxBtcEH0xbEQ=; b=qUPOgDt3cvtA5PigsjKYKD0jx+NncQsbU0zTibsUGe6CaexhVZmNCfI3GkYrXgLW/0 r0uhztQuAkyg5YvIBgMlT57VRu6aZvc61P701yzsYt0QLKH+1hviq+gtOXz8+c+rHdVQ gJm5UUVEmRTYAbeh+pQFrLh9itjUsrJX/R8ezuc793epkQBQj0KyUr9Zew7g8mCEY0IE mK+wzAxfIcvG7Xar8XQrnOSVmPULMaTOHdl+gtOfOwAWWZYDj4PMMqfWsoylURFaoOTp YczUhSpkV/m59u4jraHJNbuEr4Pe98ZKXWaJ3GgDJlf/ztYXFG9t8mTBbkuDjmFJb9tn B1YA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=RtwFYKDGf1W/tp3xEFF0blS9Fjq7SLSWxBtcEH0xbEQ=; b=A9n7SMtj1x3vGOCM9sJCbHdIPMCsM1ptuVpbQ3pctx038piKvcwg3ff2Ibvd+5+FQi wMD+ZijoEDWq+YcSBRu9autrMM0nxSZoZd9wIPhiySiuTc+gVsYiqoLiI2OwiPz85ztG 2vH/EQUJFaQVAXb32ILB8rnK/5f3zRKgL2LBOPBsRSld6O5diKyk66x/2pf48xPZst5L 6hOu00MeswlmLKgbmgOwHOikRtI/eaNWDYFvwE5Cak/zXFNWCrgYE+XXz7PyYg0QB+hk imUFIb78IDnZO2cAUlXtR9x1QvF3qGyNx5EseB+tKKh0iOyjeTMhaqRXD1rU0+Ho/gd4 LoFw== X-Gm-Message-State: AOAM531BZSCGXxv2d1yNYmHJWAO+GeshbHdH8f/U9kmF+NcWqxCGel6f wJRNxI77F9LNipAOIBU7aK0= X-Google-Smtp-Source: ABdhPJyq+DUfAAxJmopAYoBJhTrBZljH8lzQZL4Z6xYi6fNEI+jA4xykE9ydzwszwSBMiCqClNdLIQ== X-Received: by 2002:a92:cf52:: with SMTP id c18mr14524652ilr.44.1597683196086; Mon, 17 Aug 2020 09:53:16 -0700 (PDT) Received: from gouda.nowheycreamery.com (c-68-32-74-190.hsd1.mi.comcast.net. [68.32.74.190]) by smtp.gmail.com with ESMTPSA id s3sm9410039iol.49.2020.08.17.09.53.15 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2020 09:53:15 -0700 (PDT) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: bfields@redhat.com, chuck.lever@oracle.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH v4 4/5] NFSD: Return both a hole and a data segment Date: Mon, 17 Aug 2020 12:53:09 -0400 Message-Id: <20200817165310.354092-5-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200817165310.354092-1-Anna.Schumaker@Netapp.com> References: <20200817165310.354092-1-Anna.Schumaker@Netapp.com> MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Anna Schumaker But only one of each right now. We'll expand on this in the next patch. Signed-off-by: Anna Schumaker --- fs/nfsd/nfs4xdr.c | 51 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 37 insertions(+), 14 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 2fa39217c256..3f4860103b25 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -4373,7 +4373,7 @@ nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr, static __be32 nfsd4_encode_read_plus_data(struct nfsd4_compoundres *resp, struct nfsd4_read *read, - unsigned long maxcount, u32 *eof) + unsigned long *maxcount, u32 *eof) { struct xdr_stream *xdr = &resp->xdr; struct file *file = read->rd_nf->nf_file; @@ -4384,19 +4384,19 @@ nfsd4_encode_read_plus_data(struct nfsd4_compoundres *resp, __be64 tmp64; if (hole_pos > read->rd_offset) - maxcount = min_t(unsigned long, maxcount, hole_pos - read->rd_offset); + *maxcount = min_t(unsigned long, *maxcount, hole_pos - read->rd_offset); /* Content type, offset, byte count */ p = xdr_reserve_space(xdr, 4 + 8 + 4); if (!p) return nfserr_resource; - read->rd_vlen = xdr_reserve_space_vec(xdr, resp->rqstp->rq_vec, maxcount); + read->rd_vlen = xdr_reserve_space_vec(xdr, resp->rqstp->rq_vec, *maxcount); if (read->rd_vlen < 0) return nfserr_resource; nfserr = nfsd_readv(resp->rqstp, read->rd_fhp, file, read->rd_offset, - resp->rqstp->rq_vec, read->rd_vlen, &maxcount, eof); + resp->rqstp->rq_vec, read->rd_vlen, maxcount, eof); if (nfserr) return nfserr; @@ -4404,7 +4404,7 @@ nfsd4_encode_read_plus_data(struct nfsd4_compoundres *resp, write_bytes_to_xdr_buf(xdr->buf, starting_len, &tmp, 4); tmp64 = cpu_to_be64(read->rd_offset); write_bytes_to_xdr_buf(xdr->buf, starting_len + 4, &tmp64, 8); - tmp = htonl(maxcount); + tmp = htonl(*maxcount); write_bytes_to_xdr_buf(xdr->buf, starting_len + 12, &tmp, 4); return nfs_ok; } @@ -4412,11 +4412,19 @@ nfsd4_encode_read_plus_data(struct nfsd4_compoundres *resp, static __be32 nfsd4_encode_read_plus_hole(struct nfsd4_compoundres *resp, struct nfsd4_read *read, - unsigned long maxcount, u32 *eof) + unsigned long *maxcount, u32 *eof) { struct file *file = read->rd_nf->nf_file; + loff_t data_pos = vfs_llseek(file, read->rd_offset, SEEK_DATA); + unsigned long count; __be32 *p; + if (data_pos == -ENXIO) + data_pos = i_size_read(file_inode(file)); + else if (data_pos <= read->rd_offset) + return nfserr_resource; + count = data_pos - read->rd_offset; + /* Content type, offset, byte count */ p = xdr_reserve_space(&resp->xdr, 4 + 8 + 8); if (!p) @@ -4424,9 +4432,10 @@ nfsd4_encode_read_plus_hole(struct nfsd4_compoundres *resp, *p++ = htonl(NFS4_CONTENT_HOLE); p = xdr_encode_hyper(p, read->rd_offset); - p = xdr_encode_hyper(p, maxcount); + p = xdr_encode_hyper(p, count); - *eof = (read->rd_offset + maxcount) >= i_size_read(file_inode(file)); + *eof = (read->rd_offset + count) >= i_size_read(file_inode(file)); + *maxcount = min_t(unsigned long, count, *maxcount); return nfs_ok; } @@ -4434,7 +4443,7 @@ static __be32 nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr, struct nfsd4_read *read) { - unsigned long maxcount; + unsigned long maxcount, count; struct xdr_stream *xdr = &resp->xdr; struct file *file; int starting_len = xdr->buf->len; @@ -4457,6 +4466,7 @@ nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr, maxcount = min_t(unsigned long, maxcount, (xdr->buf->buflen - xdr->buf->len)); maxcount = min_t(unsigned long, maxcount, read->rd_length); + count = maxcount; eof = read->rd_offset >= i_size_read(file_inode(file)); if (eof) @@ -4465,13 +4475,26 @@ nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr, pos = vfs_llseek(file, read->rd_offset, SEEK_DATA); if (pos == -ENXIO) pos = i_size_read(file_inode(file)); + else if (pos < 0) + pos = read->rd_offset; - if (pos > read->rd_offset) { - maxcount = pos - read->rd_offset; - nfserr = nfsd4_encode_read_plus_hole(resp, read, maxcount, &eof); + if (pos == read->rd_offset) { + maxcount = count; + nfserr = nfsd4_encode_read_plus_data(resp, read, &maxcount, &eof); + if (nfserr) + goto out; + count -= maxcount; + read->rd_offset += maxcount; segments++; - } else { - nfserr = nfsd4_encode_read_plus_data(resp, read, maxcount, &eof); + } + + if (count > 0 && !eof) { + maxcount = count; + nfserr = nfsd4_encode_read_plus_hole(resp, read, &maxcount, &eof); + if (nfserr) + goto out; + count -= maxcount; + read->rd_offset += maxcount; segments++; } From patchwork Mon Aug 17 16:53:10 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11718969 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id D01C115E4 for ; Mon, 17 Aug 2020 17:33:42 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id B4CB720716 for ; Mon, 17 Aug 2020 17:33:42 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="chWB8ODO" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S2389322AbgHQRdf (ORCPT ); Mon, 17 Aug 2020 13:33:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:46780 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S2389108AbgHQQxg (ORCPT ); Mon, 17 Aug 2020 12:53:36 -0400 Received: from mail-il1-x143.google.com (mail-il1-x143.google.com [IPv6:2607:f8b0:4864:20::143]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 22345C061349 for ; Mon, 17 Aug 2020 09:53:22 -0700 (PDT) Received: by mail-il1-x143.google.com with SMTP id j9so15079349ilc.11 for ; Mon, 17 Aug 2020 09:53:22 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=sender:from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=rI/zjidG9W1rkPFtshPIGzTMbEANYwyl1HV+pg9qhjc=; b=chWB8ODOzHTLg1sKy0y9+i7IPC2vBhcTo/WY5rqTUHvaMPTESlinF5GMYAWdTeO6gP AILmkf+/fLxJvWWzAGLNXQ8wnU/BNmax/tVmp2RVE0LoWNli/FxDY+QvyEy5RldOxD1M 2HuF2ms5FTUQHG+GAWLyk0KqxMLlnYG/zifxpPZfXKBmRc3u62mbwdxeFR6S2n7Fb/Hg i7iXnZwixee5YIM4ATwskIW4aXdk0uVi2KIMz+lI5i9z8EM3/57hYgV19bNBBv0KtpPu 0zv4sC50Ohe9gA/hAtUrd3Lp2paFx3pEU4fcN4GJNFAfcOTMQszgzkwOzn7NGFxEeu3U tLuQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:sender:from:to:cc:subject:date:message-id :in-reply-to:references:mime-version:content-transfer-encoding; bh=rI/zjidG9W1rkPFtshPIGzTMbEANYwyl1HV+pg9qhjc=; b=lrvvxGpyjSpkTYyWwWrFbucPuNMG/sndTbNjjuQSybjDO3FEdjC/0aReulow1TVwrC 3W1JXKO553+Dc3PX9fstmmkRaAr3Q4/sTLwM1WtvyZUMah959gAzyx45U4iOwkZehGOn Lc+oNq4zhvpiDwMWRmJH8+4SjEcpYeFxrR/E5x2iOPMuA9oNzE9weKZEW/eET7RtQxi8 0tcuQKvqRbSVgrcObmx8d92nrkIeNKQv9R2o69w33RxH5i6hS1VsDxlPyn8kdLDXcEVS icT792M3CZWXDDBoZyptNaiQW611QdImVgUUc8JZ3pE19fHlj+DiA3kSPuSe/qhLNzXr Ejiw== X-Gm-Message-State: AOAM531Z/TmXtD5nj9MfWxgLdgs/DIXH5yV7sg+mo0rf+DK5Kn1+EDYa PciBBdrCIkLa7LOYvViZUHI= X-Google-Smtp-Source: ABdhPJyX5zk6woUqJZdBmyRbEVQRc2IdRdLVvESoIvcG35IwRJdtPYEDn5832x5L4Nwar+2HuYvf5w== X-Received: by 2002:a92:9a94:: with SMTP id c20mr2504555ill.37.1597683197013; Mon, 17 Aug 2020 09:53:17 -0700 (PDT) Received: from gouda.nowheycreamery.com (c-68-32-74-190.hsd1.mi.comcast.net. [68.32.74.190]) by smtp.gmail.com with ESMTPSA id s3sm9410039iol.49.2020.08.17.09.53.16 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Aug 2020 09:53:16 -0700 (PDT) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: bfields@redhat.com, chuck.lever@oracle.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH v4 5/5] NFSD: Encode a full READ_PLUS reply Date: Mon, 17 Aug 2020 12:53:10 -0400 Message-Id: <20200817165310.354092-6-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.28.0 In-Reply-To: <20200817165310.354092-1-Anna.Schumaker@Netapp.com> References: <20200817165310.354092-1-Anna.Schumaker@Netapp.com> MIME-Version: 1.0 Sender: linux-nfs-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Anna Schumaker Reply to the client with multiple hole and data segments. I use the result of the first vfs_llseek() call for encoding as an optimization so we don't have to immediately repeat the call. Signed-off-by: Anna Schumaker --- fs/nfsd/nfs4xdr.c | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 3f4860103b25..fb71e52accee 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -4373,16 +4373,18 @@ nfsd4_encode_offload_status(struct nfsd4_compoundres *resp, __be32 nfserr, static __be32 nfsd4_encode_read_plus_data(struct nfsd4_compoundres *resp, struct nfsd4_read *read, - unsigned long *maxcount, u32 *eof) + unsigned long *maxcount, u32 *eof, + loff_t *pos) { struct xdr_stream *xdr = &resp->xdr; struct file *file = read->rd_nf->nf_file; int starting_len = xdr->buf->len; - loff_t hole_pos = vfs_llseek(file, read->rd_offset, SEEK_HOLE); + loff_t hole_pos; __be32 nfserr; __be32 *p, tmp; __be64 tmp64; + hole_pos = pos ? *pos : vfs_llseek(file, read->rd_offset, SEEK_HOLE); if (hole_pos > read->rd_offset) *maxcount = min_t(unsigned long, *maxcount, hole_pos - read->rd_offset); @@ -4449,6 +4451,7 @@ nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr, int starting_len = xdr->buf->len; int segments = 0; __be32 *p, tmp; + bool is_data; loff_t pos; u32 eof; @@ -4472,29 +4475,21 @@ nfsd4_encode_read_plus(struct nfsd4_compoundres *resp, __be32 nfserr, if (eof) goto out; - pos = vfs_llseek(file, read->rd_offset, SEEK_DATA); - if (pos == -ENXIO) - pos = i_size_read(file_inode(file)); - else if (pos < 0) - pos = read->rd_offset; + pos = vfs_llseek(file, read->rd_offset, SEEK_HOLE); + is_data = pos > read->rd_offset; - if (pos == read->rd_offset) { + while (count > 0 && !eof) { maxcount = count; - nfserr = nfsd4_encode_read_plus_data(resp, read, &maxcount, &eof); - if (nfserr) - goto out; - count -= maxcount; - read->rd_offset += maxcount; - segments++; - } - - if (count > 0 && !eof) { - maxcount = count; - nfserr = nfsd4_encode_read_plus_hole(resp, read, &maxcount, &eof); + if (is_data) + nfserr = nfsd4_encode_read_plus_data(resp, read, &maxcount, &eof, + segments == 0 ? &pos : NULL); + else + nfserr = nfsd4_encode_read_plus_hole(resp, read, &maxcount, &eof); if (nfserr) goto out; count -= maxcount; read->rd_offset += maxcount; + is_data = !is_data; segments++; }