FAILED: patch "[PATCH] smb/client: send lease break ACKs thru correct session for" failed to apply to 6.1-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.1-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.1.y
git checkout FETCH_HEAD
git cherry-pick -x ebc5660132ddd244b57f03ed324922013a3d7363
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026092353-natural-vicinity-cd4b@gregkh' --subject-prefix 'PATCH 6.1.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From ebc5660132ddd244b57f03ed324922013a3d7363 Mon Sep 17 00:00:00 2001
From: April Cardenas <[email protected]>
Date: Thu, 10 Sep 2026 00:16:49 -0500
Subject: [PATCH] smb/client: send lease break ACKs thru correct session for
multiuser mounts
Currently, when cifs_oplock_break handles a break request from the server it searches for the appropriate tlink to handle the request but incorrectly uses the current fsuid as the search key, eventually causing read errors for users with multiuser mounts on NetApp. Fix this by using the tlink from the cfile struct instead to respond through the correct session.
As breaks are handled in a worker thread, the current fsuid isn't guaranteed to match the session that the break is intended for. This means that cifs_sb_tlink may search the rbtree using the wrong fsuid, and return a tlink with an incorrect session than
the lease break was intended for. As a result, the breaks
may be ACKed through an incorrect session.
While it seems that Samba/Windows Servers 2016-2025 ignore this as long as the lease key is correct, we ran into a case where if you're using NetApp ONTAP or Azure NetApp Files they will reject the ACK and return STATUS_LOCK_NOT_GRANTED errors on any future read requests a user may initiate through their still held open file handle, and the server will eventually close the file.
In the dmesg logs, the user may see errors like these:
CIFS: Status code returned 0xc0000128 STATUS_FILE_CLOSED
CIFS: VFS: Send error in read = -9
With a multiuser mount using NetApp, this issue is really easy for users to hit on a wide variety of kernel versions by attempting to copy a file from the share
to the local machine through GNOME Files/Nautilus.
This copy will always result in Nautilus throwing
a Bad File Descriptor error to the user and fail. With this fix, you can copy files through Nautilus without issue.
Quoted 1 line
From looking at the traces, it seems that glib will
open the file first, and call listxattr before actually attempting to copy the file data. The listxattr call always triggers a break, causing the copy to fail.
The proposed fix returns to the way the client grabbed the tlink before commit e8f5f849ffce2 ("cifs: fix potential oops in cifs_oplock_break").
The bulk of that commit (checking for list empty) remains untouched, and I think the change to using cifs_sb_tlink was intended to avoid a NULL/ERR deference on the tlink as well as update the reference count.
I believe this fix should preserve those safety properties, but of course I'd appreciate any corrections here.
fs/smb/client/file.c +2 -2
@@ -3354,8 +3354,8 @@ void cifs_oplock_break(struct work_struct *work)wait_on_bit (&cinode->flags,CIFS_INODE_PENDING_WRITERS ,TASK_UNINTERRUPTIBLE ); - tlink =cifs_sb_tlink (cifs_sb); -if (IS_ERR (tlink)) { + tlink =cifs_get_tlink (cfile->tlink); +if (IS_ERR_OR_NULL (tlink)) {/* drop the reference taken when the break was queued */ _cifsFileInfo_put (cfile, false/* do not wait for ourself */ , false); goto out;
Sasha Levin
maintainerPATCH 1/2 smb: client: avoid leaking refcount when cifs_sb_tlink() fails
From: Bjoern Doebel <[email protected]>
[ Upstream commit 23b26f4408ac3f35a482d2e5cf6fc865d4201b71 ]
cifs_oplock_break() takes over the reference that cifs_queue_oplock_break() acquired when it queued the work, and drops it with _cifsFileInfo_put() once the break has been processed.
Only in setups with "-o multiuser", cifs_sb_tlink() may fail, at which point cifs_oplock_break() returns without putting the file reference, mirroring the reference leak we already fixed in the companion patch to cifs_queue_oplock_break().
This would trigger a crash due to busy inodes on the next unmount:
BUG: Dentry ... still in use (1) [unmount of cifs cifs] VFS: Busy inodes after unmount of cifs (cifs)
Drop the reference on that path as well. Doing so before the out label mirrors the normal path, which also puts the reference before cifs_done_oplock_break().
Found by Sashiko code review. The failure path was not exercised at runtime.
Stable-dep-of: ebc5660132dd ("smb/client: send lease break ACKs thru correct session for multiuser mounts")
--- fs/smb/client/file.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
fs/smb/client/file.c +4 -1
@@ -5188,8 +5188,11 @@ void cifs_oplock_break(struct work_struct *work) TASK_UNINTERRUPTIBLE); tlink =cifs_sb_tlink (cifs_sb); -if (IS_ERR (tlink)) +if (IS_ERR (tlink)) { +/* drop the reference taken when the break was queued */ +_cifsFileInfo_put (cfile, false/* do not wait for ourself */ , false); goto out; + } tcon =tlink_tcon (tlink); server = tcon->ses->server;
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 smb/client: send lease break ACKs thru correct session for multiuser mounts
From: April Cardenas <[email protected]>
[ Upstream commit ebc5660132ddd244b57f03ed324922013a3d7363 ]
Currently, when cifs_oplock_break handles a break request from the server it searches for the appropriate tlink to handle the request but incorrectly uses the current fsuid as the search key, eventually causing read errors for users with multiuser mounts on NetApp. Fix this by using the tlink from the cfile struct instead to respond through the correct session.
As breaks are handled in a worker thread, the current fsuid isn't guaranteed to match the session that the break is intended for. This means that cifs_sb_tlink may search the rbtree using the wrong fsuid, and return a tlink with an incorrect session than
the lease break was intended for. As a result, the breaks
may be ACKed through an incorrect session.
While it seems that Samba/Windows Servers 2016-2025 ignore this as long as the lease key is correct, we ran into a case where if you're using NetApp ONTAP or Azure NetApp Files they will reject the ACK and return STATUS_LOCK_NOT_GRANTED errors on any future read requests a user may initiate through their still held open file handle, and the server will eventually close the file.
In the dmesg logs, the user may see errors like these:
CIFS: Status code returned 0xc0000128 STATUS_FILE_CLOSED
CIFS: VFS: Send error in read = -9
With a multiuser mount using NetApp, this issue is really easy for users to hit on a wide variety of kernel versions by attempting to copy a file from the share
to the local machine through GNOME Files/Nautilus.
This copy will always result in Nautilus throwing
a Bad File Descriptor error to the user and fail. With this fix, you can copy files through Nautilus without issue.
Quoted 1 line
From looking at the traces, it seems that glib will
open the file first, and call listxattr before actually attempting to copy the file data. The listxattr call always triggers a break, causing the copy to fail.
The proposed fix returns to the way the client grabbed the tlink before commit e8f5f849ffce2 ("cifs: fix potential oops in cifs_oplock_break").
The bulk of that commit (checking for list empty) remains untouched, and I think the change to using cifs_sb_tlink was intended to avoid a NULL/ERR deference on the tlink as well as update the reference count.
I believe this fix should preserve those safety properties, but of course I'd appreciate any corrections here.
--- fs/smb/client/file.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
fs/smb/client/file.c +2 -4
@@ -5173,8 +5173,6 @@ void cifs_oplock_break(struct work_struct *work) struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo, oplock_break);struct inode *inode =d_inode (cfile->dentry); -struct super_block *sb = inode->i_sb; -struct cifs_sb_info *cifs_sb =CIFS_SB (sb);struct cifsInodeInfo *cinode =CIFS_I (inode);struct cifs_tcon *tcon;struct TCP_Server_Info *server;
@@ -5187,8 +5185,8 @@ void cifs_oplock_break(struct work_struct *work)wait_on_bit (&cinode->flags,CIFS_INODE_PENDING_WRITERS ,TASK_UNINTERRUPTIBLE ); - tlink =cifs_sb_tlink (cifs_sb); -if (IS_ERR (tlink)) { + tlink =cifs_get_tlink (cfile->tlink); +if (IS_ERR_OR_NULL (tlink)) {/* drop the reference taken when the break was queued */ _cifsFileInfo_put (cfile, false/* do not wait for ourself */ , false); goto out;
Signature · 1 line
2.53.0