diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c index d5457015801d..1c9f3d053c7e 100644 --- a/fs/cifs/cifsfs.c +++ b/fs/cifs/cifsfs.c @@ -550,6 +550,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root) seq_printf(s, ",snapshot=%llu", tcon->snapshot_time); /* convert actimeo and display it in seconds */ seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); + seq_printf(s, ",wait_reconnect_timeout=%lu", + tcon->ses->server->wait_reconnect_timeout / HZ); return 0; } diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h index 71c2dd0c7f03..058ba8ba0fa8 100644 --- a/fs/cifs/cifsglob.h +++ b/fs/cifs/cifsglob.h @@ -76,6 +76,11 @@ #define SMB_ECHO_INTERVAL_MAX 600 #define SMB_ECHO_INTERVAL_DEFAULT 60 +/* wait reconnect in secs */ +#define SMB_WAIT_RECONNECT_TIMEOUT_MIN 0 +#define SMB_WAIT_RECONNECT_TIMEOUT_MAX 10 +#define SMB_WAIT_RECONNECT_TIMEOUT_DEFAULT 10 + /* maximum number of PDUs in one compound */ #define MAX_COMPOUND 5 @@ -567,6 +572,7 @@ struct smb_vol { unsigned int echo_interval; /* echo interval in secs */ __u64 snapshot_time; /* needed for timewarp tokens */ unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */ + unsigned int wait_reconnect_timeout; /* wait reconnect in secs */ }; #define CIFS_MOUNT_MASK (CIFS_MOUNT_NO_PERM | CIFS_MOUNT_SET_UID | \ @@ -697,6 +703,7 @@ struct TCP_Server_Info { struct delayed_work reconnect; /* reconnect workqueue job */ struct mutex reconnect_mutex; /* prevent simultaneous reconnects */ unsigned long echo_interval; + unsigned long wait_reconnect_timeout; }; static inline unsigned int diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c index cb70f0c6aa1b..28151bd84777 100644 --- a/fs/cifs/cifssmb.c +++ b/fs/cifs/cifssmb.c @@ -159,7 +159,7 @@ cifs_reconnect_tcon(struct cifs_tcon *tcon, int smb_command) while (server->tcpStatus == CifsNeedReconnect) { rc = wait_event_interruptible_timeout(server->response_q, (server->tcpStatus != CifsNeedReconnect), - 10 * HZ); + server->wait_reconnect_timeout * HZ); if (rc < 0) { cifs_dbg(FYI, "%s: aborting reconnect due to a received" " signal by the process\n", __func__); diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c index 6335ca143292..b3e5e8568a12 100644 --- a/fs/cifs/connect.c +++ b/fs/cifs/connect.c @@ -100,7 +100,7 @@ enum { Opt_dirmode, Opt_port, Opt_rsize, Opt_wsize, Opt_actimeo, Opt_echo_interval, Opt_max_credits, - Opt_snapshot, + Opt_snapshot, Opt_wait_reconnect_timeout, /* Mount options which take string value */ Opt_user, Opt_pass, Opt_ip, @@ -207,6 +207,7 @@ static const match_table_t cifs_mount_option_tokens = { { Opt_echo_interval, "echo_interval=%s" }, { Opt_max_credits, "max_credits=%s" }, { Opt_snapshot, "snapshot=%s" }, + { Opt_wait_reconnect_timeout, "wait_reconnect_timeout=%s" }, { Opt_blank_user, "user=" }, { Opt_blank_user, "username=" }, @@ -1492,6 +1493,8 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, vol->echo_interval = SMB_ECHO_INTERVAL_DEFAULT; + vol->wait_reconnect_timeout = SMB_WAIT_RECONNECT_TIMEOUT_DEFAULT; + if (!mountdata) goto cifs_parse_mount_err; @@ -1892,6 +1895,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname, } vol->max_credits = option; break; + case Opt_wait_reconnect_timeout: + if (get_option_ul(args, &option)) { + cifs_dbg(VFS, "%s: Invalid wait_reconnect_timeout value\n", + __func__); + goto cifs_parse_mount_err; + } + vol->wait_reconnect_timeout = option; + break; /* String Arguments */ @@ -2529,6 +2540,13 @@ cifs_get_tcp_session(struct smb_vol *volume_info) tcp_ses->echo_interval = volume_info->echo_interval * HZ; else tcp_ses->echo_interval = SMB_ECHO_INTERVAL_DEFAULT * HZ; + + if (volume_info->wait_reconnect_timeout >= SMB_WAIT_RECONNECT_TIMEOUT_MIN && + volume_info->wait_reconnect_timeout <= SMB_WAIT_RECONNECT_TIMEOUT_MAX) + tcp_ses->wait_reconnect_timeout = volume_info->wait_reconnect_timeout * HZ; + else + tcp_ses->wait_reconnect_timeout = SMB_WAIT_RECONNECT_TIMEOUT_DEFAULT * HZ; + if (tcp_ses->rdma) { #ifndef CONFIG_CIFS_SMB_DIRECT cifs_dbg(VFS, "CONFIG_CIFS_SMB_DIRECT is not enabled\n"); diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c index 379ac8caa29a..e9ef8c544057 100644 --- a/fs/cifs/smb2pdu.c +++ b/fs/cifs/smb2pdu.c @@ -214,7 +214,7 @@ smb2_reconnect(__le16 smb2_command, struct cifs_tcon *tcon) rc = wait_event_interruptible_timeout(server->response_q, (server->tcpStatus != CifsNeedReconnect), - 10 * HZ); + server->wait_reconnect_timeout * HZ); if (rc < 0) { cifs_dbg(FYI, "%s: aborting reconnect due to a received" " signal by the process\n", __func__);