Skip to contentSkip to conversation

FAILED: patch "[PATCH] cifs: add fscache_resize_cookie() to cifs_setsize()" failed to apply to 6.12-stable tree

PATCH New [email protected] 2 participants 4 messages Aug 5 – Aug 12

Subsystems (3)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 6.12-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

To reproduce the conflict and resubmit, you may use the following commands:

git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.12.y
git checkout FETCH_HEAD
git cherry-pick -x fa724e235cfdb0fb0bb427d0f9dfe864ae27403e
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026080558-upstream-wooing-96aa@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'

Possible dependencies:

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From fa724e235cfdb0fb0bb427d0f9dfe864ae27403e Mon Sep 17 00:00:00 2001
From: Frank Sorenson <[email protected]>
Date: Sat, 25 Jul 2026 21:04:44 +0000
Subject: [PATCH] cifs: add fscache_resize_cookie() to cifs_setsize()

Several code paths update the VFS inode size by calling netfs_resize_file() and cifs_setsize(), but omit the corresponding fscache_resize_cookie() call, leaving the fscache cookie out of sync with the actual file size:

- cifs_file_set_size() in inode.c: server-side truncation via setattr
- cifs_do_truncate() in file.c: truncates to zero on O_TRUNC open
- smb2_duplicate_extents() in smb2ops.c: file clone extending EOF
- smb3_simple_falloc() in smb2ops.c: two branches that extend EOF via write-range and SMB2_set_eof respectively

Since every caller of cifs_setsize() must resize the fscache cookie, add the call to cifs_setsize() itself, consistent with how truncate_pagecache() is already consolidated there.

Fixes 70431bfd825d ("cifs: Support fscache indexing rewrite")
Fixes 93a43155127f ("cifs: Fix missing set of remote_i_size")
Fixes 110fee6b9bb5 ("smb: client: fix missing timestamp updates with O_TRUNC")
Fixes 7a06d3b816d7 ("smb/client: emulate small EOF-extending mode 0 fallocate ranges")
Cc David Howells <[email protected]>
Cc Paulo Alcantara <[email protected]>
Cc Huiwen He <[email protected]>
fs/smb/client/inode.c +1 -0
index 808085eb0cdc..0afff761aab9 100644
@@ -3059,6 +3059,7 @@ void cifs_setsize(struct inode *inode, loff_t offset)
 	inode_set_mtime_to_ts(inode, inode_set_ctime_current(inode));
 	truncate_pagecache(inode, offset);
 	netfs_wait_for_outstanding_io(inode);
+	fscache_resize_cookie(cifs_inode_cookie(inode), offset);
 }
 
 int cifs_file_set_size(const unsigned int xid, struct dentry *dentry,
maintainer
#1 lore raw

PATCH 1/3 include/linux/fs.h: add inode_lock_killable()

From: Max Kellermann <[email protected]>

[ Upstream commit d8c5507cd140d9471472ece673e70250b957c595 ]

Prepare for making inode operations killable while they're waiting for the lock.

Stable-dep-of: fa724e235cfd ("cifs: add fscache_resize_cookie() to cifs_setsize()")

---
 include/linux/fs.h | 10 ++++++++++
 1 file changed, 10 insertions(+)
include/linux/fs.h +10 -0
index 466a76771b0a1..9d0968ed2344a 100644
@@ -815,6 +815,11 @@ static inline void inode_lock(struct inode *inode)
 	down_write(&inode->i_rwsem);
 }
 
+static inline __must_check int inode_lock_killable(struct inode *inode)
+{
+	return down_write_killable(&inode->i_rwsem);
+}
+
 static inline void inode_unlock(struct inode *inode)
 {
 	up_write(&inode->i_rwsem);
@@ -825,6 +830,11 @@ static inline void inode_lock_shared(struct inode *inode)
 	down_read(&inode->i_rwsem);
 }
 
