From patchwork Wed Aug 28 21:02:46 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 13781957 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 ED4C2C71147 for ; Wed, 28 Aug 2024 21:03:46 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 8043A6B009B; Wed, 28 Aug 2024 17:03:46 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 78C8A6B009C; Wed, 28 Aug 2024 17:03:46 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 653BB6B009D; Wed, 28 Aug 2024 17:03:46 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0017.hostedemail.com [216.40.44.17]) by kanga.kvack.org (Postfix) with ESMTP id 4444F6B009B for ; Wed, 28 Aug 2024 17:03:46 -0400 (EDT) Received: from smtpin19.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id 020121C3E96 for ; Wed, 28 Aug 2024 21:03:45 +0000 (UTC) X-FDA: 82502880852.19.DACEC96 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by imf30.hostedemail.com (Postfix) with ESMTP id 41DA580010 for ; Wed, 28 Aug 2024 21:03:44 +0000 (UTC) Authentication-Results: imf30.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=aUCl8CDd; spf=pass (imf30.hostedemail.com: domain of dhowells@redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1724879003; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=cZLOwDsDBBJUFs2hQlOukyGuDHu131MWSIeu0yUM/RI=; b=D94iCKpyNgpLJPQ86DxQSGRLFwYLF12ybrg1jkQnQV4giXqPw+v/jr9O5sTo37jhrkuqee R533J9+dWu2pP6YUqxmWHylv2F259HyIsNzCchpflcM/BOxlGup+nPix2nX4eysYniGJNA 7x/xHEyfn04zHTEGt3jVDj9MEIfacXg= ARC-Authentication-Results: i=1; imf30.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=aUCl8CDd; spf=pass (imf30.hostedemail.com: domain of dhowells@redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1724879003; a=rsa-sha256; cv=none; b=2ZF21Vo5SlLEh3Kx4OrH6S/JDOONsgYscCsGfQPcFK6AMqJqrbyJhGrv/Kf4ULuDL7S9us S5FQbzgz+d5sivPj9H1pMtSq70dnJPVg8xB3502Stj4k5YfwUsHw6svPgNsPPYr2PZEHwV ItSrPxYUum7veQ32/mMNWYyvb+bjhLo= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1724879023; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=cZLOwDsDBBJUFs2hQlOukyGuDHu131MWSIeu0yUM/RI=; b=aUCl8CDdxJQ9A5HaTLTS+e3wXVxPEM4LVuRUwEoC0KkG9kmQMm4PW+h5r9ge++K5n8d6g9 3uKGuAZ5IJap4sjd+EyePoDi5f5tZlaoF1XtOCgKfZpVi2hfrx2IlSiZHIspJ4Wc1x+ezu hCL5+VNwIrdVgabNAVqyeS8r755bRfI= Received: from mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (ec2-54-186-198-63.us-west-2.compute.amazonaws.com [54.186.198.63]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-465-vc_IMyGmMNa-yhlY57doPw-1; Wed, 28 Aug 2024 17:03:40 -0400 X-MC-Unique: vc_IMyGmMNa-yhlY57doPw-1 Received: from mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.4]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by mx-prod-mc-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 06D7A1955D48; Wed, 28 Aug 2024 21:03:37 +0000 (UTC) Received: from warthog.procyon.org.com (unknown [10.42.28.30]) by mx-prod-int-01.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 4C66B30001A1; Wed, 28 Aug 2024 21:03:30 +0000 (UTC) From: David Howells To: Christian Brauner , Steve French Cc: David Howells , Paulo Alcantara , Tom Talpey , Dominique Martinet , Jeff Layton , Matthew Wilcox , netfs@lists.linux.dev, linux-afs@lists.infradead.org, linux-cifs@vger.kernel.org, linux-nfs@vger.kernel.org, ceph-devel@vger.kernel.org, v9fs@lists.linux.dev, linux-erofs@lists.ozlabs.org, linux-fsdevel@vger.kernel.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, Steve French , Zhang Xiaoxu , Pavel Shilovsky , Shyam Prasad N , Rohith Surabattula Subject: [PATCH 5/6] cifs: Fix FALLOC_FL_ZERO_RANGE to preflush buffered part of target region Date: Wed, 28 Aug 2024 22:02:46 +0100 Message-ID: <20240828210249.1078637-6-dhowells@redhat.com> In-Reply-To: <20240828210249.1078637-1-dhowells@redhat.com> References: <20240828210249.1078637-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.4.1 on 10.30.177.4 X-Rspam-User: X-Stat-Signature: 3cmu7kwdcobcz65q6rxz96is5pfdcy9g X-Rspamd-Queue-Id: 41DA580010 X-Rspamd-Server: rspam11 X-HE-Tag: 1724879024-587536 X-HE-Meta: U2FsdGVkX19adghdsS9DHP5yEaYBI7yzmj0J0DThMTLStojH6bZAkypOfZAioOssXJmBMYcm9Sy28mqiPVQG8DcWc4V0/MKP/kjZgJTggvq0jApn/lD+/WiOTaxNRx+rT7CgyuRgU/PtUWconxLjphY7vKFnTmziX2TI9bcLUReCYSFzjYEaQseac5lk6zkLaZev06396jSlKadW71CismwC+sy4LL/XTdwgsRwKNeSLa5gHlpy2WBUrilmdTwtrWTcsvnlFWNeTfSVPO2EnODEv2Lt8Hrh9pyqNUCXDWbPk1nMPZJ006nVR3pXqoG+hcmFOlcRi2+N7i+CNRqiEU/G72CEObCX1G0M5YkbfTH5uvXo4HGYm52JyBA9oB2iFqLRc7NwFuHaJ/r5uAX/bCBndXn9MWikSqu627V6sYcrhXIyr/lp/BpoB+gUEgA+tIjMFS2YKzdR0LLC3HxkdS9ZoCVlfnifGz5wD8FsO/6QE54ZeytMzRSCK/yAWrAP7T9cHC1aR3lv5VXtBeoKzVY1adMvEteM3Ws7vvdFS//0WIqBxV4cKgUghquXeOTk89xWZkX95Mh3yvK2KZjHpO308sGoPUhYIU19CK5oYXPyzgYEXKO/9ixXf1eZk2HRLBnxFIRgUEHYLCgdFNtF8pLiwrxtd3K+tW9p3BddnWVXOrYLqRiJc+fnyUc57hn15JRerpKrZUozI6eYkp0AvjV9W3QHRG0tWI0bWJnXfzpKZkZzctsnat6lpi9PBE8pdJ2VXWO2W5q110liKdaA79UwfCmVErazhHITN4UBZG1+bAJlT0t8Y69NEh3QG1/RngT1H8oTlL773/xH7ok2lUxFR21e3f03w6i6WQC3WURwwEDogDt4zoNdSSxUscPdrCI0tPhXdDckLpTV3fjS6l64H86gArvam33zJgK47Iraqg/CqdNcf5FKTotm5HqI5OMcb0VWAGbdfIL4oSZH QjRmMDcE hFbQOUa9fMiYAE1uBudLlmFGQXi1lWUjx8W0PFQz37HdKzF5klI7rMUC3PYAp0LbDqE7RYVhathOQS/4l/oj5Xs1LTbECmj5UvXHHnqpRCEIcT8++lTYtHi0+YbHzk7h4MDmerEmJ2AeTri0+c3qKfWfBBH+E4lR9cBOBlQ6IKnxqN6/mvfmIK+Woc6WVCy78YzcuKmGlXQxW/gat4F3vbl6ElFGO8FLtx629B2aFC6K8c5/7VwrBPiT2vwrvo+ItDK4UqI+7ykYsYFOWDUzIBLiyf/uOF6HzMsuq5hoCxCt1wwJ4AYM6v35shlE8iQcxhsQw3ei8LQ+xnBLFRIgc3B5IxMWjeWTH356RwkI+8d3n0OdqO3HyblSzQcuunpUeBYpOUoOTkBtpTI2MDs3Cxwsa5YrKwhd04g8+4qOUy3UFK6L9HcQYZ6XVLpF0IEsXyekKXzD7fyyPNOiVwdhpaB7ymBPO92yimW0WFvzz/FgHWTPUK3zQJsvfxAC0Tpgro05H5kDzbwYeh3WNC2fSzzTrjQO7gSIrzlHiHzihtxdt2jfI+dX+yYyO0zG0GdZYTpyqy4UVkctmVhZN4WtwC2SRy+FFlEO3QmdHHT0oAXrnv4WPR9hY0HxpKrmLlS/lwqp2msXpONG10ccQvrcMHL0j9H2wkniwtDaY 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: List-Subscribe: List-Unsubscribe: Under certain conditions, the range to be cleared by FALLOC_FL_ZERO_RANGE may only be buffered locally and not yet have been flushed to the server. For example: xfs_io -f -t -c "pwrite -S 0x41 0 4k" \ -c "pwrite -S 0x42 4k 4k" \ -c "fzero 0 4k" \ -c "pread -v 0 8k" /xfstest.test/foo will write two 4KiB blocks of data, which get buffered in the pagecache, and then fallocate() is used to clear the first 4KiB block on the server - but we don't flush the data first, which means the EOF position on the server is wrong, and so the FSCTL_SET_ZERO_DATA RPC fails (and xfs_io ignores the error), but then when we try to read it, we see the old data. Fix this by preflushing any part of the target region that above the server's idea of the EOF position to force the server to update its EOF position. Note, however, that we don't want to simply expand the file by moving the EOF before doing the FSCTL_SET_ZERO_DATA[*] because someone else might see the zeroed region or if the RPC fails we then have to try to clean it up or risk getting corruption. [*] And we have to move the EOF first otherwise FSCTL_SET_ZERO_DATA won't do what we want. This fixes the generic/008 xfstest. [!] Note: A better way to do this might be to split the operation into two parts: we only do FSCTL_SET_ZERO_DATA for the part of the range below the server's EOF and then, if that worked, invalidate the buffered pages for the part above the range. Fixes: 6b69040247e1 ("cifs/smb3: Fix data inconsistent when zero file range") Signed-off-by: David Howells cc: Steve French cc: Zhang Xiaoxu cc: Pavel Shilovsky cc: Paulo Alcantara cc: Shyam Prasad N cc: Rohith Surabattula cc: Jeff Layton cc: linux-cifs@vger.kernel.org cc: linux-mm@kvack.org --- fs/smb/client/smb2ops.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index a6f00b157275..4df84ebe8dbe 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -3237,13 +3237,15 @@ static long smb3_zero_data(struct file *file, struct cifs_tcon *tcon, } static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon, - loff_t offset, loff_t len, bool keep_size) + unsigned long long offset, unsigned long long len, + bool keep_size) { struct cifs_ses *ses = tcon->ses; struct inode *inode = file_inode(file); struct cifsInodeInfo *cifsi = CIFS_I(inode); struct cifsFileInfo *cfile = file->private_data; - unsigned long long new_size; + struct netfs_inode *ictx = netfs_inode(inode); + unsigned long long i_size, new_size, remote_size; long rc; unsigned int xid; @@ -3255,6 +3257,16 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon, inode_lock(inode); filemap_invalidate_lock(inode->i_mapping); + i_size = i_size_read(inode); + remote_size = ictx->remote_i_size; + if (offset + len >= remote_size && offset < i_size) { + unsigned long long top = umin(offset + len, i_size); + + rc = filemap_write_and_wait_range(inode->i_mapping, offset, top - 1); + if (rc < 0) + goto zero_range_exit; + } + /* * We zero the range through ioctl, so we need remove the page caches * first, otherwise the data may be inconsistent with the server.