Skip to content

Commit 00be6f2

Browse files
foxmoxsmfrench
authored andcommitted
smb: client: transport: avoid reconnects triggered by pending task work
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]>
1 parent 17ef15f commit 00be6f2

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"
@@ -173,9 +174,16 @@ smb_send_kvec(struct TCP_Server_Info *server, struct msghdr *smb_msg,
173174
* send a packet. In most cases if we fail to send
174175
* after the retries we will kill the socket and
175176
* reconnect which may clear the network problem.
177+
*
178+
* Even if regular signals are masked, EINTR might be
179+
* propagated from sk_stream_wait_memory() to here when
180+
* TIF_NOTIFY_SIGNAL is used for task work. For example,
181+
* certain io_uring completions will use that. Treat
182+
* having EINTR with pending task work the same as EAGAIN
183+
* to avoid unnecessary reconnects.
176184
*/
177185
rc = sock_sendmsg(ssocket, smb_msg);
178-
if (rc == -EAGAIN) {
186+
if (rc == -EAGAIN || unlikely(rc == -EINTR && task_work_pending(current))) {
179187
retries++;
180188
if (retries >= 14 ||
181189
(!server->noblocksnd && (retries > 2))) {

0 commit comments

Comments
 (0)