From: Greg Kroah-Hartman Date: Sat, 27 Jan 2024 01:51:36 +0000 (-0800) Subject: 6.6-stable patches X-Git-Tag: v6.1.76~70 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7239b85adef23e38b8ec058a149d6311de5b4e49;p=thirdparty%2Fkernel%2Fstable-queue.git 6.6-stable patches added patches: cifs-after-disabling-multichannel-mark-tcon-for-reconnect.patch cifs-fix-a-pending-undercount-of-srv_count.patch cifs-fix-lock-ordering-while-disabling-multichannel.patch --- diff --git a/queue-6.6/cifs-after-disabling-multichannel-mark-tcon-for-reconnect.patch b/queue-6.6/cifs-after-disabling-multichannel-mark-tcon-for-reconnect.patch new file mode 100644 index 00000000000..10724a837c6 --- /dev/null +++ b/queue-6.6/cifs-after-disabling-multichannel-mark-tcon-for-reconnect.patch @@ -0,0 +1,61 @@ +From 27e1fd343f80168ff456785c2443136b6b7ca3cc Mon Sep 17 00:00:00 2001 +From: Shyam Prasad N +Date: Fri, 29 Dec 2023 11:30:07 +0000 +Subject: cifs: after disabling multichannel, mark tcon for reconnect + +From: Shyam Prasad N + +commit 27e1fd343f80168ff456785c2443136b6b7ca3cc upstream. + +Once the server disables multichannel for an active multichannel +session, on the following reconnect, the client would reduce +the number of channels to 1. However, it could be the case that +the tree connect was active on one of these disabled channels. +This results in an unrecoverable state. + +This change fixes that by making sure that whenever a channel +is being terminated, the session and tcon are marked for +reconnect too. This could mean a few redundant tree connect +calls to the server, but considering that this is not a frequent +event, we should be okay. + +Fixes: ee1d21794e55 ("cifs: handle when server stops supporting multichannel") +Signed-off-by: Shyam Prasad N +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/client/connect.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +--- a/fs/smb/client/connect.c ++++ b/fs/smb/client/connect.c +@@ -212,17 +212,21 @@ cifs_mark_tcp_ses_conns_for_reconnect(st + /* If server is a channel, select the primary channel */ + pserver = SERVER_IS_CHAN(server) ? server->primary_server : server; + ++ /* ++ * if the server has been marked for termination, there is a ++ * chance that the remaining channels all need reconnect. To be ++ * on the safer side, mark the session and trees for reconnect ++ * for this scenario. This might cause a few redundant session ++ * setup and tree connect requests, but it is better than not doing ++ * a tree connect when needed, and all following requests failing ++ */ ++ if (server->terminate) { ++ mark_smb_session = true; ++ server = pserver; ++ } + + spin_lock(&cifs_tcp_ses_lock); + list_for_each_entry_safe(ses, nses, &pserver->smb_ses_list, smb_ses_list) { +- /* +- * if channel has been marked for termination, nothing to do +- * for the channel. in fact, we cannot find the channel for the +- * server. So safe to exit here +- */ +- if (server->terminate) +- break; +- + /* check if iface is still active */ + spin_lock(&ses->chan_lock); + if (!cifs_chan_is_iface_active(ses, server)) { diff --git a/queue-6.6/cifs-fix-a-pending-undercount-of-srv_count.patch b/queue-6.6/cifs-fix-a-pending-undercount-of-srv_count.patch new file mode 100644 index 00000000000..82f7921f3bd --- /dev/null +++ b/queue-6.6/cifs-fix-a-pending-undercount-of-srv_count.patch @@ -0,0 +1,87 @@ +From f30bbc38704e279c06d073ecb18fea376791ecab Mon Sep 17 00:00:00 2001 +From: Shyam Prasad N +Date: Fri, 15 Dec 2023 17:16:55 +0000 +Subject: cifs: fix a pending undercount of srv_count + +From: Shyam Prasad N + +commit f30bbc38704e279c06d073ecb18fea376791ecab upstream. + +The following commit reverted the changes to ref count +the server struct while scheduling a reconnect work: +823342524868 Revert "cifs: reconnect work should have reference on server struct" + +However, a following change also introduced scheduling +of reconnect work, and assumed ref counting. This change +fixes that as well. + +Fixes umount problems like: + +[73496.157838] CPU: 5 PID: 1321389 Comm: umount Tainted: G W OE 6.7.0-060700rc6-generic #202312172332 +[73496.157841] Hardware name: LENOVO 20MAS08500/20MAS08500, BIOS N2CET67W (1.50 ) 12/15/2022 +[73496.157843] RIP: 0010:cifs_put_tcp_session+0x17d/0x190 [cifs] +[73496.157906] Code: 5d 31 c0 31 d2 31 f6 31 ff c3 cc cc cc cc e8 4a 6e 14 e6 e9 f6 fe ff ff be 03 00 00 00 48 89 d7 e8 78 26 b3 e5 e9 e4 fe ff ff <0f> 0b e9 b1 fe ff ff 66 66 2e 0f 1f 84 00 00 00 00 00 90 90 90 90 +[73496.157908] RSP: 0018:ffffc90003bcbcb8 EFLAGS: 00010286 +[73496.157911] RAX: 00000000ffffffff RBX: ffff8885830fa800 RCX: 0000000000000000 +[73496.157913] RDX: 0000000000000000 RSI: 0000000000000000 RDI: 0000000000000000 +[73496.157915] RBP: ffffc90003bcbcc8 R08: 0000000000000000 R09: 0000000000000000 +[73496.157917] R10: 0000000000000000 R11: 0000000000000000 R12: 0000000000000000 +[73496.157918] R13: ffff8887d56ba800 R14: 00000000ffffffff R15: ffff8885830fa800 +[73496.157920] FS: 00007f1ff0e33800(0000) GS:ffff88887ba80000(0000) knlGS:0000000000000000 +[73496.157922] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 +[73496.157924] CR2: 0000115f002e2010 CR3: 00000003d1e24005 CR4: 00000000003706f0 +[73496.157926] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 +[73496.157928] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400 +[73496.157929] Call Trace: +[73496.157931] +[73496.157933] ? show_regs+0x6d/0x80 +[73496.157936] ? __warn+0x89/0x160 +[73496.157939] ? cifs_put_tcp_session+0x17d/0x190 [cifs] +[73496.157976] ? report_bug+0x17e/0x1b0 +[73496.157980] ? handle_bug+0x51/0xa0 +[73496.157983] ? exc_invalid_op+0x18/0x80 +[73496.157985] ? asm_exc_invalid_op+0x1b/0x20 +[73496.157989] ? cifs_put_tcp_session+0x17d/0x190 [cifs] +[73496.158023] ? cifs_put_tcp_session+0x1e/0x190 [cifs] +[73496.158057] __cifs_put_smb_ses+0x2b5/0x540 [cifs] +[73496.158090] ? tconInfoFree+0xc2/0x120 [cifs] +[73496.158130] cifs_put_tcon.part.0+0x108/0x2b0 [cifs] +[73496.158173] cifs_put_tlink+0x49/0x90 [cifs] +[73496.158220] cifs_umount+0x56/0xb0 [cifs] +[73496.158258] cifs_kill_sb+0x52/0x60 [cifs] +[73496.158306] deactivate_locked_super+0x32/0xc0 +[73496.158309] deactivate_super+0x46/0x60 +[73496.158311] cleanup_mnt+0xc3/0x170 +[73496.158314] __cleanup_mnt+0x12/0x20 +[73496.158330] task_work_run+0x5e/0xa0 +[73496.158333] exit_to_user_mode_loop+0x105/0x130 +[73496.158336] exit_to_user_mode_prepare+0xa5/0xb0 +[73496.158338] syscall_exit_to_user_mode+0x29/0x60 +[73496.158341] do_syscall_64+0x6c/0xf0 +[73496.158344] ? syscall_exit_to_user_mode+0x37/0x60 +[73496.158346] ? do_syscall_64+0x6c/0xf0 +[73496.158349] ? exit_to_user_mode_prepare+0x30/0xb0 +[73496.158353] ? syscall_exit_to_user_mode+0x37/0x60 +[73496.158355] ? do_syscall_64+0x6c/0xf0 + +Reported-by: Robert Morris +Fixes: 705fc522fe9d ("cifs: handle when server starts supporting multichannel") +Signed-off-by: Shyam Prasad N +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/client/smb2pdu.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +--- a/fs/smb/client/smb2pdu.c ++++ b/fs/smb/client/smb2pdu.c +@@ -440,8 +440,7 @@ skip_sess_setup: + skip_add_channels: + + if (smb2_command != SMB2_INTERNAL_CMD) +- if (mod_delayed_work(cifsiod_wq, &server->reconnect, 0)) +- cifs_put_tcp_session(server, false); ++ mod_delayed_work(cifsiod_wq, &server->reconnect, 0); + + atomic_inc(&tconInfoReconnectCount); + out: diff --git a/queue-6.6/cifs-fix-lock-ordering-while-disabling-multichannel.patch b/queue-6.6/cifs-fix-lock-ordering-while-disabling-multichannel.patch new file mode 100644 index 00000000000..cc3966d8a6b --- /dev/null +++ b/queue-6.6/cifs-fix-lock-ordering-while-disabling-multichannel.patch @@ -0,0 +1,82 @@ +From 5eef12c4e3230f2025dc46ad8c4a3bc19978e5d7 Mon Sep 17 00:00:00 2001 +From: Shyam Prasad N +Date: Tue, 14 Nov 2023 04:58:23 +0000 +Subject: cifs: fix lock ordering while disabling multichannel + +From: Shyam Prasad N + +commit 5eef12c4e3230f2025dc46ad8c4a3bc19978e5d7 upstream. + +The code to handle the case of server disabling multichannel +was picking iface_lock with chan_lock held. This goes against +the lock ordering rules, as iface_lock is a higher order lock +(even if it isn't so obvious). + +This change fixes the lock ordering by doing the following in +that order for each secondary channel: +1. store iface and server pointers in local variable +2. remove references to iface and server in channels +3. unlock chan_lock +4. lock iface_lock +5. dec ref count for iface +6. unlock iface_lock +7. dec ref count for server +8. lock chan_lock again + +Since this function can only be called in smb2_reconnect, and +that cannot be called by two parallel processes, we should not +have races due to dropping chan_lock between steps 3 and 8. + +Fixes: ee1d21794e55 ("cifs: handle when server stops supporting multichannel") +Reported-by: Paulo Alcantara +Signed-off-by: Shyam Prasad N +Signed-off-by: Steve French +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/client/sess.c | 22 +++++++++++++--------- + 1 file changed, 13 insertions(+), 9 deletions(-) + +--- a/fs/smb/client/sess.c ++++ b/fs/smb/client/sess.c +@@ -316,28 +316,32 @@ cifs_disable_secondary_channels(struct c + iface = ses->chans[i].iface; + server = ses->chans[i].server; + ++ /* ++ * remove these references first, since we need to unlock ++ * the chan_lock here, since iface_lock is a higher lock ++ */ ++ ses->chans[i].iface = NULL; ++ ses->chans[i].server = NULL; ++ spin_unlock(&ses->chan_lock); ++ + if (iface) { + spin_lock(&ses->iface_lock); + kref_put(&iface->refcount, release_iface); +- ses->chans[i].iface = NULL; + iface->num_channels--; + if (iface->weight_fulfilled) + iface->weight_fulfilled--; + spin_unlock(&ses->iface_lock); + } + +- spin_unlock(&ses->chan_lock); +- if (server && !server->terminate) { +- server->terminate = true; +- cifs_signal_cifsd_for_reconnect(server, false); +- } +- spin_lock(&ses->chan_lock); +- + if (server) { +- ses->chans[i].server = NULL; ++ if (!server->terminate) { ++ server->terminate = true; ++ cifs_signal_cifsd_for_reconnect(server, false); ++ } + cifs_put_tcp_session(server, false); + } + ++ spin_lock(&ses->chan_lock); + } + + done: diff --git a/queue-6.6/series b/queue-6.6/series index 0d5fbc18b57..f30f2c6324a 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -161,3 +161,6 @@ selftests-bpf-test-widening-for-iterating-callbacks.patch bpf-keep-track-of-max-number-of-bpf_loop-callback-iterations.patch selftests-bpf-check-if-max-number-of-bpf_loop-iterations-is-tracked.patch revert-drm-amd-enable-pcie-pme-from-d3.patch +cifs-fix-lock-ordering-while-disabling-multichannel.patch +cifs-fix-a-pending-undercount-of-srv_count.patch +cifs-after-disabling-multichannel-mark-tcon-for-reconnect.patch