From patchwork Mon Aug 3 16:59:49 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11698433 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 579E0138A for ; Mon, 3 Aug 2020 16:59:58 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 4079322B40 for ; Mon, 3 Aug 2020 16:59:58 +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="aRlzH1hr" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728081AbgHCQ76 (ORCPT ); Mon, 3 Aug 2020 12:59:58 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56406 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726356AbgHCQ76 (ORCPT ); Mon, 3 Aug 2020 12:59:58 -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 54049C06174A for ; Mon, 3 Aug 2020 09:59:58 -0700 (PDT) Received: by mail-il1-x143.google.com with SMTP id p13so3238600ilh.4 for ; Mon, 03 Aug 2020 09:59:58 -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=sQ5eL1nmuUmkLTUxFw+0Fbr3N0wgB3Xm8iWP31hLmAs=; b=aRlzH1hr2wHpPP58ZC5qwWvavEZv8k/Ei3Q6PFmZqRIC7CeaISNUyKy6mdzBfVyCHh LZSMt08Z5bTnGyQUWBNVYleQ0DxCX7u3DZjinq4Pa2dbZp7PITVw5RoG/EZRsauk2H1i C5zYwPhTPzrI8BhrJJgkCTGaIx9Jz4WsreCn9d2rjzWKZoBvnsci3oBcr4OtUGl57uBd TaTHvBB1GvMCwVR9uN9+FYZpk/b78unDtcvIYMg7Jo8kW7kntIqESzJcT2jR0pbOChYB MT8bODzpjBeFjupVzsEy7HwyUF5GQsc96jNDK6RGDoJcxxc11+o0opTtppior2FmFiSw mMwA== 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=sQ5eL1nmuUmkLTUxFw+0Fbr3N0wgB3Xm8iWP31hLmAs=; b=i6TBv47VN5v0nbwZqOz1DG9DvXnYyWYZhVaXIEw0GLhfBZlr3cKWGkz8fiUTrJzuaM pIu/mrcwHz8EKfYOWzFT9ANcIDqHljxilOTz9lRZFfK0aUPEFAH/7y1dMGLUxmGmJz+8 kcZde9vbeKvvOX91bwYDpf8pZBteC2cuE4Fd45mREzhdVU/OqEBkfWWR2n0u7LlLRhSS ByB5kZQgN5s0Z+Bc/ECA4woklwzPrRze86LIR4Ksy31xEjF4FBFpDTfpQLRFnrQr61ex DNNx5wBjMX/CHaDxabiULWwJPzuCX2uibREPvQ9aVFRp5x+wYjn5OKqoVF/XrYhrneYG aUHw== X-Gm-Message-State: AOAM53078QxIkIoEe+8lNslIZaDfsKnEzdtQbBLla29z3cqiCsj41zhr gOhbtnalINhnNXQsrTuVftDp1i3C X-Google-Smtp-Source: ABdhPJzi+GDc7vDlwUcKsJnP5RQmi03LcTfO2+4e/sYaBceSn/w0+qE+zgI6x3t5UdrAqeWFG/EUVQ== X-Received: by 2002:a92:d781:: with SMTP id d1mr302536iln.68.1596473997682; Mon, 03 Aug 2020 09:59:57 -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 f20sm10794639ilj.62.2020.08.03.09.59.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Aug 2020 09:59:57 -0700 (PDT) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: bfields@redhat.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH v3 1/6] SUNRPC: Implement xdr_reserve_space_vec() Date: Mon, 3 Aug 2020 12:59:49 -0400 Message-Id: <20200803165954.1348263-2-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200803165954.1348263-1-Anna.Schumaker@Netapp.com> References: <20200803165954.1348263-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 --- include/linux/sunrpc/xdr.h | 2 ++ net/sunrpc/xdr.c | 45 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+) 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 3 16:59:50 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11698435 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 2D5AF138A for ; Mon, 3 Aug 2020 17:00:00 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 152EE20A8B for ; Mon, 3 Aug 2020 17:00: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="IhsTT0uX" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728090AbgHCRAA (ORCPT ); Mon, 3 Aug 2020 13:00:00 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56412 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726356AbgHCQ77 (ORCPT ); Mon, 3 Aug 2020 12:59:59 -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 6C6F4C06174A for ; Mon, 3 Aug 2020 09:59:59 -0700 (PDT) Received: by mail-il1-x141.google.com with SMTP id p13so3238668ilh.4 for ; Mon, 03 Aug 2020 09:59:59 -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=vQ94gvLioDK0D2IFkp5BPVhxBDzICQm4Mh+Md8q/jh8=; b=IhsTT0uXXGdUmcIXWBtaIypojOx8hcTY6pkQW7kcRZOctKnIRcAJbmmEhZjI0Itm1d INRONysALepG3KQ89i1mzt4DYvqNFseYmqo2cGN0ZNSPv/cjIYvWBSjomdSmzSylPv73 3wmv9Z9LtVvOwWXlvAYLG42J4pQqspDfx2MxoKdkN1DffJCtrLyIejcUwOID2TRN1Lbi Eg0IPL5T0hd7XUTicw7kL+NX24fvtsxjTfJ4mz/BXrmFTAq2LlfJvT6V+NRna0pT7BOo TdKim6pBpOBK/uivelyRjRgT+Rtf/xN0kY4Os1Vc1WJhbLEXruV4thAu+sMItiSg4FyZ 1EoA== 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=vQ94gvLioDK0D2IFkp5BPVhxBDzICQm4Mh+Md8q/jh8=; b=fp2D5JfPSNhevcTWiyUeA6VMfLXrR04W3KyNmr50q8OaviOxTVns1immtNiujSMunI Z4PUQztTn+k9HCOOR0HR2GyA8piz+loUHE5Lw0BZIdntvS9klh5FL35Xi0CH6a8Z6TYe aWHfQcvsVC5+F5t8gAUEwOZGxKwnMoBrjLl4SuNsrdIcPP/0+bw/K0qv4+ram1fv9+rX FVLeI04lYxIuvElwIP12xogbXq+bIB9FiMWxtAaP3rFsJ5CZ7Q0hyE/o99Sw68nm34/Z rJSY7qtbj2c8k+yzaOEXZnDTbII3hDlT3qe4Rzct/YkpEV0H40ZQrOjS+QGOQqlnAnzh 6kEw== X-Gm-Message-State: AOAM531hOfl6Y1P8DkIuTp35ZSQEXq28miU5LxdyWB9l3GV9OnD7OAA9 AqY0RyHKQifvzJa1DuNuxnns3kaL X-Google-Smtp-Source: ABdhPJxjQdtgoi3r3K4m8JGZPlDO+gjAeRrVjiyPl20ZQZaSoM/xtqLuDjIgVGavSmRa9u1oL1ODUw== X-Received: by 2002:a92:5a4c:: with SMTP id o73mr317695ilb.45.1596473998833; Mon, 03 Aug 2020 09:59:58 -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 f20sm10794639ilj.62.2020.08.03.09.59.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Aug 2020 09:59:58 -0700 (PDT) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: bfields@redhat.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH v3 2/6] NFSD: nfsd4_encode_readv() can use xdr_reserve_space_vec() Date: Mon, 3 Aug 2020 12:59:50 -0400 Message-Id: <20200803165954.1348263-3-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200803165954.1348263-1-Anna.Schumaker@Netapp.com> References: <20200803165954.1348263-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 Switch over to the new code so we don't need to reproduce it on the NFSD side. Signed-off-by: Anna Schumaker --- fs/nfsd/nfs4xdr.c | 28 +++------------------------- 1 file changed, 3 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, From patchwork Mon Aug 3 16:59:51 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11698437 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 4663F138A for ; Mon, 3 Aug 2020 17:00:01 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 28DEC22B45 for ; Mon, 3 Aug 2020 17:00:01 +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="u8xyHNED" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727912AbgHCRAB (ORCPT ); Mon, 3 Aug 2020 13:00:01 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56420 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726356AbgHCRAB (ORCPT ); Mon, 3 Aug 2020 13:00:01 -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 93ADAC06174A for ; Mon, 3 Aug 2020 10:00:00 -0700 (PDT) Received: by mail-il1-x141.google.com with SMTP id y18so23268205ilp.10 for ; Mon, 03 Aug 2020 10:00:00 -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=vdApmnLAm9yzh9yNjoMR9e14CYjKiX2yoqxd0OLG69c=; b=u8xyHNEDE+d8VJ4eaiTRoFl8sNuw2fWtGb7gbKPnhQ2Y1rUY2ttmI593BmjdY6wRyI Tz3pVP5n9xtaaGFSL4GmCodHQRH/Bd664DycA/LDjLY6WkrfzOVBO7ihFBe1+0P62Iks 22Pd0owrr+nVrL1onHHuihCtIJzTO6k/1dbe/ZTB1CIJwSKl+R0xFRPNzfIiQRR7wjLd TlFuoq3Chq0LeYhzM4hMgMtLXXSREq/OBFATdEaGBcIJL1bVf4oLn9C3ceBYB7Jb17gq RFEoJ5WjuEHWbtG8uhL9SBFjyc/M5rQreiZTGymjdf3PN2I2+3afLD5+3M5mlAlXxoYE eAkA== 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=vdApmnLAm9yzh9yNjoMR9e14CYjKiX2yoqxd0OLG69c=; b=t8hWDe/jsB/to48VNY62qAWRCVz99S3Gt2QhWB8bkgmexDpjJ3x9qRk3Uuk7wf+2J3 NisJH4Rd3U0nXVfKUWj+lFlKuYbcOwOjSL0CLq5ADMSVDZYRgHLDx/A+C0bZKT/XN0Vj l1sBR+Rb8mUB9FZc2FVgpMGZYubf+EJzwjhA8nXCDbR0zZqeveuuvgWDNNLINfiMlPWu vVMzJmYZdG88mothfWKWiIBdtgcVJkTmmZ1N5n32tgMycM9eHuYrfpBQpzkw+MJQm7EB zLueUkTwwczWIF9gQo+2ggJ82D0xp+WTQFXDMwt9SpJB/0EGBS0UP0IopavMBnkVgNw6 gFgg== X-Gm-Message-State: AOAM532P1axMOAlGQEv1GSPWE/smyp1Ugi8TJxqYs/BtVYKmKHp++C1e VJZ+5kO+9lodeShdawqCvbY= X-Google-Smtp-Source: ABdhPJz3HCYsYjIP2tjfZPIKGPa8D/jMdriPKUhdnothWVU+6wOx5RC5topTvK/2sI/wP3kP2XfKGg== X-Received: by 2002:a92:cac5:: with SMTP id m5mr290959ilq.91.1596473999948; Mon, 03 Aug 2020 09:59:59 -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 f20sm10794639ilj.62.2020.08.03.09.59.58 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Aug 2020 09:59:59 -0700 (PDT) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: bfields@redhat.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH v3 3/6] NFSD: Add READ_PLUS data support Date: Mon, 3 Aug 2020 12:59:51 -0400 Message-Id: <20200803165954.1348263-4-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200803165954.1348263-1-Anna.Schumaker@Netapp.com> References: <20200803165954.1348263-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 | 85 ++++++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 100 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..1d143bf02b83 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,87 @@ 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; + if (svc_encode_read_payload(resp->rqstp, starting_len + 16, maxcount)) + return nfserr_io; + + 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 +4590,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 3 16:59:52 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11698439 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 49ABC912 for ; Mon, 3 Aug 2020 17:00:02 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 2F39C20A8B for ; Mon, 3 Aug 2020 17:00:02 +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="GYKflM59" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728097AbgHCRAC (ORCPT ); Mon, 3 Aug 2020 13:00:02 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56422 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726356AbgHCRAB (ORCPT ); Mon, 3 Aug 2020 13:00:01 -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 A4A99C06174A for ; Mon, 3 Aug 2020 10:00:01 -0700 (PDT) Received: by mail-il1-x142.google.com with SMTP id x1so11389085ilp.7 for ; Mon, 03 Aug 2020 10:00:01 -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=m/iaCHTj1bfpqh6fyIWupfy5aDZSLO5YIBrwmLa15pE=; b=GYKflM59g8ZqdngbOs/hLGmBkIU1dHDHeXrTcuSLpw/JCFqULHsECYZJC6zoO1vtgq 5Mk9GpEjEpDWBR7yZgD7aHL4KbKfAx3S4gxk2aXEcvOZmys93O8tmzlSb8257HRjIZ0j uSg2nRuYo3Njxaeqi6qabZ9GvfeuFEW2jLhY5h2TZ6mufWIDn/op8+SUaYK4mczkOP9X GI9kciUTbKfzOhDvK58Ku2TaV3kChJ7rJ4lN/yMsSth9ERYEqalsU3Fx2QxkDyJVOc+d htGfBhXRaSRVzlqoFefEFEqCFj/SRFWOAoug23kM3t910mGFyyAsQ5x+vkBRrr8GncvG w0Cw== 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=m/iaCHTj1bfpqh6fyIWupfy5aDZSLO5YIBrwmLa15pE=; b=ZyVo7aKcYmJjqwS6qZBIiYxbL2l5N3e/h/BA7Rfm8VW8ePEOgB3MEpeqGO8AFkq6gQ hLrtfIcL+y8iMR16CwDhDzjyZrUmRB3Zp+KEsj0lf7R7k7w8OVUNTGNbL3ry7jk69Yv2 ZakC0Dg9pvgEpIOHXEDknwornb0RtYmhY/hchF/HEKhW0yoPkImgt83QaFykoFYoiSMS +vetDA9ys7yRFOb/hDne5/+p7QgSo3AJbXhvgCLXpLRmPct2VKYroW/E9cDbik+Znkfw kA86GSrqs9jUMUAvWMcPQdXxeH4fY4vqgHYAJhs5XkwKhhGO1u1Dmw4+LYscQi73IQMg MrjQ== X-Gm-Message-State: AOAM531lGETsBROOn4mJO0+eHM5h6S70E8qT1N7nQDR2WWjBY2PSSkhR jTMsZnS8LJLP6tln3dl6BJ4= X-Google-Smtp-Source: ABdhPJzhiJYi14KSK7bDNHDZdGwgKwGV/QFxSsNVfn8dtj5KSvBkvhDtbeDn2m9ANW108TCeQnlFig== X-Received: by 2002:a92:858a:: with SMTP id f132mr287112ilh.225.1596474000905; Mon, 03 Aug 2020 10:00:00 -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 f20sm10794639ilj.62.2020.08.03.09.59.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Aug 2020 10:00:00 -0700 (PDT) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: bfields@redhat.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH v3 4/6] NFSD: Add READ_PLUS hole segment encoding Date: Mon, 3 Aug 2020 12:59:52 -0400 Message-Id: <20200803165954.1348263-5-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200803165954.1348263-1-Anna.Schumaker@Netapp.com> References: <20200803165954.1348263-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 1d143bf02b83..292819eafcac 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) @@ -4407,6 +4411,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) @@ -4417,6 +4442,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) @@ -4435,11 +4461,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 3 16:59:53 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11698441 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 8DDD914DD for ; Mon, 3 Aug 2020 17:00:03 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 7256122B40 for ; Mon, 3 Aug 2020 17:00:03 +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="JXX8gl2A" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1727919AbgHCRAD (ORCPT ); Mon, 3 Aug 2020 13:00:03 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56428 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726356AbgHCRAC (ORCPT ); Mon, 3 Aug 2020 13:00:02 -0400 Received: from mail-il1-x144.google.com (mail-il1-x144.google.com [IPv6:2607:f8b0:4864:20::144]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B7AF4C06174A for ; Mon, 3 Aug 2020 10:00:02 -0700 (PDT) Received: by mail-il1-x144.google.com with SMTP id j9so28312322ilc.11 for ; Mon, 03 Aug 2020 10:00:02 -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=vHsvIo6B5kn1CX5NV/inEHyATDX6IWmUUP9Oh7/wY5M=; b=JXX8gl2A+lM+P/Dw/zSq4NmmSzUhuPsf0UC3VBBYfCGeIhdGZxfJnYk6h8OJ/5NOsD bW6S5denBBuVifRx+cdbMhmG4i/GX96ZfzFGRHbyl2jzLHlyU6lr2o/YN3RjWFWyvGia XS1f2X75vv1EuLFv/neaMx/mY88BVPy2vBsQaEryFdoYfIsvzfYlDJZ564p0bY9FPmAO F0bLO8WSzFKNR+Bagcuk20LcFpr74YBXNVuh3cryY2y5WJTMEfdJbZx4wPbSYptl1qve Mbd/1ryW+aYRTEYNSFQTZBzG7HwfpMFgMZNQT/lhOJGHYHGuuI+vH6Qj/9cRdnC3c4u1 Dxpw== 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=vHsvIo6B5kn1CX5NV/inEHyATDX6IWmUUP9Oh7/wY5M=; b=koWKi+/XxK1sNUsGqr4G9YQ36Ue+3ksX+RAVdS5iiT00JgLEDBjln3IHvV6rnq/o5E gDQW11PNr/LlE0tGBu2VAJVRUkS0IIef/kWaXKOVsR0Rqzs32nMmhX76cZ/kri6cd4O5 uZJm5eAa+7x8BV7ACd8MWIUVdfWjb8//MlAs73iai3BIZ+NK9nTP00PD5TA7S1ZGSzbk QWl8YrB7Nb5rZxNlqyuO7hB5pVQGg7j3cdJp4xOTDd2+7fCAmY4wnYU+KZtrqNGcZufP GOoD1lkyvlhhPx/enIBAK1Q1a36cz9XA8n1ot1gj6zPcenLoa8cCUsmVfZmjD5jlKVI9 oldg== X-Gm-Message-State: AOAM531E9M/yykFQlXnElSHM/qz0/76+RTzcpb8zqs36CZidPWp8t+23 DAQjOt5rjI2HyvLI313p8+L1IiLR X-Google-Smtp-Source: ABdhPJyYbkJ9HkxqKTKoFodWxkXLxfdRWBqiWSRe+ikVjrAlbtvS745loDHEpc3xoh6UeajfSa9HdA== X-Received: by 2002:a92:d289:: with SMTP id p9mr350777ilp.100.1596474002065; Mon, 03 Aug 2020 10:00:02 -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 f20sm10794639ilj.62.2020.08.03.10.00.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Aug 2020 10:00:01 -0700 (PDT) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: bfields@redhat.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH v3 5/6] NFSD: Return both a hole and a data segment Date: Mon, 3 Aug 2020 12:59:53 -0400 Message-Id: <20200803165954.1348263-6-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200803165954.1348263-1-Anna.Schumaker@Netapp.com> References: <20200803165954.1348263-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 | 53 +++++++++++++++++++++++++++++++++-------------- 1 file changed, 38 insertions(+), 15 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 292819eafcac..c01bf6241c71 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,29 +4384,29 @@ 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; - if (svc_encode_read_payload(resp->rqstp, starting_len + 16, maxcount)) + if (svc_encode_read_payload(resp->rqstp, starting_len + 16, *maxcount)) return nfserr_io; 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); + tmp = htonl(*maxcount); write_bytes_to_xdr_buf(xdr->buf, starting_len + 12, &tmp, 4); return nfs_ok; } @@ -4414,11 +4414,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) @@ -4426,9 +4434,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; } @@ -4436,7 +4445,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; @@ -4459,6 +4468,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) @@ -4467,13 +4477,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 3 16:59:54 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Anna Schumaker X-Patchwork-Id: 11698443 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 86BAA138A for ; Mon, 3 Aug 2020 17:00:04 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by mail.kernel.org (Postfix) with ESMTP id 6F64F22B40 for ; Mon, 3 Aug 2020 17:00:04 +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="ea/KKgtG" Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726356AbgHCRAE (ORCPT ); Mon, 3 Aug 2020 13:00:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:56434 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728101AbgHCRAD (ORCPT ); Mon, 3 Aug 2020 13:00:03 -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 9D813C06174A for ; Mon, 3 Aug 2020 10:00:03 -0700 (PDT) Received: by mail-il1-x141.google.com with SMTP id j9so28312364ilc.11 for ; Mon, 03 Aug 2020 10:00:03 -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=Ec36spzdfrPyvBwQNxLIcliUAGfsOXwO4aIN5yaiCIo=; b=ea/KKgtGu4yKoXgcyCmuzgA7Ll10TJnguAlNHQ5Q5XpC5DYIjiR96vYucetmr/TRPt y9i2toNQo+ylt94v8HwgiXcKWuVfRP8/7kZlKodBQYxh+V7H1jkYcZMVvwzzTVMXHhEv J2dzeC9/YcZhNf11MYzHNvc4/ElhRMkPUe1+TbnVdByKVKZ/2WenFrgSmxf41NJY1p/N VyQOHPUycJTvNlbLyEMomEFGJ4faxzlX1fesmLPIvIxKHlLunj9wy5w/ybIvoD2OmlUp wEBiDekrguJwYQgKt21sradCuusQ7JR2QRDa5pRZnPXq3pwHPXHKJeTMQ2SNBTP5tSc4 hTyA== 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=Ec36spzdfrPyvBwQNxLIcliUAGfsOXwO4aIN5yaiCIo=; b=LhrpHHvurz4QNhOw8mv16sZh7tCJClx0Gtss4/YBjqdjd5oEnSfss5oP31/j/vJD/4 S9wU1htxr463DnB0MNvh00FuqpAbagweKKVEkfBWr8BVuGKCcQCr85dMOS4Yv/IYlKoD /aLaOrOVq+ZhDAM/rDpBaqG/aHiLBqJdNpp8mEQdDkAR51HmPQN8raKi5lokg2ljhFp/ 9ePQ8HJp40odIwzjOXp7MCTARO+ZB2mkToODJEUZhfBVBhuXNaOt60v4YCzciYN5nDbR DZPiB8/oK/CF6q7AyekJJdahoGKxW4GArCjvUFo1wOtoriIeensPuCcHDofW8eAtBlrr z/8A== X-Gm-Message-State: AOAM5308j4gf7RaDTx5e0jwYRX5pP0MYGnJNyMsS8tGmZ1TEXEYywVPr QKRHcI8rn3w4uYuC/pLyJTo= X-Google-Smtp-Source: ABdhPJwH92zHLg2tm6oPhV0xJcFvjnmNNkEQApTVfQvoB7HJZ2GHDk55lelFX2ZbtDorB8VDXVFuMw== X-Received: by 2002:a92:2c10:: with SMTP id t16mr334318ile.24.1596474002982; Mon, 03 Aug 2020 10:00:02 -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 f20sm10794639ilj.62.2020.08.03.10.00.02 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 03 Aug 2020 10:00:02 -0700 (PDT) From: schumaker.anna@gmail.com X-Google-Original-From: Anna.Schumaker@Netapp.com To: bfields@redhat.com, linux-nfs@vger.kernel.org Cc: Anna.Schumaker@Netapp.com Subject: [PATCH v3 6/6] NFSD: Encode a full READ_PLUS reply Date: Mon, 3 Aug 2020 12:59:54 -0400 Message-Id: <20200803165954.1348263-7-Anna.Schumaker@Netapp.com> X-Mailer: git-send-email 2.27.0 In-Reply-To: <20200803165954.1348263-1-Anna.Schumaker@Netapp.com> References: <20200803165954.1348263-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 c01bf6241c71..8e334f6da8e4 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); @@ -4451,6 +4453,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; @@ -4474,29 +4477,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++; }