
mainline inclusion from mainline-v6.15-rc1 commit 764da2fff399756d09b02db7fa7bd05e57928cc0 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/IC1OPD CVE: NA Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i... -------------------------------- When a SMB connection is reset and reconnected, the negotiated IO parameters (rsize/wsize) can become out of sync with the server's current capabilities. This can lead to suboptimal performance or even IO failures if the server's limits have changed. This patch implements automatic IO size renegotiation: 1. Adds cifs_renegotiate_iosize() function to update all superblocks associated with a tree connection 2. Updates each mount's rsize/wsize based on current server capabilities 3. Calls this function after successful tree connection reconnection With this change, all mount points will automatically maintain optimal and reliable IO parameters after network disruptions, using the bidirectional mapping added in previous patches. This completes the series improving connection resilience by keeping mount parameters synchronized with server capabilities. Signed-off-by: Wang Zhaolong <wangzhaolong1@huawei.com> Signed-off-by: Steve French <stfrench@microsoft.com> [The mainline code has already undergone multiple refactoring sessions.] Conflicts: fs/cifs/smb2pdu.c fs/smb/client/smb2pdu.c [The mainline code has already undergone multiple refactoring sessions.] Signed-off-by: Wang Zhaolong <wangzhaolong1@huawei.com> --- fs/cifs/smb2pdu.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 4197096e7fdb..696c84632617 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -3674,10 +3674,28 @@ smb2_echo_callback(struct mid_q_entry *mid) DeleteMidQEntry(mid); add_credits(server, &credits, CIFS_ECHO_OP); } +static void cifs_renegotiate_iosize(struct TCP_Server_Info *server, + struct cifs_tcon *tcon) +{ + struct cifs_sb_info *cifs_sb; + + if (server == NULL || tcon == NULL) + return; + + spin_lock(&tcon->sb_list_lock); + list_for_each_entry(cifs_sb, &tcon->cifs_sb_list, tcon_sb_link) { + cifs_sb->rsize = + server->ops->negotiate_rsize(tcon, cifs_sb->rsize); + cifs_sb->wsize = + server->ops->negotiate_wsize(tcon, cifs_sb->wsize); + } + spin_unlock(&tcon->sb_list_lock); +} + void smb2_reconnect_server(struct work_struct *work) { struct TCP_Server_Info *server = container_of(work, struct TCP_Server_Info, reconnect.work); struct cifs_ses *ses; @@ -3722,14 +3740,16 @@ void smb2_reconnect_server(struct work_struct *work) spin_unlock(&cifs_tcp_ses_lock); list_for_each_entry_safe(tcon, tcon2, &tmp_list, rlist) { rc = smb2_reconnect(SMB2_INTERNAL_CMD, tcon, server); - if (!rc) + if (!rc) { + cifs_renegotiate_iosize(server, tcon); cifs_reopen_persistent_handles(tcon); - else + } else { resched = true; + } list_del_init(&tcon->rlist); if (tcon->ipc) cifs_put_smb_ses(tcon->ses); else cifs_put_tcon(tcon); -- 2.39.2