+static inline __must_check int inode_lock_shared_killable(struct inode *inode)
+{
+	return down_read_killable(&inode->i_rwsem);
+}
+
 static inline void inode_unlock_shared(struct inode *inode)
 {
 	up_read(&inode->i_rwsem);
Signature · 1 line
2.53.0
maintainer
#2 lore raw

PATCH 2/3 smb: client: fix race with fallocate(2) and AIO+DIO

From: Paulo Alcantara <[email protected]>

[ Upstream commit dba9f997c9d9a1cade05d006ed0429a63a4eed32 ]

AIO+DIO may extend the file size, hence we need to make sure ->i_size is stable across the entire fallocate(2) operation, otherwise it would become a truncate and then inode size reduced back down when it finishes.

Fix this by calling netfs_wait_for_outstanding_io() right after acquiring ->i_rwsem exclusively in cifs_fallocate() and then guarantee a stable ->i_size across fallocate(2).

Also call netfs_wait_for_outstanding_io() after truncating pagecache to avoid any potential races with writeback.

Fixes 210627b0aca9 ("smb: client: fix missing timestamp updates with O_TRUNC")
Cc Frank Sorenson <[email protected]>

Stable-dep-of: fa724e235cfd ("cifs: add fscache_resize_cookie() to cifs_setsize()")

---
 fs/smb/client/cifsfs.c  | 22 +++++++++++++++++++---
 fs/smb/client/inode.c   |  1 +
 fs/smb/client/smb2ops.c | 18 ++++++------------
 3 files changed, 26 insertions(+), 15 deletions(-)
fs/smb/client/cifsfs.c +19 -3
index 2f666c92b027b..08e7931cdda2b 100644
@@ -359,11 +359,27 @@ static long cifs_fallocate(struct file *file, int mode, loff_t off, loff_t len)
 	struct cifs_sb_info *cifs_sb = CIFS_FILE_SB(file);
 	struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
 	struct TCP_Server_Info *server = tcon->ses->server;
+	struct inode *inode = file_inode(file);
+	int rc;
+
+	if (!server->ops->fallocate)
+		return -EOPNOTSUPP;
+
+	rc = inode_lock_killable(inode);
+	if (rc)
+		return rc;
+
+	netfs_wait_for_outstanding_io(inode);
 
-	if (server->ops->fallocate)
-		return server->ops->fallocate(file, tcon, mode, off, len);
+	rc = file_modified(file);
+	if (rc)
+		goto out_unlock;
+
+	rc = server->ops->fallocate(file, tcon, mode, off, len);
 
-	return -EOPNOTSUPP;
+out_unlock:
+	inode_unlock(inode);
+	return rc;
 }
 
 static int cifs_permission(struct mnt_idmap *idmap,
fs/smb/client/inode.c +1 -0
index e7fc8d0aebee7..453a5df20f8cc 100644
@@ -2965,6 +2965,7 @@ void cifs_setsize(struct inode *inode, loff_t offset)
 	/* Cached inode must be refreshed on truncate */
 	cifs_i->time = 0;
 	truncate_pagecache(inode, offset);
+	netfs_wait_for_outstanding_io(inode);
 }
 
 static int
fs/smb/client/smb2ops.c +6 -12
index 61309fead04e5..e99b8e1f66d4f 100644
@@ -3315,7 +3315,6 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
 	trace_smb3_zero_enter(xid, cfile->fid.persistent_fid, tcon->tid,
 			      ses->Suid, offset, len);
 
-	inode_lock(inode);
 	filemap_invalidate_lock(inode->i_mapping);
 
 	i_size = i_size_read(inode);
@@ -3333,6 +3332,7 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
 	 * first, otherwise the data may be inconsistent with the server.
 	 */
 	truncate_pagecache_range(inode, offset, offset + len - 1);
+	netfs_wait_for_outstanding_io(inode);
 
 	/* if file not oplocked can't be sure whether asking to extend size */
 	rc = -EOPNOTSUPP;
@@ -3361,7 +3361,6 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
 
  zero_range_exit:
 	filemap_invalidate_unlock(inode->i_mapping);
-	inode_unlock(inode);
 	free_xid(xid);
 	if (rc)
 		trace_smb3_zero_err(xid, cfile->fid.persistent_fid, tcon->tid,
@@ -3385,7 +3384,6 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
 
 	xid = get_xid();
 
-	inode_lock(inode);
 	/* Need to make file sparse, if not already, before freeing range. */
 	/* Consider adding equivalent for compressed since it could also work */
 	rc = smb2_set_sparse(xid, tcon, cfile, inode, set_sparse);
@@ -3398,6 +3396,7 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
 	 * caches first, otherwise the data may be inconsistent with the server.
 	 */
 	truncate_pagecache_range(inode, offset, offset + len - 1);
+	netfs_wait_for_outstanding_io(inode);
 
 	cifs_dbg(FYI, "Offset %lld len %lld\n", offset, len);
 
@@ -3432,7 +3431,6 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
 unlock:
 	filemap_invalidate_unlock(inode->i_mapping);
 out:
-	inode_unlock(inode);
 	free_xid(xid);
 	return rc;
 }
