From patchwork Fri Aug 23 20:08:16 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 13775938 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 9A52AC531DC for ; Fri, 23 Aug 2024 20:09:27 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 2F5826B03A1; Fri, 23 Aug 2024 16:09:27 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 2A543800C8; Fri, 23 Aug 2024 16:09:27 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 146B16B03A3; Fri, 23 Aug 2024 16:09:27 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0010.hostedemail.com [216.40.44.10]) by kanga.kvack.org (Postfix) with ESMTP id E8A026B03A1 for ; Fri, 23 Aug 2024 16:09:26 -0400 (EDT) Received: from smtpin29.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay08.hostedemail.com (Postfix) with ESMTP id 8E22A140122 for ; Fri, 23 Aug 2024 20:09:26 +0000 (UTC) X-FDA: 82484599932.29.DA72173 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by imf24.hostedemail.com (Postfix) with ESMTP id C38EF18001B for ; Fri, 23 Aug 2024 20:09:24 +0000 (UTC) Authentication-Results: imf24.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=UFp1Bgtx; spf=pass (imf24.hostedemail.com: domain of dhowells@redhat.com designates 170.10.133.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=1724443682; 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=JCLN+DgZIMYjLim8F8YFGy04wez+ty5Hq7K/oJiQsg4=; b=ou9700jGU4lkjWjCk7eHgC5wE8+mQxCtZeVU1/3ZrPkhGT6kmXOjTseQwbAvpG9wS+u6du zGPJ1mXGHRy6hF0Ynt+W9tXZtI2zLcEKijj0oR3i0qlPkGu15HwHP8YFypujYVUhkGkWAQ rHDDhMdhPwQ4dgrQEf8jgyT3GVobpF8= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1724443682; a=rsa-sha256; cv=none; b=8QsmVzY7NSQPAYPtUL2hBrrxIune77idfmQvnwdgeBxvq2mHjIeg4pllMLl1Jny68WE0AK mMkUVnG7Vqd6Tyk6b45nwb02iHPumi0yGSA72rB3YQi6UGO5AzxbUG9ZngGLuRKClYZ4mM T1oLKBo/ebKillNehiJ8BkLH6DwhddQ= ARC-Authentication-Results: i=1; imf24.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=UFp1Bgtx; spf=pass (imf24.hostedemail.com: domain of dhowells@redhat.com designates 170.10.133.124 as permitted sender) smtp.mailfrom=dhowells@redhat.com; dmarc=pass (policy=none) header.from=redhat.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1724443764; 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=JCLN+DgZIMYjLim8F8YFGy04wez+ty5Hq7K/oJiQsg4=; b=UFp1BgtxFrBGOcjc3/d1vwNsCgge2oVdt5+ZcbBvCJZcWX2rV0daqRKTdgohUjBLzmv0tk F53sBhsozuEOi+BEpetsAI22MNpyOcjaCgiOlNhK4jby0+clIOCKigtdwS09mYgo+CrYF4 X62FinngfZ0WzBOyC+RzlcjSMvAO9XY= Received: from mx-prod-mc-02.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-634-N2VgEkt9MmW_PQ0CeQQcEw-1; Fri, 23 Aug 2024 16:09:18 -0400 X-MC-Unique: N2VgEkt9MmW_PQ0CeQQcEw-1 Received: from mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com [10.30.177.17]) (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-02.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTPS id 740711955D4D; Fri, 23 Aug 2024 20:09:16 +0000 (UTC) Received: from warthog.procyon.org.uk.com (unknown [10.42.28.30]) by mx-prod-int-05.mail-002.prod.us-west-2.aws.redhat.com (Postfix) with ESMTP id 42F201956053; Fri, 23 Aug 2024 20:09:12 +0000 (UTC) From: David Howells To: Christian Brauner , Steve French Cc: David Howells , Pankaj Raghav , Paulo Alcantara , 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, Shyam Prasad N Subject: [PATCH 8/9] cifs: Fix FALLOC_FL_PUNCH_HOLE support Date: Fri, 23 Aug 2024 21:08:16 +0100 Message-ID: <20240823200819.532106-9-dhowells@redhat.com> In-Reply-To: <20240823200819.532106-1-dhowells@redhat.com> References: <20240823200819.532106-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.0 on 10.30.177.17 X-Rspam-User: X-Rspamd-Server: rspam04 X-Rspamd-Queue-Id: C38EF18001B X-Stat-Signature: 81rwnqhfxu3t3ejd1idqe9o5ko36rpz9 X-HE-Tag: 1724443764-415899 X-HE-Meta: U2FsdGVkX1/qGjRzXM/rCTeA/j+Lgecd4lPIgPEjlmuHmSeHiYydelU2Tj9+Y+RK+ce9mnyQymRjDxG2pQJwP+8rPIv2ZbbKh5NdN0Bfmec+9tvyA+eSODDWyqOd1cNNzI4GYBYxz4ZajVAJYS2eA2WYUAsSWGDVPR+55v5b4pdcAeslrxgzVDK6KdPJrjkenGgczubMbA9qDSxAt85Z2rDfutChKRh8RmcFuDrRYxIywWet5nYqFZt7StUqDUuBtBZAKYUhoTVw5IDqdFa3jI9gdmWNp3U/ToUmDX5gL1QE+RR+6ilLnKt6cT2fym3l7cOybTaMcdGOZDFFRLZRcTOhsI2R21GCc2gt5Pb6WRNIAlbhc7+yhhsJgnGgI3IObGbfhKb59EG/GypO/scVLPAFG92dlg2Gp358hJ8EUK29hlGMOvrKrrDRWxBRA7mpqMR6cCvxT8UtTazQqLY+6uUXl6vyiRwcK7ObOAMKBl+p0lOX5xyATXqPwENRgkd5jsCxgupIdHOu1YY5irlQKZNdiWvkRbIFOCqqT7LG3mqyIBipeGH4MpuFdQGQNnP3+BvTdzTU8IiRbSz10Xsd2bh8V7APQt1ISruAnTHTSqL8U7QQRqVmoG6AhjQmEg22gOgJW+MyvV5035EFoZ3sWR87CtBbxvSsGdhvV345kg2ad5+P0EUZBKgu0zs/wmAgwYQafaUo5N+Rj+sEUuhxPnTlWKgYLPMYR/QVCqV2gvpvPZo7ESWsLwaZIjZALz/vrCJZRkoUr+W3PErbrhsvG67VNZEUbKIF/mTAXM/ZoFIdWbjIZ8yNf8yM94o9NNHyvUErvS4ND4aP907pReBUUPWvWOq18hLSBIvltaghfP1I9ut4s9pXnAnqvfGw1IGL8wCwoeLA7LNJ+KUO1CqDUcEhRoD4dJ9EXT5jukm80+cUyeU3WhuuJlh3GvFxTLO3vd0H4XG3D6isLNR6Yo+ gMwIOuSS Dt5f2RHdwshMYw0BQxSOxTfy/+xk1X8dYoyowDuNqGJT7pfOQtlaFyfYmLpoZ5ma9Gwax0bMM/THzjZ507xLM9xsY5gjelw8ZDkSOJzsnX4D1XGRwg29WMWCTHvQBQnMbbJ0RfqjvW1OEsekSl6h3yG5SbvZGvM6bJZNzld3c+nM+ele+N3jZV9FwHkQW3Ti1MyBnjVNEbKNY0+bJ2zIK7q62bLsjvaqMHJpdsMfrl8I6Qywsvve4Xp0Hd9lx+aFXaNGnYZMQJMoM9lmKBAY3TfGQdEyksyDHjFEvwmQaGJ1YZn74jpJvts9uio3jgwfPJrQHw45dw871EjAYmmnG55L2X2/lqNhevJPOHR8VeXAUsVyT40OV33kbi4+MLUp1jLCubaUS+80/Ec8N0f35P5k6nyEPqpUcs3SYMFH228YaOY86v27p/ybA2xSECL1SkelEROd0B7nJcxKaj+OC1oFrOFPy5oE7AJNtNlBAGtZGUsmkZrwYwWdcRC2zs1afVQGGYThHHijrqQtUXVgj4IxY6GjhIR8GhUmlYk7smzBp6mg= 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: The cifs filesystem doesn't quite emulate FALLOC_FL_PUNCH_HOLE correctly (note that due to lack of protocol support, it can't actually implement it directly). Whilst it will (partially) invalidate dirty folios in the pagecache, it doesn't write them back first, and so the EOF marker on the server may be lower than inode->i_size. This presents a problem, however, as if the punched hole invalidates the tail of the locally cached dirty data, writeback won't know it needs to move the EOF over to account for the hole punch (which isn't supposed to move the EOF). We could just write zeroes over the punched out region of the pagecache and write that back - but this is supposed to be a deallocatory operation. Fix this by manually moving the EOF over on the server after the operation if the hole punched would corrupt it. Note that the FSCTL_SET_ZERO_DATA RPC and the setting of the EOF should probably be compounded to stop a third party interfering (or, at least, massively reduce the chance). This was reproducible occasionally by using fsx with the following script: truncate 0x0 0x375e2 0x0 punch_hole 0x2f6d3 0x6ab5 0x375e2 truncate 0x0 0x3a71f 0x375e2 mapread 0xee05 0xcf12 0x3a71f write 0x2078e 0x5604 0x3a71f write 0x3ebdf 0x1421 0x3a71f * punch_hole 0x379d0 0x8630 0x40000 * mapread 0x2aaa2 0x85b 0x40000 fallocate 0x1b401 0x9ada 0x40000 read 0x15f2 0x7d32 0x40000 read 0x32f37 0x7a3b 0x40000 * The second "write" should extend the EOF to 0x40000, and the "punch_hole" should operate inside of that - but that depends on whether the VM gets in and writes back the data first. If it doesn't, the file ends up 0x3a71f in size, not 0x40000. Fixes: 31742c5a3317 ("enable fallocate punch hole ("fallocate -p") for SMB3") Signed-off-by: David Howells cc: Steve French cc: Paulo Alcantara cc: Shyam Prasad N cc: Jeff Layton cc: linux-cifs@vger.kernel.org cc: netfs@lists.linux.dev --- fs/smb/client/smb2ops.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c index 14c3d11869ba..8fb68c47c218 100644 --- a/fs/smb/client/smb2ops.c +++ b/fs/smb/client/smb2ops.c @@ -3305,6 +3305,7 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon, struct inode *inode = file_inode(file); struct cifsFileInfo *cfile = file->private_data; struct file_zero_data_information fsctl_buf; + unsigned long long end = offset + len, i_size, remote_i_size; long rc; unsigned int xid; __u8 set_sparse = 1; @@ -3336,6 +3337,27 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon, (char *)&fsctl_buf, sizeof(struct file_zero_data_information), CIFSMaxBufSize, NULL, NULL); + + if (rc) + goto unlock; + + /* If there's dirty data in the buffer that would extend the EOF if it + * were written, then we need to move the EOF marker over to the lower + * of the high end of the hole and the proposed EOF. The problem is + * that we locally hole-punch the tail of the dirty data, the proposed + * EOF update will end up in the wrong place. + */ + i_size = i_size_read(inode); + remote_i_size = netfs_inode(inode)->remote_i_size; + if (end > remote_i_size && i_size > remote_i_size) { + unsigned long long extend_to = umin(end, i_size); + rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid, + cfile->fid.volatile_fid, cfile->pid, extend_to); + if (rc >= 0) + netfs_inode(inode)->remote_i_size = extend_to; + } + +unlock: filemap_invalidate_unlock(inode->i_mapping); out: inode_unlock(inode);