Received: by 2002:a05:6358:c692:b0:131:369:b2a3 with SMTP id fe18csp1209815rwb; Fri, 28 Jul 2023 06:25:37 -0700 (PDT) X-Google-Smtp-Source: APBJJlGFpVKZqmO5SvbbpPD2S5tlrNfPpAGDs5PFpM+8KeviQ4Qw3MIAEixZqzq2EYn+6bNek7VI X-Received: by 2002:a05:6a20:2583:b0:132:f61e:7d41 with SMTP id k3-20020a056a20258300b00132f61e7d41mr2413834pzd.5.1690550737364; Fri, 28 Jul 2023 06:25:37 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690550737; cv=none; d=google.com; s=arc-20160816; b=SFLKeHGZmxurR3meuOawXFYW6TaKMy4t/Ci6zNFPJ2HDUGKIN4eTBgG014SmJNsxXg igVsY7rpQ1g3TLRAt2QHWxnYXi8GxLPQxzFAd+ZiQNHa5M1vlY5B63diGAE0Alpo7X8o 6a1PiZOVUl5A26H0ByzrmH9G66kzn/t7lR9tQRglbPA9+y9P8ZpSl/FNyi6EWB43m3fI eBM0OnNESp5W58hPP/LOEPsiXZ3F7/kim10kF84pWMt8wwh83ILazalsRQkVrOiBiz9v qm/SuMOu/6Dg/ljn/Csv/oOdBvoNdwac8yH90998hsueXvG7RkRtxklbc5VldJ7lNro3 7kBw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:to:content-transfer-encoding:mime-version :user-agent:message-id:date:cc:from:subject:dkim-signature; bh=C7b/ZTvfzcyQbc4EQKvATdchhtGp9PSC8zyjgFgnAu8=; fh=Stx+fpb1DfeZlPtjWurY/DUlLNs+5gg/OnbtaVdRthY=; b=wMNVdbXLdh9pAzgfObROD69C2caxIImTME+vF8UEnrridbThr1ihCpdCvRP5NYwitT 1f27TaLtmRC3B2/Lz/OfzQOfsPKBeet9tlGVzhDJpdt5ttLTQDqZHB2Z1pv1uPewFbTS CMzVbo66Svdb+1j8s3M66RStrf+VBA9tSwp2rGgBqbpMa/P3ev3AV5h3iI9cVoTABdwG z9VfO91o9yhcwtwhUOaywKK2A+6GWu03dghHogsHv+bdzfvRvcbE4bgE8Rg/+Yq/VO6d RIuljx4fCHVFFqbXFBrTuwNpe1bJ4eQ/DBW/auCm0Hp49mamYvuQ/f7yuW4uQItY3LCA QwVA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=P3WiCF1U; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id i25-20020a635859000000b005633492e104si3109992pgm.497.2023.07.28.06.25.21; Fri, 28 Jul 2023 06:25:37 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=P3WiCF1U; spf=pass (google.com: domain of linux-nfs-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-nfs-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235367AbjG1Mck (ORCPT + 99 others); Fri, 28 Jul 2023 08:32:40 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:48702 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234023AbjG1Mcj (ORCPT ); Fri, 28 Jul 2023 08:32:39 -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 6F26410FC; Fri, 28 Jul 2023 05:32:38 -0700 (PDT) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by dfw.source.kernel.org (Postfix) with ESMTPS id 000FC6211C; Fri, 28 Jul 2023 12:32:37 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id BA8C1C433C8; Fri, 28 Jul 2023 12:32:36 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1690547557; bh=5+IB+ctY7aSwJzgoHEiHuMClfV6yZJmKN9IgrfrAyvQ=; h=Subject:From:Cc:Date:From; b=P3WiCF1UYQWWIAnOTPxtAyCawIacJu2MOEAFrnl1+2E+hKa6G4LjFOVGnWg7MImqK 6FIMvXgzND14/EyoTerASk2ymrcjMAXQbagk2jYRVMkrpUVy9OkXVNKOztvx/NY/29 GqqN20SZl4m5ly2CnUqm162H+TNKcf4cj6eBRiKtOdQnUjQGolwKG2xyDOPCevjWhs ZYgh73uCB0n1/OW9soeoq2rYOSRAyESzTpnJZMPajQdjQgO31dgu7nGCJWZgiO2nsq LLKGU5uD8lBNGGB/EiM07/m57Tr/XA6b+0BVjqzXk41HsEd/rUnLbXdPa4m3hjZkP6 nRElSuklB2zSw== Subject: [PATCH] nfsd: Fix reading via splice From: Chuck Lever Cc: Chuck Lever , David Howells , Jeff Layton , Hugh Dickins , Jens Axboe , Matthew Wilcox , linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, Chuck Lever , hughd@google.com, axboe@kernel.dk, willy@infradead.org, linux-nfs@vger.kernel.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org Date: Fri, 28 Jul 2023 08:32:35 -0400 Message-ID: <169054754615.3783.11682801287165281930.stgit@klimt.1015granger.net> User-Agent: StGit/1.5 MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit X-Spam-Status: No, score=-3.4 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,MISSING_HEADERS, RCVD_IN_DNSWL_MED,SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net To: unlisted-recipients:; (no To-header on input) Precedence: bulk List-ID: X-Mailing-List: linux-nfs@vger.kernel.org From: David Howells nfsd_splice_actor() has a clause in its loop that chops up a compound page into individual pages such that if the same page is seen twice in a row, it is discarded the second time. This is a problem with the advent of shmem_splice_read() as that inserts zero_pages into the pipe in lieu of pages that aren't present in the pagecache. Fix this by assuming that the last page is being extended only if the currently stored length + starting offset is not currently on a page boundary. This can be tested by NFS-exporting a tmpfs filesystem on the test machine and truncating it to more than a page in size (eg. truncate -s 8192) and then reading it by NFS. The first page will be all zeros, but thereafter garbage will be read. Note: I wonder if we can ever get a situation now where we get a splice that gives us contiguous parts of a page in separate actor calls. As NFSD can only be splicing from a file (I think), there are only three sources of the page: copy_splice_read(), shmem_splice_read() and file_splice_read(). The first allocates pages for the data it reads, so the problem cannot occur; the second should never see a partial page; and the third waits for each page to become available before we're allowed to read from it. Fixes: bd194b187115 ("shmem: Implement splice-read") Reported-by: Chuck Lever Signed-off-by: David Howells Reviewed-by: Jeff Layton cc: Hugh Dickins cc: Jens Axboe cc: Matthew Wilcox cc: linux-nfs@vger.kernel.org cc: linux-fsdevel@vger.kernel.org cc: linux-mm@kvack.org Signed-off-by: Chuck Lever --- fs/nfsd/vfs.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c index 59b7d60ae33e..ee3bbaa79478 100644 --- a/fs/nfsd/vfs.c +++ b/fs/nfsd/vfs.c @@ -956,10 +956,13 @@ nfsd_splice_actor(struct pipe_inode_info *pipe, struct pipe_buffer *buf, last_page = page + (offset + sd->len - 1) / PAGE_SIZE; for (page += offset / PAGE_SIZE; page <= last_page; page++) { /* - * Skip page replacement when extending the contents - * of the current page. + * Skip page replacement when extending the contents of the + * current page. But note that we may get two zero_pages in a + * row from shmem. */ - if (page == *(rqstp->rq_next_page - 1)) + if (page == *(rqstp->rq_next_page - 1) && + offset_in_page(rqstp->rq_res.page_base + + rqstp->rq_res.page_len)) continue; if (unlikely(!svc_rqst_replace_page(rqstp, page))) return -EIO;