@@ -3709,8 +3707,6 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon,
 
 	xid = get_xid();
 
-	inode_lock(inode);
-
 	old_eof = i_size_read(inode);
 	if ((off >= old_eof) ||
 	    off + len >= old_eof) {
@@ -3725,6 +3721,7 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon,
 
 	truncate_pagecache_range(inode, off, old_eof);
 	ictx->zero_point = old_eof;
+	netfs_wait_for_outstanding_io(inode);
 
 	rc = smb2_copychunk_range(xid, cfile, cfile, off + len,
 				  old_eof - off - len, off);
@@ -3745,8 +3742,7 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon,
 	fscache_resize_cookie(cifs_inode_cookie(inode), new_eof);
 out_2:
 	filemap_invalidate_unlock(inode->i_mapping);
- out:
-	inode_unlock(inode);
+out:
 	free_xid(xid);
 	return rc;
 }
@@ -3763,8 +3759,6 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
 
 	xid = get_xid();
 
-	inode_lock(inode);
-
 	old_eof = i_size_read(inode);
 	if (off >= old_eof) {
 		rc = -EINVAL;
@@ -3779,6 +3773,7 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
 	if (rc < 0)
 		goto out_2;
 	truncate_pagecache_range(inode, off, old_eof);
+	netfs_wait_for_outstanding_io(inode);
 
 	rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
 			  cfile->fid.volatile_fid, cfile->pid, new_eof);
@@ -3801,8 +3796,7 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
 	rc = 0;
 out_2:
 	filemap_invalidate_unlock(inode->i_mapping);
- out:
-	inode_unlock(inode);
+out:
 	free_xid(xid);
 	return rc;
 }
Signature · 1 line
2.53.0
maintainer
#3 lore raw

PATCH 3/3 cifs: add fscache_resize_cookie() to cifs_setsize()

In reply to Sasha Levin

From: Frank Sorenson <[email protected]>

[ Upstream commit fa724e235cfdb0fb0bb427d0f9dfe864ae27403e ]

Several code paths update the VFS inode size by calling netfs_resize_file() and cifs_setsize(), but omit the corresponding fscache_resize_cookie() call, leaving the fscache cookie out of sync with the actual file size:

- cifs_file_set_size() in inode.c: server-side truncation via setattr
- cifs_do_truncate() in file.c: truncates to zero on O_TRUNC open
- smb2_duplicate_extents() in smb2ops.c: file clone extending EOF
- smb3_simple_falloc() in smb2ops.c: two branches that extend EOF via write-range and SMB2_set_eof respectively

Since every caller of cifs_setsize() must resize the fscache cookie, add the call to cifs_setsize() itself, consistent with how truncate_pagecache() is already consolidated there.

Fixes 70431bfd825d ("cifs: Support fscache indexing rewrite")
Fixes 93a43155127f ("cifs: Fix missing set of remote_i_size")
Fixes 110fee6b9bb5 ("smb: client: fix missing timestamp updates with O_TRUNC")
Fixes 7a06d3b816d7 ("smb/client: emulate small EOF-extending mode 0 fallocate ranges")
Cc David Howells <[email protected]>
Cc Paulo Alcantara <[email protected]>
Cc Huiwen He <[email protected]>
---
 fs/smb/client/inode.c | 1 +
 1 file changed, 1 insertion(+)
fs/smb/client/inode.c +1 -0
index 453a5df20f8cc..b67b316538b83 100644
@@ -2966,6 +2966,7 @@ void cifs_setsize(struct inode *inode, loff_t offset)
 	cifs_i->time = 0;
 	truncate_pagecache(inode, offset);
 	netfs_wait_for_outstanding_io(inode);
+	fscache_resize_cookie(cifs_inode_cookie(inode), offset);
 }
 
 static int
Signature · 1 line
2.53.0