Linux CIFS filesystem development
 help / color / mirror / Atom feed
* [PATCH 1/5] netfs: discard post-EOF pagecache when extending a file via write
@ 2026-09-21 15:49 Paulo Alcantara
  2026-09-21 15:49 ` [PATCH 2/5] smb: client: discard post-EOF pagecache when extending a file via truncate Paulo Alcantara
                   ` (3 more replies)
  0 siblings, 4 replies; 6+ messages in thread
From: Paulo Alcantara @ 2026-09-21 15:49 UTC (permalink / raw)
  To: linux-cifs, netfs
  Cc: David Howells, Christian Brauner, Namjae Jeon, Ronnie Sahlberg,
	Shyam Prasad N, Tom Talpey, Bharath SM, stable

Fix netfs to erase the contents of a hole created after the EOF by an
ordinary write if dirty data has been previously left there by writes
through an mmapped region.  Neither the buffered nor the
unbuffered/DIO write path drops that stale pagecache.

Discard it with truncate_pagecache() before an extending write, which
zeroes the folio straddling the EOF and drops the folios beyond it
while preserving the data below.

Fixes: 938e13a73b24 ("netfs: Implement buffered write API")
Fixes: 153a9961b551 ("netfs: Implement unbuffered/DIO write support")
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: stable@vger.kernel.org
---
 fs/netfs/buffered_write.c | 4 ++++
 fs/netfs/direct_write.c   | 4 ++++
 2 files changed, 8 insertions(+)

diff --git a/fs/netfs/buffered_write.c b/fs/netfs/buffered_write.c
index 2cdb68e6b16f..62849fd44313 100644
--- a/fs/netfs/buffered_write.c
+++ b/fs/netfs/buffered_write.c
@@ -469,6 +469,7 @@ ssize_t netfs_buffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *fr
 					 struct netfs_group *netfs_group)
 {
 	struct file *file = iocb->ki_filp;
+	struct inode *inode = file_inode(file);
 	ssize_t ret;
 
 	trace_netfs_write_iter(iocb, from);
@@ -481,6 +482,9 @@ ssize_t netfs_buffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *fr
 	if (ret)
 		return ret;
 
+	if (iocb->ki_pos > i_size_read(inode))
+		truncate_pagecache(inode, i_size_read(inode));
+
 	return netfs_perform_write(iocb, from, netfs_group);
 }
 EXPORT_SYMBOL(netfs_buffered_write_iter_locked);
diff --git a/fs/netfs/direct_write.c b/fs/netfs/direct_write.c
index 2361277416c7..4268a4ee376a 100644
--- a/fs/netfs/direct_write.c
+++ b/fs/netfs/direct_write.c
@@ -359,6 +359,10 @@ ssize_t netfs_unbuffered_write_iter(struct kiocb *iocb, struct iov_iter *from)
 	ret = file_update_time(file);
 	if (ret < 0)
 		goto out;
+
+	if (iocb->ki_pos > i_size_read(inode))
+		truncate_pagecache(inode, i_size_read(inode));
+
 	if (iocb->ki_flags & IOCB_NOWAIT) {
 		/* We could block if there are any pages in the range. */
 		ret = -EAGAIN;
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 2/5] smb: client: discard post-EOF pagecache when extending a file via truncate
  2026-09-21 15:49 [PATCH 1/5] netfs: discard post-EOF pagecache when extending a file via write Paulo Alcantara
@ 2026-09-21 15:49 ` Paulo Alcantara
  2026-09-21 16:48   ` Paulo Alcantara
  2026-09-21 15:49 ` [PATCH 3/5] smb: client: discard post-EOF pagecache when extending a file via zero range Paulo Alcantara
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 6+ messages in thread
From: Paulo Alcantara @ 2026-09-21 15:49 UTC (permalink / raw)
  To: linux-cifs, netfs
  Cc: David Howells, Christian Brauner, Namjae Jeon, Ronnie Sahlberg,
	Shyam Prasad N, Tom Talpey, Bharath SM, stable

cifs_setsize() relied on pagecache_isize_extended() to zero the tail of
the folio straddling the old EOF, but that helper is a no-op on CIFS
(i_blkbits is 14), so data dirtied past EOF through an mmap survived and
became visible once the file was extended.

Drop that call and lower the truncate_pagecache() boundary to the smaller
of the old and new sizes, which is block-size independent and reliably
discards the pagecache beyond the old EOF.

Fixes: c510edb9734a ("cifs: call pagecache_isize_extended() in cifs_setsize() when extending")
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: stable@vger.kernel.org
---
 fs/smb/client/inode.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

diff --git a/fs/smb/client/inode.c b/fs/smb/client/inode.c
index 1fe0ef0a95db..d79a9d80ef34 100644
--- a/fs/smb/client/inode.c
+++ b/fs/smb/client/inode.c
@@ -3071,9 +3071,13 @@ void cifs_setsize(struct inode *inode, loff_t offset)
 		inode->i_blocks = blocks;
 	spin_unlock(&inode->i_lock);
 	inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
-	if (offset > old_size)
-		pagecache_isize_extended(inode, old_size, offset);
-	truncate_pagecache(inode, offset);
+	/*
+	 * Drop the pagecache beyond the smaller of the old and new size so that
+	 * data written past the old EOF through an mmap is not exposed once the
+	 * file is extended.  pagecache_isize_extended() can't be used here as
+	 * it is a no-op when the block size is >= PAGE_SIZE, as on CIFS.
+	 */
+	truncate_pagecache(inode, min(offset, old_size));
 	netfs_wait_for_outstanding_io(inode);
 }
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 3/5] smb: client: discard post-EOF pagecache when extending a file via zero range
  2026-09-21 15:49 [PATCH 1/5] netfs: discard post-EOF pagecache when extending a file via write Paulo Alcantara
  2026-09-21 15:49 ` [PATCH 2/5] smb: client: discard post-EOF pagecache when extending a file via truncate Paulo Alcantara
