From patchwork Fri Jul 28 12:32:35 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chuck Lever X-Patchwork-Id: 13331869 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 kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 2F917C001E0 for ; Fri, 28 Jul 2023 12:32:41 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 453906B0072; Fri, 28 Jul 2023 08:32:41 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 403356B0074; Fri, 28 Jul 2023 08:32:41 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 2F2F38D0001; Fri, 28 Jul 2023 08:32:41 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0016.hostedemail.com [216.40.44.16]) by kanga.kvack.org (Postfix) with ESMTP id 1FAEF6B0072 for ; Fri, 28 Jul 2023 08:32:41 -0400 (EDT) Received: from smtpin11.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id BB07E1CA2D9 for ; Fri, 28 Jul 2023 12:32:40 +0000 (UTC) X-FDA: 81060959280.11.F6CF8E5 Received: from dfw.source.kernel.org (dfw.source.kernel.org [139.178.84.217]) by imf30.hostedemail.com (Postfix) with ESMTP id 0F8218001B for ; Fri, 28 Jul 2023 12:32:38 +0000 (UTC) Authentication-Results: imf30.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=P3WiCF1U; dmarc=pass (policy=none) header.from=kernel.org; spf=pass (imf30.hostedemail.com: domain of cel@kernel.org designates 139.178.84.217 as permitted sender) smtp.mailfrom=cel@kernel.org ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1690547559; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding:in-reply-to: references:dkim-signature; bh=C7b/ZTvfzcyQbc4EQKvATdchhtGp9PSC8zyjgFgnAu8=; b=O8ZJxGmC5+NdlEzzxxcclL6y20k9PJMm1vzZoP8deYznQJEwZHwWxcsO4QoGVl4YJEJWPi E6LxLj0Am+hgzLWboTWZZTXqXhgnw+fFeoiEEfZncq0YoMxhMTyXqnvqXmPCkZLcVY+l/B sWhHrS2xDkSlq3sq45yCZckmqRrKI+s= ARC-Authentication-Results: i=1; imf30.hostedemail.com; dkim=pass header.d=kernel.org header.s=k20201202 header.b=P3WiCF1U; dmarc=pass (policy=none) header.from=kernel.org; spf=pass (imf30.hostedemail.com: domain of cel@kernel.org designates 139.178.84.217 as permitted sender) smtp.mailfrom=cel@kernel.org ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1690547559; a=rsa-sha256; cv=none; b=Oq3LN/bnahoebOUBFMvv3t77m2ZjM+HbvFfcmmoedxSqyEHzttIoFMG+d84q9bGNDTSSZ9 MHsIadzuDDNBohq6QIejwR0AU7AEVy3sBz3ZF1ic+eW+DXJWmCCgBEZWLbKQmG9B+oIRjD cGrm52sxQnbsSZub4xYmcjbAYjLyQG4= 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 0776262124; Fri, 28 Jul 2023 12:32:38 +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 X-Rspamd-Queue-Id: 0F8218001B X-Rspam-User: X-Rspamd-Server: rspam04 X-Stat-Signature: g4ks8341tcxbjhp9ceipgz6hr51hrrub X-HE-Tag: 1690547558-562955 X-HE-Meta: U2FsdGVkX1/qfGeQR5f+WC8+iIxrKi8Uua/PGIO/U8DHnjZjSDDgtbPd/bY66C5M1Ldiq9zPyoZRwWnw9DxjNtUyIRqO/hOg72SuAqeB+UX6LhvcygeLuDKJ9ZqvNSWErs798mDTyJumQ25zSSX8VYUj48a6akCW4sm3BLSo6r+7Cq0tjlHP/wPYyQdxojChQQ02SKLfUVAyzFWhvkNEKLqZxDok4h6end5vYX977OGc/Vz4hjmjJHiEzkreYZ3jqGFyus7DYNYFHvCyRD9lzD5tiZndzuU1ufIiuN4XDxVkeGZhdNnEvT0ATVTFQdV7rUvMWXFbzN9zAauJOcRQ+tbL2Ek7SHqYn5wolGoykzzG6G9nEMK+S1BmnfloJGRx5n3GwNlVxIpaFhd198YG3gW3zad9kG22Qr3fjyRezaikVII2yW0QH5N8JLuorBi3eLTWDrtgueZELPZWGeZQFcQzU8zQ31uElehOdRjSXHDirO9ooAlkE4wMUT1gQbBHSTosQ+Y+XGnjEnGkEu5H4grJlAZ4FyAygvqxpuPAydfbYqxG7/NOFT/IVFuLqgxW/Uw5k68C4akLvt+gIYpayBjszjlY+tlkBs7OsqWHn0qYb9wkqtGg7nhZPZvv/rgvNSM4470Q2eccriKryvALOr6ySLI9oW5Ln0NmbcDOKdCdJioroKsNDcGT1fC2hDCzjSKT8fTGAOc/5Urpag3Nvb/RQAllAbYkMhMGBtbvdRzr13ycBs4GHjXd4rrkBEj+ZtLQW/SjCGV2318qRBFeXhAYPo+hZqniaKTv2es+2FxJSVZru5r4Qt6/4gyBjZ2XvIp2SO/IcqAOaMhjFVYYCnuE0KH8iTd8m9GzG+dwDF6YK3UqPA2eImzv0x0XnhpzXeqZYvm0dvdxs3EZyxT0cHedeIGX3MgmlVIKQ84n9JTOo8ZF9COmMbHvUhZAvb4RBF6hoCi7EZQIg9OQySP D6V4qK6V iRGbSfOQfYjIkMOppi67YKiwrHBfaPJamFTbvHHsosVfGe5B/fDRlLChAnnGcLz+3qZlKWKjXPBT0RSkx5BbYiZHD0c3rwM74DZHSbcgm9egSnOsyHMqVfUahKQIAp498TFAMBVf5uwG+oGXIh6Wryua2OfETJdsJNvCSZMdYuxCo4WGEtC5NsxqNhPTOUYQUVzrguL6SO6Ea1VW0vOEkOUdZ9/a62W6J4jRvvZWIWNK/YmRAbKFGj9oTBsAdkyyg0iTofDQ/QYztsoXtzNcx4MK88+F3VFw+RM1Ccl3ba12lLU+TmEPzzipOLz0ZwN+M1PxE1mSbNLj4foFOvzNxFo1dtVt+b4qBBOY4kuLiGT96fapda40GQH3KP9IhGfhEnCzOChrKo2xekmEEwOxyTOs9lV5XFM08WebBwdRX7l7e2i1umkPihtMoIrj3U9uCPocj/BmdxADOZ5Avs189FWCWKIFFFBVCyUnNvBYo+RtaeHENUt2x1IH2fD9nMp+TokjLYhnmvLMj1+t6HG3i7KmbXVolqcMdlhwOLyQ2xJoHER0a/T70APRBgT1sfiXFCVdMP8+U7S26TawPAmONV/r9jA== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: 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;