summaryrefslogtreecommitdiff
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
authorRohith Surabattula <rohiths@microsoft.com>2020-09-18 08:37:28 +0300
committerSteve French <stfrench@microsoft.com>2020-10-16 07:58:04 +0300
commit8e670f77c4a55013db6d23b962f9bf6673a5e7b6 (patch)
treeab0a3802b3b1ae95c652569bb838c3a92e054f60 /fs/cifs/connect.c
parentd1542cf6165e526a6837cc9d1e20cb0da841bd0b (diff)
downloadlinux-8e670f77c4a55013db6d23b962f9bf6673a5e7b6.tar.xz
Handle STATUS_IO_TIMEOUT gracefully
Currently STATUS_IO_TIMEOUT is not treated as retriable error. It is currently mapped to ETIMEDOUT and returned to userspace for most system calls. STATUS_IO_TIMEOUT is returned by server in case of unavailability or throttling errors. This patch will map the STATUS_IO_TIMEOUT to EAGAIN, so that it can be retried. Also, added a check to drop the connection to not overload the server in case of ongoing unavailability. Signed-off-by: Rohith Surabattula <rohiths@microsoft.com> Reviewed-by: Aurelien Aptel <aaptel@suse.com> Reviewed-by: Pavel Shilovsky <pshilov@microsoft.com> Signed-off-by: Steve French <stfrench@microsoft.com>
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c15
1 files changed, 14 insertions, 1 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index a5731dd6e656..1a3b7793095e 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -69,6 +69,9 @@ extern bool disable_legacy_dialects;
#define TLINK_ERROR_EXPIRE (1 * HZ)
#define TLINK_IDLE_EXPIRE (600 * HZ)
+/* Drop the connection to not overload the server */
+#define NUM_STATUS_IO_TIMEOUT 5
+
enum {
/* Mount options that take no arguments */
Opt_user_xattr, Opt_nouser_xattr,
@@ -1117,7 +1120,7 @@ cifs_demultiplex_thread(void *p)
struct task_struct *task_to_wake = NULL;
struct mid_q_entry *mids[MAX_COMPOUND];
char *bufs[MAX_COMPOUND];
- unsigned int noreclaim_flag;
+ unsigned int noreclaim_flag, num_io_timeout = 0;
noreclaim_flag = memalloc_noreclaim_save();
cifs_dbg(FYI, "Demultiplex PID: %d\n", task_pid_nr(current));
@@ -1213,6 +1216,16 @@ next_pdu:
continue;
}
+ if (server->ops->is_status_io_timeout &&
+ server->ops->is_status_io_timeout(buf)) {
+ num_io_timeout++;
+ if (num_io_timeout > NUM_STATUS_IO_TIMEOUT) {
+ cifs_reconnect(server);
+ num_io_timeout = 0;
+ continue;
+ }
+ }
+
server->lstrp = jiffies;
for (i = 0; i < num_mids; i++) {