@ 2026-09-21 15:49 ` Paulo Alcantara
  2026-09-21 15:49 ` [PATCH 4/5] smb: client: discard post-EOF pagecache when extending a file via copy range Paulo Alcantara
  2026-09-21 15:49 ` [PATCH 5/5] smb: client: discard post-EOF pagecache when extending a file via clone range Paulo Alcantara
  3 siblings, 0 replies; 6+ messages in thread
From: Paulo Alcantara @ 2026-09-21 15:49 UTC (permalink / raw)
  To: linux-cifs, netfs
  Cc: David Howells, Christian Brauner, Namjae Jeon, Ronnie Sahlberg,
	Shyam Prasad N, Tom Talpey, Bharath SM, stable

smb3_zero_range() removed the pagecache only for the range being zeroed,
so when it extends the file the folio straddling the old EOF - which may
hold data dirtied past EOF through an mmap - was never dropped and became
visible as file content once the file was extended.

Lower the discard boundary to the smaller of the zero-range offset and the
old EOF.

Fixes: 72c419d9b073 ("cifs: fix smb3_zero_range so it can expand the file-size when required")
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: stable@vger.kernel.org
---
 fs/smb/client/smb2ops.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 3464470d3297..7282ed916470 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -3558,8 +3558,11 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
 	/*
 	 * We zero the range through ioctl, so we need remove the page caches
 	 * first, otherwise the data may be inconsistent with the server.
+	 *
+	 * Start at the old EOF when extending so the folio straddling it, which
+	 * may hold data written past EOF through an mmap, is dropped too.
 	 */
-	truncate_pagecache_range(inode, offset, offset + len - 1);
+	truncate_pagecache_range(inode, min(offset, i_size), offset + len - 1);
 	netfs_wait_for_outstanding_io(inode);
 
 	/* if file not oplocked can't be sure whether asking to extend size */
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 4/5] smb: client: discard post-EOF pagecache when extending a file via copy range
  2026-09-21 15:49 [PATCH 1/5] netfs: discard post-EOF pagecache when extending a file via write Paulo Alcantara
  2026-09-21 15:49 ` [PATCH 2/5] smb: client: discard post-EOF pagecache when extending a file via truncate Paulo Alcantara
  2026-09-21 15:49 ` [PATCH 3/5] smb: client: discard post-EOF pagecache when extending a file via zero range Paulo Alcantara
@ 2026-09-21 15:49 ` Paulo Alcantara
  2026-09-21 15:49 ` [PATCH 5/5] smb: client: discard post-EOF pagecache when extending a file via clone range Paulo Alcantara
  3 siblings, 0 replies; 6+ messages in thread
From: Paulo Alcantara @ 2026-09-21 15:49 UTC (permalink / raw)
  To: linux-cifs, netfs
  Cc: David Howells, Christian Brauner, Namjae Jeon, Ronnie Sahlberg,
	Shyam Prasad N, Tom Talpey, Bharath SM, stable

cifs_file_copychunk_range() invalidated the pagecache only for the
destination region, so when a copy extends the file the folio straddling
the old EOF - which may hold data dirtied past EOF through an mmap - was
never dropped and became visible as file content once the file was
extended.

Start the invalidation at the smaller of the destination offset and the
old EOF.  filemap_invalidate_inode() writes back before invalidating
while i_size is still old, so nothing past the old EOF is flushed to the
server.

Fixes: 8101d6e112e2 ("cifs: Fix copy offload to flush destination region")
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: stable@vger.kernel.org
---
 fs/smb/client/cifsfs.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
index 7ecd70efdfea..f1fb4b7b7b7c 100644
--- a/fs/smb/client/cifsfs.c
+++ b/fs/smb/client/cifsfs.c
@@ -1581,8 +1581,13 @@ ssize_t cifs_file_copychunk_range(unsigned int xid,
 	/* Flush and invalidate all the folios in the destination region.  If
 	 * the copy was successful, then some of the flush is extra overhead,
 	 * but we need to allow for the copy failing in some way (eg. ENOSPC).
+	 *
+	 * Start at the old EOF when extending so the folio straddling it, which
+	 * may hold data written past EOF through an mmap, is dropped too.
 	 */
-	rc = filemap_invalidate_inode(target_inode, true, destoff, destoff + len - 1);
+	rc = filemap_invalidate_inode(target_inode, true,
+				      min(destoff, i_size_read(target_inode)),
+				      destoff + len - 1);
 	if (rc)
 		goto unlock;
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [PATCH 5/5] smb: client: discard post-EOF pagecache when extending a file via clone range
  2026-09-21 15:49 [PATCH 1/5] netfs: discard post-EOF pagecache when extending a file via write Paulo Alcantara
                   ` (2 preceding siblings ...)
  2026-09-21 15:49 ` [PATCH 4/5] smb: client: discard post-EOF pagecache when extending a file via copy range Paulo Alcantara
@ 2026-09-21 15:49 ` Paulo Alcantara
  3 siblings, 0 replies; 6+ messages in thread
