From patchwork Thu May 18 17:45:36 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13247199 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 03445C77B7A for ; Thu, 18 May 2023 17:46:05 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S230122AbjERRqE (ORCPT ); Thu, 18 May 2023 13:46:04 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38150 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230093AbjERRps (ORCPT ); Thu, 18 May 2023 13:45:48 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 87AE810D9 for ; Thu, 18 May 2023 10:45:39 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id CF67165151 for ; Thu, 18 May 2023 17:45:38 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id E0043C433EF; Thu, 18 May 2023 17:45:37 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1684431938; bh=zmx31IBMhswvh8VvcwzaL8k+Mw8JRQIyOLRpM63CV0s=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=bpUIM/xb/BsQt/XZiCRQKh+aA2Ak7oGdC+WuC4RA0n3zYZ51o4CFxYeW+4sRD2yPJ YhqHTB+37Ko4FiQoVqVm1cDOO10W85NoE8OAvVcZz+Ab57CMMVZdRa3OgxBCBM7YZM SKlpu1k//XQi4AtXCnNtAkpKEqcBOMoHi3ENqrvK0IIZV+0ECj8wOC8/mbIhjCIyOv 1OcXNSRD0AIktPej8PiUe51x40iZ7ak0aEi3Vq3e2OHgdnsjogvGADQuhN21aVDqta ztwTkswQ9dSmnfBQRMV9eHvOTwfwUQINYYSlz+KdGdWfBzbSHlPfhU9FdkOx74baL9 5HToUEzWkmmmQ== Subject: [PATCH v1 1/6] NFSD: Ensure that xdr_write_pages updates rq_next_page From: Chuck Lever To: anna.schumaker@netapp.com, dhowells@redhat.com, jlayton@redhat.com Cc: Chuck Lever , linux-nfs@vger.kernel.org Date: Thu, 18 May 2023 13:45:36 -0400 Message-ID: <168443193694.516083.10348236224527959251.stgit@klimt.1015granger.net> In-Reply-To: <168443154055.516083.746756240848084451.stgit@klimt.1015granger.net> References: <168443154055.516083.746756240848084451.stgit@klimt.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever All other NFSv[23] procedures manage to keep page_ptr and rq_next_page in lock step. Signed-off-by: Chuck Lever --- fs/nfsd/nfs3xdr.c | 11 +++++++---- fs/nfsd/nfsxdr.c | 11 +++++++---- include/linux/sunrpc/svc.h | 21 +++++++++++++++++++++ 3 files changed, 35 insertions(+), 8 deletions(-) diff --git a/fs/nfsd/nfs3xdr.c b/fs/nfsd/nfs3xdr.c index 3308dd671ef0..f32128955ec8 100644 --- a/fs/nfsd/nfs3xdr.c +++ b/fs/nfsd/nfs3xdr.c @@ -828,7 +828,8 @@ nfs3svc_encode_readlinkres(struct svc_rqst *rqstp, struct xdr_stream *xdr) return false; if (xdr_stream_encode_u32(xdr, resp->len) < 0) return false; - xdr_write_pages(xdr, resp->pages, 0, resp->len); + svcxdr_encode_opaque_pages(rqstp, xdr, resp->pages, 0, + resp->len); if (svc_encode_result_payload(rqstp, head->iov_len, resp->len) < 0) return false; break; @@ -859,8 +860,9 @@ nfs3svc_encode_readres(struct svc_rqst *rqstp, struct xdr_stream *xdr) return false; if (xdr_stream_encode_u32(xdr, resp->count) < 0) return false; - xdr_write_pages(xdr, resp->pages, rqstp->rq_res.page_base, - resp->count); + svcxdr_encode_opaque_pages(rqstp, xdr, resp->pages, + rqstp->rq_res.page_base, + resp->count); if (svc_encode_result_payload(rqstp, head->iov_len, resp->count) < 0) return false; break; @@ -961,7 +963,8 @@ nfs3svc_encode_readdirres(struct svc_rqst *rqstp, struct xdr_stream *xdr) return false; if (!svcxdr_encode_cookieverf3(xdr, resp->verf)) return false; - xdr_write_pages(xdr, dirlist->pages, 0, dirlist->len); + svcxdr_encode_opaque_pages(rqstp, xdr, dirlist->pages, 0, + dirlist->len); /* no more entries */ if (xdr_stream_encode_item_absent(xdr) < 0) return false; diff --git a/fs/nfsd/nfsxdr.c b/fs/nfsd/nfsxdr.c index caf6355b18fa..5777f40c7353 100644 --- a/fs/nfsd/nfsxdr.c +++ b/fs/nfsd/nfsxdr.c @@ -468,7 +468,8 @@ nfssvc_encode_readlinkres(struct svc_rqst *rqstp, struct xdr_stream *xdr) case nfs_ok: if (xdr_stream_encode_u32(xdr, resp->len) < 0) return false; - xdr_write_pages(xdr, &resp->page, 0, resp->len); + svcxdr_encode_opaque_pages(rqstp, xdr, &resp->page, 0, + resp->len); if (svc_encode_result_payload(rqstp, head->iov_len, resp->len) < 0) return false; break; @@ -491,8 +492,9 @@ nfssvc_encode_readres(struct svc_rqst *rqstp, struct xdr_stream *xdr) return false; if (xdr_stream_encode_u32(xdr, resp->count) < 0) return false; - xdr_write_pages(xdr, resp->pages, rqstp->rq_res.page_base, - resp->count); + svcxdr_encode_opaque_pages(rqstp, xdr, resp->pages, + rqstp->rq_res.page_base, + resp->count); if (svc_encode_result_payload(rqstp, head->iov_len, resp->count) < 0) return false; break; @@ -511,7 +513,8 @@ nfssvc_encode_readdirres(struct svc_rqst *rqstp, struct xdr_stream *xdr) return false; switch (resp->status) { case nfs_ok: - xdr_write_pages(xdr, dirlist->pages, 0, dirlist->len); + svcxdr_encode_opaque_pages(rqstp, xdr, dirlist->pages, 0, + dirlist->len); /* no more entries */ if (xdr_stream_encode_item_absent(xdr) < 0) return false; diff --git a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h index 762d7231e574..3b10636c51a9 100644 --- a/include/linux/sunrpc/svc.h +++ b/include/linux/sunrpc/svc.h @@ -508,6 +508,27 @@ static inline void svcxdr_init_encode(struct svc_rqst *rqstp) xdr->rqst = NULL; } +/** + * svcxdr_encode_opaque_pages - Insert pages into an xdr_stream + * @xdr: xdr_stream to be updated + * @pages: array of pages to insert + * @base: starting offset of first data byte in @pages + * @len: number of data bytes in @pages to insert + * + * After the @pages are added, the tail iovec is instantiated pointing + * to end of the head buffer, and the stream is set up to encode + * subsequent items into the tail. + */ +static inline void svcxdr_encode_opaque_pages(struct svc_rqst *rqstp, + struct xdr_stream *xdr, + struct page **pages, + unsigned int base, + unsigned int len) +{ + xdr_write_pages(xdr, pages, base, len); + xdr->page_ptr = rqstp->rq_next_page - 1; +} + /** * svcxdr_set_auth_slack - * @rqstp: RPC transaction From patchwork Thu May 18 17:45:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13247200 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 710E4C7EE25 for ; Thu, 18 May 2023 17:46:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229498AbjERRqF (ORCPT ); Thu, 18 May 2023 13:46:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38274 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230120AbjERRpz (ORCPT ); Thu, 18 May 2023 13:45:55 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 15D8B10D7 for ; Thu, 18 May 2023 10:45:46 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 8B30A65152 for ; Thu, 18 May 2023 17:45:45 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 71B4AC433D2; Thu, 18 May 2023 17:45:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1684431945; bh=w9dAfnhhZKznEo7cq52KQd5r+P0fpvIilJBFp8XqpGs=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=o7wA40gOV0D16I2HtIzDQfWxJdpZU5w4yEm5XqWvU0xdDIHWX5zd9AB6UlotSuePJ FRm7vhRWl5ILgCTXU5yxbGNpwwmzYMo5KfJFfcPvPg7coRctuPrIlDW9R9ZDSQQ+4r a+U6sGlwZYqn2DGL0O4gxQv1pB/fFecMlUe0BpHo3AWJmEx5ZgIm1Ob26Yj+1T9KJK DEwNHcu6d9J67GYnY2+C736gFKhlLstU+M/N5OxEriui645Hix3T30GGZp+oLP/zza XNlr4joDjrZ4McIU3leBXqxwMj7bvsY1r94HVGf3vhuBwPbVOFJ7R3iKKGgmBc57tV ADVMwGwUKbtwg== Subject: [PATCH v1 2/6] NFSD: Use svcxdr_encode_opaque_pages() in nfsd4_encode_splice_read() From: Chuck Lever To: anna.schumaker@netapp.com, dhowells@redhat.com, jlayton@redhat.com Cc: Andy Zlotek , Calum Mackay , Chuck Lever , linux-nfs@vger.kernel.org Date: Thu, 18 May 2023 13:45:43 -0400 Message-ID: <168443194347.516083.17882210704288086567.stgit@klimt.1015granger.net> In-Reply-To: <168443154055.516083.746756240848084451.stgit@klimt.1015granger.net> References: <168443154055.516083.746756240848084451.stgit@klimt.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Commit 15b23ef5d348 ("nfsd4: fix corruption of NFSv4 read data") encountered exactly the same issue: after a splice read, a filesystem-owned page is left in rq_pages[]; the symptoms are the same as described there. If the computed number of pages in nfsd4_encode_splice_read() is not exactly the same as the actual number of pages that were consumed by nfsd_splice_actor() (say, because of a bug) then hilarity ensues. Instead of recomputing the page offset based on the size of the payload, use rq_next_page, which is already properly updated by nfsd_splice_actor(), to cause svc_rqst_release_pages() to operate correctly in every instance. This is a defensive change since we believe that after commit 27c934dd8832 ("nfsd: don't replace page in rq_pages if it's a continuation of last page") has been applied, there are no known opportunities for nfsd_splice_actor() to screw up. So I'm not marking it for stable backport. Reported-by: Andy Zlotek Suggested-by: Calum Mackay Signed-off-by: Chuck Lever --- fs/nfsd/nfs4xdr.c | 42 +++++++++++++++++++++--------------------- 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index c5c6873b938d..0368e0902146 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -4032,6 +4032,11 @@ nfsd4_encode_open_downgrade(struct nfsd4_compoundres *resp, __be32 nfserr, return nfsd4_encode_stateid(xdr, &od->od_stateid); } +/* + * The operation of this function assumes that this is the only + * READ operation in the COMPOUND. If there are multiple READs, + * we use nfsd4_encode_readv(). + */ static __be32 nfsd4_encode_splice_read( struct nfsd4_compoundres *resp, struct nfsd4_read *read, @@ -4042,8 +4047,12 @@ static __be32 nfsd4_encode_splice_read( int status, space_left; __be32 nfserr; - /* Make sure there will be room for padding if needed */ - if (xdr->end - xdr->p < 1) + /* + * Make sure there is room at the end of buf->head for + * svcxdr_encode_opaque_pages() to create a tail buffer + * to XDR-pad the payload. + */ + if (xdr->iov != xdr->buf->head || xdr->end - xdr->p < 1) return nfserr_resource; nfserr = nfsd_splice_read(read->rd_rqstp, read->rd_fhp, @@ -4059,31 +4068,22 @@ static __be32 nfsd4_encode_splice_read( goto out_err; } - buf->page_len = maxcount; - buf->len += maxcount; - xdr->page_ptr += (buf->page_base + maxcount + PAGE_SIZE - 1) - / PAGE_SIZE; - - /* Use rest of head for padding and remaining ops: */ - buf->tail[0].iov_base = xdr->p; - buf->tail[0].iov_len = 0; - xdr->iov = buf->tail; - if (maxcount&3) { - int pad = 4 - (maxcount&3); - - *(xdr->p++) = 0; - - buf->tail[0].iov_base += maxcount&3; - buf->tail[0].iov_len = pad; - buf->len += pad; - } + svcxdr_encode_opaque_pages(read->rd_rqstp, xdr, buf->pages, 0, + maxcount); + /* + * Prepare to encode subsequent operations. + * + * xdr_truncate_encode() is not safe to use after a successful + * splice read has been done, so the following stream + * manipulations are open-coded. + */ space_left = min_t(int, (void *)xdr->end - (void *)xdr->p, buf->buflen - buf->len); buf->buflen = buf->len + space_left; xdr->end = (__be32 *)((void *)xdr->end + space_left); - return 0; + return nfs_ok; out_err: /* From patchwork Thu May 18 17:45:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13247201 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id DE403C7EE23 for ; Thu, 18 May 2023 17:46:06 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229726AbjERRqG (ORCPT ); Thu, 18 May 2023 13:46:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38358 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230142AbjERRqA (ORCPT ); Thu, 18 May 2023 13:46:00 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 80DCF10EF for ; Thu, 18 May 2023 10:45:52 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 06CAA65151 for ; Thu, 18 May 2023 17:45:52 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 176EDC433EF; Thu, 18 May 2023 17:45:51 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1684431951; bh=NVWxOt6L9hNhW548s723r+uCh1QTojidjmChOQNlhwo=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=qLct4iaZlIVvdaoySmz1z1N32dqEX5nHoRH4gLJXkG1/zkKOq+sOja5cg3xyqvFFo PBmySo7CwPFxSIM8r636HeOb5cIPeOukecgRqPVRJzCSE7h/AEvjbISWXin8c8cQIp yAIqiVId5Uw7lsvq3aJ70YKz6fErAwYp3AM7kCyh1iTRwWBCxb0XUcU6MRRSbPk/vq e9uIUpjw5mTJnWE6vo0nU6MEDaAGitYSExdhN9Hd9KW8LoZQmgFId79Y3BLE8p1tNs UBvZ4TdWQz0Wrc+/Q9l3iF+msNlrsQVijd/ici8a4iK4QapDwIYZoeP0wVIoxHA+rg JuuWqc2fItXgw== Subject: [PATCH v1 3/6] NFSD: Update rq_next_page between COMPOUND operations From: Chuck Lever To: anna.schumaker@netapp.com, dhowells@redhat.com, jlayton@redhat.com Cc: Chuck Lever , linux-nfs@vger.kernel.org Date: Thu, 18 May 2023 13:45:50 -0400 Message-ID: <168443195015.516083.14011811574141137830.stgit@klimt.1015granger.net> In-Reply-To: <168443154055.516083.746756240848084451.stgit@klimt.1015granger.net> References: <168443154055.516083.746756240848084451.stgit@klimt.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever A GETATTR with a large result can advance xdr->page_ptr without updating rq_next_page. If a splice READ follows that GETATTR in the COMPOUND, nfsd_splice_actor can start splicing at the wrong page. I've also seen READLINK and READDIR leave rq_next_page in an unmodified state. There are potentially a myriad of combinations like this, so play it safe: move the rq_next_page update to nfsd4_encode_operation. Signed-off-by: Chuck Lever --- fs/nfsd/nfs4xdr.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 0368e0902146..23dd09c4b2cd 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -5439,6 +5439,12 @@ nfsd4_encode_operation(struct nfsd4_compoundres *resp, struct nfsd4_op *op) release: if (opdesc && opdesc->op_release) opdesc->op_release(&op->u); + + /* + * Account for pages consumed while encoding this operation. + * The xdr_stream primitives don't manage rq_next_page. + */ + rqstp->rq_next_page = xdr->page_ptr + 1; } /* @@ -5507,9 +5513,6 @@ nfs4svc_encode_compoundres(struct svc_rqst *rqstp, struct xdr_stream *xdr) p = resp->statusp; *p++ = resp->cstate.status; - - rqstp->rq_next_page = xdr->page_ptr + 1; - *p++ = htonl(resp->taglen); memcpy(p, resp->tag, resp->taglen); p += XDR_QUADLEN(resp->taglen); From patchwork Thu May 18 17:45:56 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13247202 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B4FA5C77B7A for ; Thu, 18 May 2023 17:46:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229520AbjERRqJ (ORCPT ); Thu, 18 May 2023 13:46:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38394 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S229820AbjERRqG (ORCPT ); Thu, 18 May 2023 13:46:06 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id EB24FE61 for ; Thu, 18 May 2023 10:45:58 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 80B0665152 for ; Thu, 18 May 2023 17:45:58 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 8C55EC433D2; Thu, 18 May 2023 17:45:57 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1684431957; bh=YGp7ohilP2ZwBHsR3MUlES5YLo6UxMmn4o5e8mCRsiU=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=hkf7mfXLjMzEXq16Okx5SzTjULIZzmByLW+YM2mZ5hc2oXSAO64yeOZz+iR8CdVna LWc3vc6aSxN2btkt0ckVWOukOTYxa6EE+w59WANIap4jEdm5v2S6k31/yfk72eNTjj 1gUh9fVMyoPvkWOT9FgTpa0quvDtb0UUQxh0jjjkJrszAOPWtObkSxLKxPerwSrLD1 3YpLb49krHDuBJTlSZor+HJhRf1EiBbdJTW1pQPsP46vaCiJcH34Zd8AiYOa0h3O3K jQagroSjkRg56wWGVcCHo6RttMOuQYELiHRzklNSrvHY1Y5dtzwYJFSVlzLIDCXxN4 u40n7LITZyyqQ== Subject: [PATCH v1 4/6] NFSD: Hoist rq_vec preparation into nfsd_read() From: Chuck Lever To: anna.schumaker@netapp.com, dhowells@redhat.com, jlayton@redhat.com Cc: Chuck Lever , linux-nfs@vger.kernel.org Date: Thu, 18 May 2023 13:45:56 -0400 Message-ID: <168443195664.516083.12106288760156437793.stgit@klimt.1015granger.net> In-Reply-To: <168443154055.516083.746756240848084451.stgit@klimt.1015granger.net> References: <168443154055.516083.746756240848084451.stgit@klimt.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Accrue the following benefits: a) Deduplicate this common bit of code. b) Don't prepare rq_vec for NFSv2 and NFSv3 spliced reads, which don't use rq_vec. This is already the case for nfsd4_encode_read(). c) Eventually, converting NFSD's read path to use a bvec iterator will be simpler. In the next patch, nfsd_iter_read() will replace nfsd_readv() for all NFS versions. Signed-off-by: Chuck Lever --- fs/nfsd/nfs3proc.c | 14 +---------- fs/nfsd/nfsproc.c | 14 +---------- fs/nfsd/vfs.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++------ fs/nfsd/vfs.h | 8 +++++- 4 files changed, 68 insertions(+), 36 deletions(-) diff --git a/fs/nfsd/nfs3proc.c b/fs/nfsd/nfs3proc.c index e6bb8eeb5bc2..fc8d5b7db9f8 100644 --- a/fs/nfsd/nfs3proc.c +++ b/fs/nfsd/nfs3proc.c @@ -151,8 +151,6 @@ nfsd3_proc_read(struct svc_rqst *rqstp) { struct nfsd3_readargs *argp = rqstp->rq_argp; struct nfsd3_readres *resp = rqstp->rq_resp; - unsigned int len; - int v; dprintk("nfsd: READ(3) %s %lu bytes at %Lu\n", SVCFH_fmt(&argp->fh), @@ -166,17 +164,7 @@ nfsd3_proc_read(struct svc_rqst *rqstp) if (argp->offset + argp->count > (u64)OFFSET_MAX) argp->count = (u64)OFFSET_MAX - argp->offset; - v = 0; - len = argp->count; resp->pages = rqstp->rq_next_page; - while (len > 0) { - struct page *page = *(rqstp->rq_next_page++); - - rqstp->rq_vec[v].iov_base = page_address(page); - rqstp->rq_vec[v].iov_len = min_t(unsigned int, len, PAGE_SIZE); - len -= rqstp->rq_vec[v].iov_len; - v++; - } /* Obtain buffer pointer for payload. * 1 (status) + 22 (post_op_attr) + 1 (count) + 1 (eof) @@ -187,7 +175,7 @@ nfsd3_proc_read(struct svc_rqst *rqstp) fh_copy(&resp->fh, &argp->fh); resp->status = nfsd_read(rqstp, &resp->fh, argp->offset, - rqstp->rq_vec, v, &resp->count, &resp->eof); + &resp->count, &resp->eof); return rpc_success; } diff --git a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c index c37195572fd0..a7315928a760 100644 --- a/fs/nfsd/nfsproc.c +++ b/fs/nfsd/nfsproc.c @@ -176,9 +176,7 @@ nfsd_proc_read(struct svc_rqst *rqstp) { struct nfsd_readargs *argp = rqstp->rq_argp; struct nfsd_readres *resp = rqstp->rq_resp; - unsigned int len; u32 eof; - int v; dprintk("nfsd: READ %s %d bytes at %d\n", SVCFH_fmt(&argp->fh), @@ -187,17 +185,7 @@ nfsd_proc_read(struct svc_rqst *rqstp) argp->count = min_t(u32, argp->count, NFSSVC_MAXBLKSIZE_V2); argp->count = min_t(u32, argp->count, rqstp->rq_res.buflen); - v = 0; - len = argp->count; resp->pages = rqstp->rq_next_page; - while (len > 0) { - struct page *page = *(rqstp->rq_next_page++); - - rqstp->rq_vec[v].iov_base = page_address(page); - rqstp->rq_vec[v].iov_len = min_t(unsigned int, len, PAGE_SIZE); - len -= rqstp->rq_vec[v].iov_len; - v++; - } /* Obtain buffer pointer for payload. 19 is 1 word for * status, 17 words for fattr, and 1 word for the byte count. @@ -207,7 +195,7 @@ nfsd_proc_read(struct svc_rqst *rqstp) resp->count = argp->count; fh_copy(&resp->fh, &argp->fh); resp->status = nfsd_read(rqstp, &resp->fh, argp->offset, - rqstp->rq_vec, v, &resp->count, &eof); + &resp->count, &eof); if (resp->status == nfs_ok) resp->status = fh_getattr(&resp->fh, &resp->stat); else if (resp->status == nfserr_jukebox) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index c4ef24c5ffd0..054d58d01299 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1028,6 +1028,50 @@ __be32 nfsd_readv(struct svc_rqst *rqstp, struct svc_fh *fhp, return nfsd_finish_read(rqstp, fhp, file, offset, count, eof, host_err); } +/** + * nfsd_iter_read - Perform a VFS read using an iterator + * @rqstp: RPC transaction context + * @fhp: file handle of file to be read + * @file: opened struct file of file to be read + * @offset: starting byte offset + * @count: IN: requested number of bytes; OUT: number of bytes read + * @base: offset in first page of read buffer + * @eof: OUT: set non-zero if operation reached the end of the file + * + * Some filesystems or situations cannot use nfsd_splice_read. This + * function is the slightly less-performant fallback for those cases. + * + * Returns nfs_ok on success, otherwise an nfserr stat value is + * returned. + */ +__be32 nfsd_iter_read(struct svc_rqst *rqstp, struct svc_fh *fhp, + struct file *file, loff_t offset, unsigned long *count, + unsigned int base, u32 *eof) +{ + unsigned long v, total; + struct iov_iter iter; + loff_t ppos = offset; + struct page *page; + ssize_t host_err; + + v = 0; + total = *count; + while (total) { + page = *(rqstp->rq_next_page++); + rqstp->rq_vec[v].iov_base = page_address(page) + base; + rqstp->rq_vec[v].iov_len = min_t(size_t, total, PAGE_SIZE - base); + total -= rqstp->rq_vec[v].iov_len; + ++v; + base = 0; + } + WARN_ON_ONCE(v > ARRAY_SIZE(rqstp->rq_vec)); + + trace_nfsd_read_vector(rqstp, fhp, offset, *count); + iov_iter_kvec(&iter, ITER_DEST, rqstp->rq_vec, v, *count); + host_err = vfs_iter_read(file, &iter, &ppos, 0); + return nfsd_finish_read(rqstp, fhp, file, offset, count, eof, host_err); +} + /* * Gathered writes: If another process is currently writing to the file, * there's a high chance this is another nfsd (triggered by a bulk write @@ -1153,14 +1197,24 @@ nfsd_vfs_write(struct svc_rqst *rqstp, struct svc_fh *fhp, struct nfsd_file *nf, return nfserr; } -/* - * Read data from a file. count must contain the requested read count - * on entry. On return, *count contains the number of bytes actually read. +/** + * nfsd_read - Read data from a file + * @rqstp: RPC transaction context + * @fhp: file handle of file to be read + * @offset: starting byte offset + * @count: IN: requested number of bytes; OUT: number of bytes read + * @eof: OUT: set non-zero if operation reached the end of the file + * + * The caller must verify that there is enough space in @rqstp.rq_res + * to perform this operation. + * * N.B. After this call fhp needs an fh_put + * + * Returns nfs_ok on success, otherwise an nfserr stat value is + * returned. */ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, - loff_t offset, struct kvec *vec, int vlen, unsigned long *count, - u32 *eof) + loff_t offset, unsigned long *count, u32 *eof) { struct nfsd_file *nf; struct file *file; @@ -1175,12 +1229,10 @@ __be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, if (file->f_op->splice_read && test_bit(RQ_SPLICE_OK, &rqstp->rq_flags)) err = nfsd_splice_read(rqstp, fhp, file, offset, count, eof); else - err = nfsd_readv(rqstp, fhp, file, offset, vec, vlen, count, eof); + err = nfsd_iter_read(rqstp, fhp, file, offset, count, 0, eof); nfsd_file_put(nf); - trace_nfsd_read_done(rqstp, fhp, offset, *count); - return err; } diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index 43fb57a301d3..6381a2890b0b 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -115,8 +115,12 @@ __be32 nfsd_readv(struct svc_rqst *rqstp, struct svc_fh *fhp, struct kvec *vec, int vlen, unsigned long *count, u32 *eof); -__be32 nfsd_read(struct svc_rqst *, struct svc_fh *, - loff_t, struct kvec *, int, unsigned long *, +__be32 nfsd_iter_read(struct svc_rqst *rqstp, struct svc_fh *fhp, + struct file *file, loff_t offset, + unsigned long *count, unsigned int base, + u32 *eof); +__be32 nfsd_read(struct svc_rqst *rqstp, struct svc_fh *fhp, + loff_t offset, unsigned long *count, u32 *eof); __be32 nfsd_write(struct svc_rqst *, struct svc_fh *, loff_t, struct kvec *, int, unsigned long *, From patchwork Thu May 18 17:46:03 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13247203 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B6112C7EE23 for ; Thu, 18 May 2023 17:46:35 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229820AbjERRqM (ORCPT ); Thu, 18 May 2023 13:46:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38396 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230094AbjERRqJ (ORCPT ); Thu, 18 May 2023 13:46:09 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A6C6510E7 for ; Thu, 18 May 2023 10:46:05 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 0555A65172 for ; Thu, 18 May 2023 17:46:05 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 0D2A2C4339B; Thu, 18 May 2023 17:46:03 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1684431964; bh=5cq3hHSmmvzznWlj+O2y3SpqOlSMPmQc3draLNBzshI=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=BvcizT4eLLf858C8I2a9Yb9zyoz3PQ5d3MFwZknw3owzzmNsAiYU557RGsgej24ZE sf2P4VGg9AgaP3DS4pZASQcmH/u2Hfnj4q0NEoDhbz2cXVqrAbSOwSpTgyXHHYdVrf uWiEKvwpeGkeyfPP42x5C7DWzYxKVJAjkicCbU6WByaa9fF9CR76xZVmnKPeWAhjAW +Ownk4wx8c7x5S4C1QtXE681ZRqE5h+0A5leNIIVnWVfW02Co11PC47VGw4TEXhj7d w6jQedWl970LTl8Fsq+OX+PW8dXlbnSBH8WQArj2U2eeYGVgsqT9HEMqUxyfTyLkNc xm8GOu3NfAQuw== Subject: [PATCH v1 5/6] NFSD: Hoist rq_vec preparation into nfsd_read() [step two] From: Chuck Lever To: anna.schumaker@netapp.com, dhowells@redhat.com, jlayton@redhat.com Cc: Chuck Lever , linux-nfs@vger.kernel.org Date: Thu, 18 May 2023 13:46:03 -0400 Message-ID: <168443196312.516083.6031724443786862273.stgit@klimt.1015granger.net> In-Reply-To: <168443154055.516083.746756240848084451.stgit@klimt.1015granger.net> References: <168443154055.516083.746756240848084451.stgit@klimt.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever Now that the preparation of an rq_vec has been removed from the generic read path, nfsd_splice_read() no longer needs to reset rq_next_page. nfsd4_encode_read() calls nfsd_splice_read() directly. As far as I can ascertain, resetting rq_next_page for NFSv4 splice reads is unnecessary because rq_next_page is already set correctly. Moreover, resetting it might even be incorrect if previous operations in the COMPOUND have already consumed at least a page of the send buffer. I would expect that the result would be encoding the READ payload over previously-encoded results. Signed-off-by: Chuck Lever --- fs/nfsd/nfs4xdr.c | 10 +++++----- fs/nfsd/vfs.c | 13 ++++++++++++- include/linux/sunrpc/xdr.h | 3 +-- net/sunrpc/xdr.c | 26 ++++++++++++-------------- 4 files changed, 30 insertions(+), 22 deletions(-) diff --git a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c index 23dd09c4b2cd..b83954fc57e3 100644 --- a/fs/nfsd/nfs4xdr.c +++ b/fs/nfsd/nfs4xdr.c @@ -4104,13 +4104,13 @@ static __be32 nfsd4_encode_readv(struct nfsd4_compoundres *resp, __be32 zero = xdr_zero; __be32 nfserr; - read->rd_vlen = xdr_reserve_space_vec(xdr, resp->rqstp->rq_vec, maxcount); - if (read->rd_vlen < 0) + if (xdr_reserve_space_vec(xdr, maxcount) < 0) return nfserr_resource; - nfserr = nfsd_readv(resp->rqstp, read->rd_fhp, file, read->rd_offset, - resp->rqstp->rq_vec, read->rd_vlen, &maxcount, - &read->rd_eof); + nfserr = nfsd_iter_read(resp->rqstp, read->rd_fhp, file, + read->rd_offset, &maxcount, + xdr->buf->page_len & ~PAGE_MASK, + &read->rd_eof); read->rd_length = maxcount; if (nfserr) return nfserr; diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 054d58d01299..13ccd385b308 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -995,6 +995,18 @@ static __be32 nfsd_finish_read(struct svc_rqst *rqstp, struct svc_fh *fhp, } } +/** + * nfsd_splice_read - Perform a VFS read using a splice pipe + * @rqstp: RPC transaction context + * @fhp: file handle of file to be read + * @file: opened struct file of file to be read + * @offset: starting byte offset + * @count: IN: requested number of bytes; OUT: number of bytes read + * @eof: OUT: set non-zero if operation reached the end of the file + * + * Returns nfs_ok on success, otherwise an nfserr stat value is + * returned. + */ __be32 nfsd_splice_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, loff_t offset, unsigned long *count, u32 *eof) @@ -1008,7 +1020,6 @@ __be32 nfsd_splice_read(struct svc_rqst *rqstp, struct svc_fh *fhp, ssize_t host_err; trace_nfsd_read_splice(rqstp, fhp, offset, *count); - rqstp->rq_next_page = rqstp->rq_respages + 1; host_err = splice_direct_to_actor(file, &sd, nfsd_direct_splice_actor); return nfsd_finish_read(rqstp, fhp, file, offset, count, eof, host_err); } diff --git a/include/linux/sunrpc/xdr.h b/include/linux/sunrpc/xdr.h index 72014c9216fc..f89ec4b5ea16 100644 --- a/include/linux/sunrpc/xdr.h +++ b/include/linux/sunrpc/xdr.h @@ -242,8 +242,7 @@ extern void xdr_init_encode(struct xdr_stream *xdr, struct xdr_buf *buf, extern void xdr_init_encode_pages(struct xdr_stream *xdr, struct xdr_buf *buf, struct page **pages, 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 int xdr_reserve_space_vec(struct xdr_stream *xdr, 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 void xdr_truncate_decode(struct xdr_stream *xdr, size_t len); diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c index 36835b2f5446..2a22e78af116 100644 --- a/net/sunrpc/xdr.c +++ b/net/sunrpc/xdr.c @@ -1070,22 +1070,22 @@ __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. + * 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. + * + * Return values: + * %0: success + * %-EMSGSIZE: not enough space is available in @xdr */ -int xdr_reserve_space_vec(struct xdr_stream *xdr, struct kvec *vec, size_t nbytes) +int xdr_reserve_space_vec(struct xdr_stream *xdr, size_t nbytes) { - int thislen; - int v = 0; + size_t thislen; __be32 *p; /* @@ -1097,21 +1097,19 @@ int xdr_reserve_space_vec(struct xdr_stream *xdr, struct kvec *vec, size_t nbyte xdr->end = xdr->p; } + /* XXX: Let's find a way to make this more efficient */ 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; + return -EMSGSIZE; - vec[v].iov_base = p; - vec[v].iov_len = thislen; - v++; nbytes -= thislen; } - return v; + return 0; } EXPORT_SYMBOL_GPL(xdr_reserve_space_vec); From patchwork Thu May 18 17:46:09 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13247204 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D447EC7EE25 for ; Thu, 18 May 2023 17:46:37 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S229456AbjERRqg (ORCPT ); Thu, 18 May 2023 13:46:36 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38472 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S230097AbjERRqQ (ORCPT ); Thu, 18 May 2023 13:46:16 -0400 Received: from dfw.source.kernel.org (dfw.source.kernel.org [IPv6:2604:1380:4641:c500::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 6C4AE10D9 for ; Thu, 18 May 2023 10:46:12 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 6F03065159 for ; Thu, 18 May 2023 17:46:11 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 80E3EC433D2; Thu, 18 May 2023 17:46:10 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1684431970; bh=+UOLD0NJ5wRDTmjdvrWiiMCQm1uRuyCjI8JQo6Kni1I=; h=Subject:From:To:Cc:Date:In-Reply-To:References:From; b=iPVoAqPaGnKZJha4KLuY1cAuizayiDdrZzEa6fMpp1HgsfS+HYmYCy3Va5u6NLJQs 2+OAuNY4T8qDqReAus7epa21MUT6qeAu2KqzKIwxZyafJw/A3q8UJ9c6015Uc6KG60 yK1pp14OUYpU6eEQlYJtOmaosrcmyl6RV6e7BtoHBncTr27K5vqxWiox7IGTEX913e kyC7aTl/yw2yWL5uHIP/pR9gXJuWsEMCdKgD2w9BZ7nK8HMNScfjOTWeNUTJxcjXlJ y3L0c5fDT82kqKZPQEifZZDA7TTeoX/Fnb+uP47FTk/1qbxLAXqKw6I423ZQcmS7VF IqFv6S0X1Ee9Q== Subject: [PATCH v1 6/6] NFSD: Remove nfsd_readv() From: Chuck Lever To: anna.schumaker@netapp.com, dhowells@redhat.com, jlayton@redhat.com Cc: Chuck Lever , linux-nfs@vger.kernel.org Date: Thu, 18 May 2023 13:46:09 -0400 Message-ID: <168443196963.516083.11442184693179163969.stgit@klimt.1015granger.net> In-Reply-To: <168443154055.516083.746756240848084451.stgit@klimt.1015granger.net> References: <168443154055.516083.746756240848084451.stgit@klimt.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: Chuck Lever nfsd_readv()'s consumers now use nfsd_iter_read(). Signed-off-by: Chuck Lever --- fs/nfsd/vfs.c | 15 --------------- fs/nfsd/vfs.h | 5 ----- 2 files changed, 20 deletions(-) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 13ccd385b308..1053c81f82f1 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -1024,21 +1024,6 @@ __be32 nfsd_splice_read(struct svc_rqst *rqstp, struct svc_fh *fhp, return nfsd_finish_read(rqstp, fhp, file, offset, count, eof, host_err); } -__be32 nfsd_readv(struct svc_rqst *rqstp, struct svc_fh *fhp, - struct file *file, loff_t offset, - struct kvec *vec, int vlen, unsigned long *count, - u32 *eof) -{ - struct iov_iter iter; - loff_t ppos = offset; - ssize_t host_err; - - trace_nfsd_read_vector(rqstp, fhp, offset, *count); - iov_iter_kvec(&iter, ITER_DEST, vec, vlen, *count); - host_err = vfs_iter_read(file, &iter, &ppos, 0); - return nfsd_finish_read(rqstp, fhp, file, offset, count, eof, host_err); -} - /** * nfsd_iter_read - Perform a VFS read using an iterator * @rqstp: RPC transaction context diff --git a/fs/nfsd/vfs.h b/fs/nfsd/vfs.h index 6381a2890b0b..a6890ea7b765 100644 --- a/fs/nfsd/vfs.h +++ b/fs/nfsd/vfs.h @@ -110,11 +110,6 @@ __be32 nfsd_splice_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, loff_t offset, unsigned long *count, u32 *eof); -__be32 nfsd_readv(struct svc_rqst *rqstp, struct svc_fh *fhp, - struct file *file, loff_t offset, - struct kvec *vec, int vlen, - unsigned long *count, - u32 *eof); __be32 nfsd_iter_read(struct svc_rqst *rqstp, struct svc_fh *fhp, struct file *file, loff_t offset, unsigned long *count, unsigned int base,