FAILED: patch "[PATCH] cifs: add cifs_resize_file_locked() to guard" failed to apply to 6.18-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.18-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.18.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 '2026090358-afar-boss-f2c3@gregkh' --subject-prefix 'PATCH 6.18.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/4 smb: move some definitions from common/smb2pdu.h into common/fscc.h
From: ZhangGuoDong <[email protected]>
[ Upstream commit a5e581093b1d9321cbb627dd8c209d0d4e0a988a ]
These definitions are specified in MS-FSCC, so move them into fscc.h.
Only add some documentation references, no other changes.
The original header relocation is not applicable to this stable tree: fscc.h is absent and the relevant definitions are already kept in smb2pdu.h.
For this stable-only dependency adaptation, prepare the existing fallocate paths for EOF-extending ranges and allocation metadata refresh, and align the cifs declarations with the target patch context. This lets the fscache resize locking fix apply without adding its new helper in the dependency.
[ sashal: Reduced backport -- upstream a5e581093b1d9 touches 2 file(s), this
backport carries 2. Not backported here:
fs/smb/common/fscc.h
fs/smb/common/smb2pdu.h
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 | 5 ++- fs/smb/client/smb2ops.c | 89 +++++++++++++++++++++++++++++++++++------ 2 files changed, 80 insertions(+), 14 deletions(-)
fs/smb/client/cifsfs.h +3 -2
@@ -133,9 +133,10 @@ extern ssize_t cifs_file_copychunk_range(unsigned int xid, 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); +long cifs_ioctl (struct file *filep,unsigned int command,unsigned long arg); +void cifs_setsize (struct inode *inode,loff_t offset); +struct fs_context ;struct smb3_fs_context ;extern struct dentry *cifs_smb3_do_mount (struct file_system_type *fs_type,int flags,struct smb3_fs_context *ctx);
fs/smb/client/smb2ops.c +77 -12
140 lines not on this page · raw message
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/4 smb/client: reduce fallocate zero buffer allocation
From: Huiwen He <[email protected]>
[ Upstream commit 9e4ec3be67af41ab859302d7109b34976efd9258 ]
The fallocate emulation allocates a 1 MiB zero-filled buffer even though each SMB2_write request is limited to SMB2_MAX_BUFFER_SIZE, which is 64 KiB. A high-order 1 MiB allocation is more likely to fail on a fragmented system.
Allocate only the smaller of the requested range and SMB2_MAX_BUFFER_SIZE, and reuse that zero-filled buffer for every write request. Also reject a successful write that makes no progress to avoid looping indefinitely.
This reduces the contiguous allocation required by fallocate emulation without changing the written data or range semantics.
Stable-dep-of: 32a7af68df73 ("cifs: add cifs_resize_file_locked() to guard fscache_resize_cookie() under i_rwsem")
--- fs/smb/client/smb2ops.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
fs/smb/client/smb2ops.c +4 -3
@@ -3508,7 +3508,7 @@ static int smb3_simple_fallocate_write_range(unsigned int xid, char *buf) {struct cifs_io_parms io_parms = {0 }; -int nbytes; +unsigned int nbytes;int rc =0 ;struct kvec iov[2 ];
@@ -3529,9 +3529,10 @@ static int smb3_simple_fallocate_write_range(unsigned int xid, rc =SMB2_write (xid, &io_parms, &nbytes, iov,1 );if (rc)break ; +if (!nbytes) +return -EIO ;if (nbytes > len)return -EINVAL ; - buf += nbytes; off += nbytes; len -= nbytes; }
@@ -3551,7 +3552,7 @@ static int smb3_simple_fallocate_range(unsigned int xid,loff_t l;int rc; - buf =kvzalloc (1024 *1024 ,GFP_KERNEL ); + buf =kvzalloc (min_t (loff_t, len,SMB2_MAX_BUFFER_SIZE ),GFP_KERNEL );if (buf ==NULL ) { rc = -ENOMEM ; goto out;
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 3/4 smb/client: emulate small EOF-extending mode 0 fallocate ranges
In reply to Sasha LevinFrom: Huiwen He <[email protected]>
[ Upstream commit 7a06d3b816d73448b4e38b83d65049f090b7b201 ]
When a mode 0 fallocate extends EOF from 1G to 2G + 1M, the client currently sends SetEOF for 2G + 1M. This can make fallocate return success without allocating the requested range, or allocate extra space before that range.
For example, on a fresh file:
xfs_io -f \
-c "falloc 0 1G" \
-c "falloc 2G 1M" \
-c "truncate 3G" testThe second fallocate should allocate [2G, 2G + 1M), leaving [1G, 2G) as a hole.
Before this change, the result depended on the server allocation policy. With Samba "strict allocate = no", SetEOF could return success without allocating [2G, 2G + 1M). With "strict allocate = yes":
# filefrag -v test
[0, 1G) allocated
[1G, 2G) allocated unexpectedly
[2G, 2G + 1M) allocatedSMB cannot allocate that arbitrary range, so write zeroes to small EOF-extending ranges instead. Limit this to 1 MiB to bound the client-side I/O cost.
With "strict allocate = no", the requested range [2G, 2G + 1M) is allocated by the writes. With "strict allocate = yes":
# filefrag -v test
[0, 1G) allocated
[1G, 2G) hole
[2G, 2G + 1M) allocatedThis fixes the small EOF-extending range case exercised by generic/213.
Stable-dep-of: 32a7af68df73 ("cifs: add cifs_resize_file_locked() to guard fscache_resize_cookie() under i_rwsem")
--- fs/smb/client/smb2ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/smb/client/smb2ops.c +1 -1
@@ -3553,7 +3553,7 @@ static int smb3_simple_fallocate_range(unsigned int xid,int rc; buf =kvzalloc (min_t (loff_t, len,SMB2_MAX_BUFFER_SIZE ),GFP_KERNEL ); -if (buf ==NULL ) { +if (!buf) { rc = -ENOMEM ; goto out; }
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 4/4 cifs: add cifs_resize_file_locked() to guard fscache_resize_cookie() under i_rwsem
In reply to Sasha LevinFrom: 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
@@ -135,6 +135,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 fs_context ;struct smb3_fs_context ;
fs/smb/client/inode.c +19 -5
@@ -3039,7 +3039,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,
@@ -3105,10 +3121,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
@@ -2197,8 +2197,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,
@@ -3702,8 +3701,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,
@@ -3728,8 +3726,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