From: Paulo Alcantara @ 2026-09-21 15:49 UTC (permalink / raw)
  To: linux-cifs, netfs
  Cc: David Howells, Christian Brauner, Namjae Jeon, Ronnie Sahlberg,
	Shyam Prasad N, Tom Talpey, Bharath SM, stable

cifs_remap_file_range() discarded the pagecache only for the folios
overlapping the destination region, so when a clone extends the file the
folio straddling the old EOF - which may hold data dirtied past EOF
through an mmap - was never dropped and became visible as file content
once the file was extended.

Start the discard at the smaller of fstart and the old EOF.  i_size is
still old here, so nothing past the old EOF is flushed to the server.

Fixes: c54fc3a4f375 ("cifs: Fix flushing, invalidation and file size with FICLONE")
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Namjae Jeon <linkinjeon@kernel.org>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: stable@vger.kernel.org
---
 fs/smb/client/cifsfs.c | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/fs/smb/client/cifsfs.c b/fs/smb/client/cifsfs.c
index f1fb4b7b7b7c..6410249f529a 100644
--- a/fs/smb/client/cifsfs.c
+++ b/fs/smb/client/cifsfs.c
@@ -1467,9 +1467,14 @@ static loff_t cifs_remap_file_range(struct file *src_file, loff_t off,
 	i_size = target_inode->i_size;
 	spin_unlock(&target_inode->i_lock);
 
-	/* Discard all the folios that overlap the destination region. */
+	/*
+	 * Discard all the folios that overlap the destination region.  Start at
+	 * the old EOF when extending so the folio straddling it, which may hold
+	 * data written past EOF through an mmap, is dropped too.
+	 */
 	cifs_dbg(FYI, "about to discard pages %llx-%llx\n", fstart, fend);
-	truncate_inode_pages_range(&target_inode->i_data, fstart, fend);
+	truncate_inode_pages_range(&target_inode->i_data,
+				   min(fstart, i_size), fend);
 
 	fscache_invalidate(cifs_inode_cookie(target_inode), NULL, i_size, 0);
 
-- 
2.55.0


^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH 2/5] smb: client: discard post-EOF pagecache when extending a file via truncate
  2026-09-21 15:49 ` [PATCH 2/5] smb: client: discard post-EOF pagecache when extending a file via truncate Paulo Alcantara
@ 2026-09-21 16:48   ` Paulo Alcantara
  0 siblings, 0 replies; 6+ messages in thread
From: Paulo Alcantara @ 2026-09-21 16:48 UTC (permalink / raw)
  To: linux-cifs, netfs
  Cc: David Howells, Christian Brauner, Namjae Jeon, Ronnie Sahlberg,
	Shyam Prasad N, Tom Talpey, Bharath SM, stable

Paulo Alcantara <pc@manguebit.org> writes:

> cifs_setsize() relied on pagecache_isize_extended() to zero the tail of
> the folio straddling the old EOF, but that helper is a no-op on CIFS
> (i_blkbits is 14), so data dirtied past EOF through an mmap survived and
> became visible once the file was extended.
>
> Drop that call and lower the truncate_pagecache() boundary to the smaller
> of the old and new sizes, which is block-size independent and reliably
> discards the pagecache beyond the old EOF.
> ...

I'll address Sashiko's comments [1] for this patch and 1/5.  Please
ignore the whole series for now.

[1] https://sashiko.dev/#/patchset/20260921154957.903891-1-pc%40manguebit.org

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2026-09-21 16:48 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-09-21 15:49 [PATCH 1/5] netfs: discard post-EOF pagecache when extending a file via write Paulo Alcantara
2026-09-21 15:49 ` [PATCH 2/5] smb: client: discard post-EOF pagecache when extending a file via truncate Paulo Alcantara
2026-09-21 16:48   ` Paulo Alcantara
2026-09-21 15:49 ` [PATCH 3/5] smb: client: discard post-EOF pagecache when extending a file via zero range Paulo Alcantara
2026-09-21 15:49 ` [PATCH 4/5] smb: client: discard post-EOF pagecache when extending a file via copy range Paulo Alcantara
2026-09-21 15:49 ` [PATCH 5/5] smb: client: discard post-EOF pagecache when extending a file via clone range Paulo Alcantara

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox