Skip to content

Commit d35b091

Browse files
foxmoxopsiff
authored andcommitted
smb: client: transport: avoid reconnects triggered by pending task work
[ Upstream commit 00be6f2 ] When io_uring is used in the same task as CIFS, there might be unnecessary reconnects, causing issues in user-space applications like QEMU with a log like: > CIFS: VFS: \\10.10.100.81 Error -512 sending data on socket to server Certain io_uring completions might be added to task_work with notify_method being TWA_SIGNAL and thus TIF_NOTIFY_SIGNAL is set for the task. In __smb_send_rqst(), signals are masked before calling smb_send_kvec(), but the masking does not apply to TIF_NOTIFY_SIGNAL. If sk_stream_wait_memory() is reached via sock_sendmsg() while TIF_NOTIFY_SIGNAL is set, signal_pending(current) will evaluate to true there, and -EINTR will be propagated all the way from sk_stream_wait_memory() to sock_sendmsg() in smb_send_kvec(). Afterwards, __smb_send_rqst() will see that not everything was written and reconnect. Signed-off-by: Fiona Ebner <[email protected]> Signed-off-by: Steve French <[email protected]> Signed-off-by: Sasha Levin <[email protected]> (cherry picked from commit c3e4a6de0d1f5104577bd1ce453607bc932e41f4) Signed-off-by: Wentao Guan <[email protected]>
1 parent 4899096 commit d35b091

File tree

1 file changed

+9
-1
lines changed

1 file changed

+9
-1
lines changed

fs/smb/client/transport.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
#include <linux/mempool.h>
2323
#include <linux/sched/signal.h>
2424
#include <linux/task_io_accounting_ops.h>
25+
#include <linux/task_work.h>
2526
#include "cifspdu.h"
2627
#include "cifsglob.h"
2728
#include "cifsproto.h"
@@ -211,9 +212,16 @@ smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg,
211212
* send a packet. In most cases if we fail to send
212213
* after the retries we will kill the socket and
213214
* reconnect which may clear the network problem.
215+
*
216+
* Even if regular signals are masked, EINTR might be
217+
* propagated from sk_stream_wait_memory() to here when
218+
* TIF_NOTIFY_SIGNAL is used for task work. For example,
219+
* certain io_uring completions will use that. Treat
220+
* having EINTR with pending task work the same as EAGAIN
221+
* to avoid unnecessary reconnects.
214222
*/
215223
rc = sock_sendmsg(ssocket, smb_msg);
216-
if (rc == -EAGAIN) {
224+
if (rc == -EAGAIN || unlikely(rc == -EINTR && task_work_pending(current))) {
217225
retries++;
218226
if (retries >= 14 ||
219227
(!server->noblocksnd && (retries > 2))) {

0 commit comments

Comments
 (0)