FAILED: patch "[PATCH] cifs: add cifs_resize_file_locked() to guard" failed to apply to 6.12-stable tree
Subsystems (3)
[email protected]
maintainerThe 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 32a7af68df7361fe7cf153cf36124d04b94aec00
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026090359-ahoy-outage-a083@gregkh' --subject-prefix 'PATCH 6.12.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 32a7af68df7361fe7cf153cf36124d04b94aec00 Mon Sep 17 00:00:00 2001
From: Frank Sorenson <[email protected]>
Date: Fri, 31 Jul 2026 12:12:29 -0500
Subject: [PATCH] cifs: add cifs_resize_file_locked() to guard
fscache_resize_cookie() under i_rwsem
cifs_setsize() calls fscache_resize_cookie() without holding i_rwsem. When the fscache cookie is active (FSCACHE_COOKIE_IS_CACHING is set), fscache_resize_cookie() performs a real resize that requires i_rwsem held exclusively. If another file descriptor has the same inode open, fscache_use_cookie() was already called from that cifs_open(), making the cookie active. In that case, calling cifs_setsize() from cifs_do_truncate() (invoked from cifs_open() without i_rwsem) races against concurrent fscache I/O.
Strip fscache_resize_cookie() from cifs_setsize(), making it a pure size/page-cache helper. Add cifs_resize_file_locked() for callers that already hold i_rwsem: it calls netfs_resize_file() and cifs_setsize(), then temporarily activates the cookie with fscache_use_cookie() to perform the resize under the lock, then deactivates it with cifs_fscache_unuse_inode_cookie(). Using fscache_use_cookie() before the resize ensures correctness whether or not another fd already holds the cookie active.
Switch cifs_file_set_size(), smb2_duplicate_extents(), and both size- extension branches of smb3_simple_falloc() to the new wrapper; those paths already hold i_rwsem via VFS setattr, lock_two_nondirectories(), or cifs_fallocate() respectively. cifs_do_truncate() continues to call cifs_setsize() followed by cifs_invalidate_cache(), since it runs without i_rwsem.
fs/smb/client/cifsfs.h +1 -0
@@ -147,6 +147,7 @@ ssize_t cifs_file_copychunk_range(unsigned int xid, struct file *src_file,long cifs_ioctl (struct file *filep,unsigned int command,unsigned long arg);void cifs_setsize (struct inode *inode,loff_t offset); +void cifs_resize_file_locked (struct inode *inode,loff_t offset);struct fs_context ;struct smb3_fs_context ;
fs/smb/client/inode.c +19 -5
@@ -3059,7 +3059,23 @@ 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); +} + +void cifs_resize_file_locked (struct inode *inode,loff_t offset) +{ +struct fscache_cookie *cookie =cifs_inode_cookie (inode); + +lockdep_assert_held_write (&inode->i_rwsem); + +netfs_resize_file (netfs_inode (inode), offset, true); +cifs_setsize (inode, offset); + +if (!cookie) +return ; + +fscache_use_cookie (cookie, true); +fscache_resize_cookie (cookie, offset); +cifs_fscache_unuse_inode_cookie (inode, true); } int cifs_file_set_size(const unsigned int xid, struct dentry *dentry,
@@ -3125,10 +3141,8 @@ int cifs_file_set_size(const unsigned int xid, struct dentry *dentry,cifs_put_tlink (tlink); set_size_out: -if (rc ==0 ) { -netfs_resize_file (&cifsInode->netfs, size, true); -cifs_setsize (inode, size); - } +if (rc ==0 ) +cifs_resize_file_locked (inode, size);return rc; }
fs/smb/client/smb2ops.c +3 -6
@@ -2222,8 +2222,7 @@ smb2_duplicate_extents(const unsigned int xid, rc =smb2_set_file_size (xid, tcon, trgtfile, dest_off + len, false);if (rc) goto duplicate_extents_out; -netfs_resize_file (netfs_inode (inode), dest_off + len, true); -cifs_setsize (inode, dest_off + len); +cifs_resize_file_locked (inode, dest_off + len); } rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid, trgtfile->fid.volatile_fid,
@@ -3776,8 +3775,7 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon, } new_eof = off + len; -netfs_resize_file (&cifsi->netfs, new_eof, true); -cifs_setsize (inode, new_eof); +cifs_resize_file_locked (inode, new_eof); qrc = SMB2_query_info(xid, tcon, cfile->fid.persistent_fid,
@@ -3825,8 +3823,7 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,if (rc) goto out; -netfs_resize_file (&cifsi->netfs, new_eof, true); -cifs_setsize (inode, new_eof); +cifs_resize_file_locked (inode, new_eof); qrc = SMB2_query_info(xid, tcon, cfile->fid.persistent_fid,
Sasha Levin
maintainerPATCH 1/2 smb: client: fix generic/694 due to wrong ->i_blocks
From: Paulo Alcantara <[email protected]>
[ Upstream commit 23b5df09c27aec13962b30d32a4167ebdd043f8e ]
When updating ->i_size, make sure to always update ->i_blocks as well until we query new allocation size from the server.
generic/694 was failing because smb3_simple_falloc() was missing the update of ->i_blocks after calling cifs_setsize(). So, fix this by updating ->i_blocks directly in cifs_setsize(), so all places that call it doesn't need to worry about updating ->i_blocks later.
[ sashal: Reduced backport -- upstream 23b5df09c27ae touches 4 file(s), this
backport carries 4. Not backported here:
fs/smb/client/file.c
This note is generated from the file lists only; see the resolution record for the reasoning. ]
Stable-dep-of: 32a7af68df73 ("cifs: add cifs_resize_file_locked() to guard fscache_resize_cookie() under i_rwsem")
--- fs/smb/client/cifsfs.h | 6 +- fs/smb/client/cifsglob.h | 6 ++ fs/smb/client/inode.c | 28 ++++------ fs/smb/client/smb2ops.c | 116 ++++++++++++++++++++++++++++----------- 4 files changed, 104 insertions(+), 52 deletions(-)
fs/smb/client/cifsfs.h +3 -3
@@ -128,14 +128,14 @@ extern ssize_t cifs_listxattr(struct dentry *, char *, size_t);# define cifs_listxattr NULL#endif +extern int cifs_truncate_page (struct address_space *mapping,loff_t from);extern ssize_t cifs_file_copychunk_range (unsigned int xid,struct file *src_file,loff_t off,struct file *dst_file,loff_t destoff,size_t len,unsigned int flags); -extern long cifs_ioctl (struct file *filep,unsigned int cmd,unsigned long arg); -extern void cifs_setsize (struct inode *inode,loff_t offset); -extern int cifs_truncate_page (struct address_space *mapping,loff_t from); +long cifs_ioctl (struct file *filep,unsigned int command,unsigned long arg); +void cifs_setsize (struct inode *inode,loff_t offset);struct smb3_fs_context ; extern struct dentry *cifs_smb3_do_mount(struct file_system_type *fs_type,
fs/smb/client/cifsglob.h +6 -0
@@ -2284,4 +2284,10 @@ static inline int cifs_open_create_options(unsigned int oflags, int opts) return opts; } +/* +* The number of blocks is not related to (i_size / i_blksize), but instead +* 512 byte (2**9) size is required for calculating num blocks. +*/ +#define CIFS_INO_BLOCKS (size) DIV_ROUND_UP_ULL((u64)(size), 512) +#endif /* _CIFS_GLOB_H */
fs/smb/client/inode.c +11 -17
@@ -235,13 +235,7 @@ cifs_fattr_to_inode(struct inode *inode, struct cifs_fattr *fattr,*/ if (is_size_safe_to_change (cifs_i, fattr->cf_eof, from_readdir)) {i_size_write (inode, fattr->cf_eof); - -/* -* i_blocks is not related to (i_size / i_blksize), -* but instead 512 byte (2**9) size is required for -* calculating num blocks. -*/ - inode->i_blocks = (512 -1 + fattr->cf_bytes) >>9 ; + inode->i_blocks =CIFS_INO_BLOCKS (fattr->cf_bytes); }if (S_ISLNK (fattr->cf_mode) && fattr->cf_symlink_target) {
@@ -2960,6 +2954,11 @@ void cifs_setsize(struct inode *inode, loff_t offset)spin_lock (&inode->i_lock);i_size_write (inode, offset); +/* +* Until we can query the server for actual allocation size, +* this is best estimate we have for blocks allocated for a file. +*/ + inode->i_blocks =CIFS_INO_BLOCKS (offset);spin_unlock (&inode->i_lock);/* Cached inode must be refreshed on truncate */
@@ -2974,6 +2973,7 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, unsigned int xid, const char *full_path, struct dentry *dentry) { int rc; +loff_t size = attrs->ia_size;struct cifsFileInfo *open_file;struct cifsInodeInfo *cifsInode =CIFS_I (inode);struct cifs_sb_info *cifs_sb =CIFS_SB (inode->i_sb);
@@ -3032,17 +3032,11 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs, set_size_out:if (rc ==0 ) { -netfs_resize_file (&cifsInode->netfs, attrs->ia_size, true); -cifs_setsize (inode, attrs->ia_size); -/* -* i_blocks is not related to (i_size / i_blksize), but instead -* 512 byte (2**9) size is required for calculating num blocks. -* Until we can query the server for actual allocation size, -* this is best estimate we have for blocks allocated for a file -* Number of blocks must be rounded up so size 1 is not 0 blocks -*/ - inode->i_blocks = (512 -1 + attrs->ia_size) >>9 ; +netfs_resize_file (&cifsInode->netfs, size, true); +cifs_setsize (inode, size); + } +if (rc ==0 ) {/* * The man page of truncate says if the size changed, * then the st_ctime and st_mtime fields for the file
fs/smb/client/smb2ops.c +84 -32
199 lines not on this page · raw message
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 cifs: add cifs_resize_file_locked() to guard fscache_resize_cookie() under i_rwsem
From: Frank Sorenson <[email protected]>
[ Upstream commit 32a7af68df7361fe7cf153cf36124d04b94aec00 ]
cifs_setsize() calls fscache_resize_cookie() without holding i_rwsem. When the fscache cookie is active (FSCACHE_COOKIE_IS_CACHING is set), fscache_resize_cookie() performs a real resize that requires i_rwsem held exclusively. If another file descriptor has the same inode open, fscache_use_cookie() was already called from that cifs_open(), making the cookie active. In that case, calling cifs_setsize() from cifs_do_truncate() (invoked from cifs_open() without i_rwsem) races against concurrent fscache I/O.
Strip fscache_resize_cookie() from cifs_setsize(), making it a pure size/page-cache helper. Add cifs_resize_file_locked() for callers that already hold i_rwsem: it calls netfs_resize_file() and cifs_setsize(), then temporarily activates the cookie with fscache_use_cookie() to perform the resize under the lock, then deactivates it with cifs_fscache_unuse_inode_cookie(). Using fscache_use_cookie() before the resize ensures correctness whether or not another fd already holds the cookie active.
Switch cifs_file_set_size(), smb2_duplicate_extents(), and both size- extension branches of smb3_simple_falloc() to the new wrapper; those paths already hold i_rwsem via VFS setattr, lock_two_nondirectories(), or cifs_fallocate() respectively. cifs_do_truncate() continues to call cifs_setsize() followed by cifs_invalidate_cache(), since it runs without i_rwsem.
--- fs/smb/client/cifsfs.h | 1 + fs/smb/client/inode.c | 24 +++++++++++++++++++----- fs/smb/client/smb2ops.c | 9 +++------ 3 files changed, 23 insertions(+), 11 deletions(-)
fs/smb/client/cifsfs.h +1 -0
@@ -136,6 +136,7 @@ extern ssize_t cifs_file_copychunk_range(unsigned int xid,long cifs_ioctl (struct file *filep,unsigned int command,unsigned long arg);void cifs_setsize (struct inode *inode,loff_t offset); +void cifs_resize_file_locked (struct inode *inode,loff_t offset);struct smb3_fs_context ; extern struct dentry *cifs_smb3_do_mount(struct file_system_type *fs_type,
fs/smb/client/inode.c +19 -5
@@ -2965,7 +2965,23 @@ 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); +} + +void cifs_resize_file_locked (struct inode *inode,loff_t offset) +{ +struct fscache_cookie *cookie =cifs_inode_cookie (inode); + +lockdep_assert_held_write (&inode->i_rwsem); + +netfs_resize_file (netfs_inode (inode), offset, true); +cifs_setsize (inode, offset); + +if (!cookie) +return ; + +fscache_use_cookie (cookie, true); +fscache_resize_cookie (cookie, offset); +cifs_fscache_unuse_inode_cookie (inode, true); } static int
@@ -3031,10 +3047,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,cifs_put_tlink (tlink); set_size_out: -if (rc ==0 ) { -netfs_resize_file (&cifsInode->netfs, size, true); -cifs_setsize (inode, size); - } +if (rc ==0 ) +cifs_resize_file_locked (inode, size);if (rc ==0 ) {/*
fs/smb/client/smb2ops.c +3 -6
@@ -2114,8 +2114,7 @@ smb2_duplicate_extents(const unsigned int xid, rc =smb2_set_file_size (xid, tcon, trgtfile, dest_off + len, false);if (rc) goto duplicate_extents_out; -netfs_resize_file (netfs_inode (inode), dest_off + len, true); -cifs_setsize (inode, dest_off + len); +cifs_resize_file_locked (inode, dest_off + len); } rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid, trgtfile->fid.volatile_fid,
@@ -3624,8 +3623,7 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon, } new_eof = off + len; -netfs_resize_file (&cifsi->netfs, new_eof, true); -cifs_setsize (inode, new_eof); +cifs_resize_file_locked (inode, new_eof); qrc = SMB2_query_info(xid, tcon, cfile->fid.persistent_fid,
@@ -3650,8 +3648,7 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,if (rc) goto out; -netfs_resize_file (&cifsi->netfs, new_eof, true); -cifs_setsize (inode, new_eof); +cifs_resize_file_locked (inode, new_eof); qrc = SMB2_query_info(xid, tcon, cfile->fid.persistent_fid,
Signature · 1 line
2.53.0
Re: [PATCH 6.12.y 2/2] cifs: add cifs_resize_file_locked() to guard fscache_resize_cookie() under i_rwsem
Quoted 135 lines · Sasha Levin
From: Frank Sorenson <[email protected]>
[ Upstream commit
32a7af68df7361fe7cf153cf36124d04b94aec00]
cifs_setsize()callsfscache_resize_cookie()without holdingi_rwsem. When the fscache cookie is active (FSCACHE_COOKIE_IS_CACHINGis set),fscache_resize_cookie()performs a real resize that requiresi_rwsemheld exclusively. If another file descriptor has the same inode open,fscache_use_cookie()was already called from thatcifs_open(), making the cookie active. In that case, callingcifs_setsize()fromcifs_do_truncate()(invoked fromcifs_open()withouti_rwsem) races against concurrent fscache I/O.Strip
fscache_resize_cookie()fromcifs_setsize(), making it a pure size/page-cache helper. Addcifs_resize_file_locked()for callers that already holdi_rwsem: it callsnetfs_resize_file()andcifs_setsize(), then temporarily activates the cookie withfscache_use_cookie()to perform the resize under the lock, then deactivates it withcifs_fscache_unuse_inode_cookie(). Usingfscache_use_cookie()before the resize ensures correctness whether or not another fd already holds the cookie active.Switch
cifs_file_set_size(),smb2_duplicate_extents(), and both size- extension branches ofsmb3_simple_falloc()to the new wrapper; those paths already holdi_rwsemvia VFS setattr,lock_two_nondirectories(), orcifs_fallocate()respectively.cifs_do_truncate()continues to callcifs_setsize()followed bycifs_invalidate_cache(), since it runs withouti_rwsem.Fixes fa724e235cfd ("cifs: add fscache_resize_cookie() to cifs_setsize()")Cc David Howells <[email protected]>Cc Paulo Alcantara <[email protected]>Signed-off-by Frank Sorenson <[email protected]>Signed-off-by Namjae Jeon <[email protected]>Signed-off-by Paulo Alcantara <[email protected]>Signed-off-by Sasha Levin <[email protected]>--- fs/smb/client/cifsfs.h | 1 + fs/smb/client/inode.c | 24 +++++++++++++++++++----- fs/smb/client/smb2ops.c | 9 +++------ 3 files changed, 23 insertions(+), 11 deletions(-)fs/smb/client/cifsfs.h +1
-0@@ -136,6 +136,7 @@ extern ssize_t cifs_file_copychunk_range(unsigned int xid,long cifs_ioctl (struct file *filep,unsigned int command,unsigned long arg);void cifs_setsize (struct inode *inode,loff_t offset); +void cifs_resize_file_locked (struct inode *inode,loff_t offset);struct smb3_fs_context ; extern struct dentry *cifs_smb3_do_mount(struct file_system_type *fs_type,fs/smb/client/inode.c +19
-5@@ -2965,7 +2965,23 @@ 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); +} + +void cifs_resize_file_locked (struct inode *inode,loff_t offset) +{ +struct fscache_cookie *cookie =cifs_inode_cookie (inode); + +lockdep_assert_held_write (&inode->i_rwsem); + +netfs_resize_file (netfs_inode (inode), offset, true); +cifs_setsize (inode, offset); + +if (!cookie) +return ; + +fscache_use_cookie (cookie, true); +fscache_resize_cookie (cookie, offset); +cifs_fscache_unuse_inode_cookie (inode, true); } static int@@ -3031,10 +3047,8 @@ cifs_set_file_size(struct inode *inode, struct iattr *attrs,cifs_put_tlink (tlink); set_size_out: -if (rc ==0 ) { -netfs_resize_file (&cifsInode->netfs, size, true); -cifs_setsize (inode, size); - } +if (rc ==0 ) +cifs_resize_file_locked (inode, size);if (rc ==0 ) {/* fs/smb/client/smb2ops.c +3
-6@@ -2114,8 +2114,7 @@ smb2_duplicate_extents(const unsigned int xid, rc =smb2_set_file_size (xid, tcon, trgtfile, dest_off + len, false);if (rc) goto duplicate_extents_out; -netfs_resize_file (netfs_inode (inode), dest_off + len, true); -cifs_setsize (inode, dest_off + len); +cifs_resize_file_locked (inode, dest_off + len); } rc = SMB2_ioctl(xid, tcon, trgtfile->fid.persistent_fid, trgtfile->fid.volatile_fid,@@ -3624,8 +3623,7 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon, } new_eof = off + len; -netfs_resize_file (&cifsi->netfs, new_eof, true); -cifs_setsize (inode, new_eof); +cifs_resize_file_locked (inode, new_eof); qrc = SMB2_query_info(xid, tcon, cfile->fid.persistent_fid,@@ -3650,8 +3648,7 @@ static long smb3_simple_falloc(struct file *file, struct cifs_tcon *tcon,if (rc) goto out; -netfs_resize_file (&cifsi->netfs, new_eof, true); -cifs_setsize (inode, new_eof); +cifs_resize_file_locked (inode, new_eof); qrc = SMB2_query_info(xid, tcon, cfile->fid.persistent_fid,Signature · 1 line
2.53.0
Does not apply