aboutsummaryrefslogtreecommitdiffstats
path: root/fs
diff options
context:
space:
mode:
authorSteve French <smfrench@gmail.com>2015-12-18 13:31:36 -0500
committerSteve French <sfrench@localhost.localdomain>2016-01-14 14:39:15 -0500
commitadfeb3e00e8e1b9fb4ad19eb7367e7c272d16003 (patch)
treebcef0a8563f7e4d6e541e070458c1672ebd4bc37 /fs
parenta108471b5730b52017e73b58c9f486319d2ac308 (diff)
cifs: Make echo interval tunable
Currently the echo interval is set to 60 seconds using a macro. This setting determines the interval at which echo requests are sent to the server on an idling connection. This setting also affects the time required for a connection to an unresponsive server to timeout. Making this setting a tunable allows users to control the echo interval times as well as control the time after which the connecting to an unresponsive server times out. To set echo interval, pass the echo_interval=n mount option. Version four of the patch. v2: Change MIN and MAX timeout values v3: Remove incorrect comment in cifs_get_tcp_session v4: Fix bug in setting echo_intervalw Signed-off-by: Sachin Prabhu <sprabhu@redhat.com> Acked-by: Shirish Pargaonkar <shirishpargaonkar@gmail.com>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/cifsfs.c2
-rw-r--r--fs/cifs/cifsglob.h8
-rw-r--r--fs/cifs/connect.c35
3 files changed, 34 insertions, 11 deletions
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index b7fcb3151103..53e343d073bb 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -507,6 +507,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
507 507
508 seq_printf(s, ",rsize=%u", cifs_sb->rsize); 508 seq_printf(s, ",rsize=%u", cifs_sb->rsize);
509 seq_printf(s, ",wsize=%u", cifs_sb->wsize); 509 seq_printf(s, ",wsize=%u", cifs_sb->wsize);
510 seq_printf(s, ",echo_interval=%lu",
511 tcon->ses->server->echo_interval / HZ);
510 /* convert actimeo and display it in seconds */ 512 /* convert actimeo and display it in seconds */
511 seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ); 513 seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
512 514
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 2b510c537a0d..9d14926531ba 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -70,8 +70,10 @@
70#define SERVER_NAME_LENGTH 40 70#define SERVER_NAME_LENGTH 40
71#define SERVER_NAME_LEN_WITH_NULL (SERVER_NAME_LENGTH + 1) 71#define SERVER_NAME_LEN_WITH_NULL (SERVER_NAME_LENGTH + 1)
72 72
73/* SMB echo "timeout" -- FIXME: tunable? */ 73/* echo interval in seconds */
74#define SMB_ECHO_INTERVAL (60 * HZ) 74#define SMB_ECHO_INTERVAL_MIN 1
75#define SMB_ECHO_INTERVAL_MAX 600
76#define SMB_ECHO_INTERVAL_DEFAULT 60
75 77
76#include "cifspdu.h" 78#include "cifspdu.h"
77 79
@@ -507,6 +509,7 @@ struct smb_vol {
507 struct sockaddr_storage dstaddr; /* destination address */ 509 struct sockaddr_storage dstaddr; /* destination address */
508 struct sockaddr_storage srcaddr; /* allow binding to a local IP */ 510 struct sockaddr_storage srcaddr; /* allow binding to a local IP */
509 struct nls_table *local_nls; 511 struct nls_table *local_nls;
512 unsigned int echo_interval; /* echo interval in secs */
510}; 513};
511 514
512#define CIFS_MOUNT_MASK (CIFS_MOUNT_NO_PERM | CIFS_MOUNT_SET_UID | \ 515#define CIFS_MOUNT_MASK (CIFS_MOUNT_NO_PERM | CIFS_MOUNT_SET_UID | \
@@ -628,6 +631,7 @@ struct TCP_Server_Info {
628 unsigned int max_read; 631 unsigned int max_read;
629 unsigned int max_write; 632 unsigned int max_write;
630#endif /* CONFIG_CIFS_SMB2 */ 633#endif /* CONFIG_CIFS_SMB2 */
634 unsigned long echo_interval;
631}; 635};
632 636
633static inline unsigned int 637static inline unsigned int
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 103054af9713..de53c5558fe3 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -95,6 +95,7 @@ enum {
95 Opt_cruid, Opt_gid, Opt_file_mode, 95 Opt_cruid, Opt_gid, Opt_file_mode,
96 Opt_dirmode, Opt_port, 96 Opt_dirmode, Opt_port,
97 Opt_rsize, Opt_wsize, Opt_actimeo, 97 Opt_rsize, Opt_wsize, Opt_actimeo,
98 Opt_echo_interval,
98 99
99 /* Mount options which take string value */ 100 /* Mount options which take string value */
100 Opt_user, Opt_pass, Opt_ip, 101 Opt_user, Opt_pass, Opt_ip,
@@ -188,6 +189,7 @@ static const match_table_t cifs_mount_option_tokens = {
188 { Opt_rsize, "rsize=%s" }, 189 { Opt_rsize, "rsize=%s" },
189 { Opt_wsize, "wsize=%s" }, 190 { Opt_wsize, "wsize=%s" },
190 { Opt_actimeo, "actimeo=%s" }, 191 { Opt_actimeo, "actimeo=%s" },
192 { Opt_echo_interval, "echo_interval=%s" },
191 193
192 { Opt_blank_user, "user=" }, 194 { Opt_blank_user, "user=" },
193 { Opt_blank_user, "username=" }, 195 { Opt_blank_user, "username=" },
@@ -418,6 +420,7 @@ cifs_echo_request(struct work_struct *work)
418 int rc; 420 int rc;
419 struct TCP_Server_Info *server = container_of(work, 421 struct TCP_Server_Info *server = container_of(work,
420 struct TCP_Server_Info, echo.work); 422 struct TCP_Server_Info, echo.work);
423 unsigned long echo_interval = server->echo_interval;
421 424
422 /* 425 /*
423 * We cannot send an echo if it is disabled or until the 426 * We cannot send an echo if it is disabled or until the
@@ -427,7 +430,7 @@ cifs_echo_request(struct work_struct *work)
427 */ 430 */
428 if (!server->ops->need_neg || server->ops->need_neg(server) || 431 if (!server->ops->need_neg || server->ops->need_neg(server) ||
429 (server->ops->can_echo && !server->ops->can_echo(server)) || 432 (server->ops->can_echo && !server->ops->can_echo(server)) ||
430 time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ)) 433 time_before(jiffies, server->lstrp + echo_interval - HZ))
431 goto requeue_echo; 434 goto requeue_echo;
432 435
433 rc = server->ops->echo ? server->ops->echo(server) : -ENOSYS; 436 rc = server->ops->echo ? server->ops->echo(server) : -ENOSYS;
@@ -436,7 +439,7 @@ cifs_echo_request(struct work_struct *work)
436 server->hostname); 439 server->hostname);
437 440
438requeue_echo: 441requeue_echo:
439 queue_delayed_work(cifsiod_wq, &server->echo, SMB_ECHO_INTERVAL); 442 queue_delayed_work(cifsiod_wq, &server->echo, echo_interval);
440} 443}
441 444
442static bool 445static bool
@@ -487,12 +490,9 @@ server_unresponsive(struct TCP_Server_Info *server)
487 * a response in >60s. 490 * a response in >60s.
488 */ 491 */
489 if (server->tcpStatus == CifsGood && 492 if (server->tcpStatus == CifsGood &&
490 time_after(jiffies, server->lstrp + 2 * SMB_ECHO_INTERVAL)) { 493 time_after(jiffies, server->lstrp + 2 * server->echo_interval)) {
491 cifs_dbg(VFS, "Server %s (addr=%pISc) has not responded in " 494 cifs_dbg(VFS, "Server %s has not responded in %lu seconds. Reconnecting...\n",
492 "%d seconds. Reconnecting...\n", 495 server->hostname, (2 * server->echo_interval) / HZ);
493 server->hostname,
494 (struct sockaddr *)&server->dstaddr,
495 (2 * SMB_ECHO_INTERVAL) / HZ);
496 cifs_reconnect(server); 496 cifs_reconnect(server);
497 wake_up(&server->response_q); 497 wake_up(&server->response_q);
498 return true; 498 return true;
@@ -1627,6 +1627,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
1627 goto cifs_parse_mount_err; 1627 goto cifs_parse_mount_err;
1628 } 1628 }
1629 break; 1629 break;
1630 case Opt_echo_interval:
1631 if (get_option_ul(args, &option)) {
1632 cifs_dbg(VFS, "%s: Invalid echo interval value\n",
1633 __func__);
1634 goto cifs_parse_mount_err;
1635 }
1636 vol->echo_interval = option;
1637 break;
1630 1638
1631 /* String Arguments */ 1639 /* String Arguments */
1632 1640
@@ -2092,6 +2100,9 @@ static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol)
2092 if (!match_security(server, vol)) 2100 if (!match_security(server, vol))
2093 return 0; 2101 return 0;
2094 2102
2103 if (server->echo_interval != vol->echo_interval)
2104 return 0;
2105
2095 return 1; 2106 return 1;
2096} 2107}
2097 2108
@@ -2211,6 +2222,12 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
2211 tcp_ses->tcpStatus = CifsNew; 2222 tcp_ses->tcpStatus = CifsNew;
2212 ++tcp_ses->srv_count; 2223 ++tcp_ses->srv_count;
2213 2224
2225 if (volume_info->echo_interval >= SMB_ECHO_INTERVAL_MIN &&
2226 volume_info->echo_interval <= SMB_ECHO_INTERVAL_MAX)
2227 tcp_ses->echo_interval = volume_info->echo_interval * HZ;
2228 else
2229 tcp_ses->echo_interval = SMB_ECHO_INTERVAL_DEFAULT * HZ;
2230
2214 rc = ip_connect(tcp_ses); 2231 rc = ip_connect(tcp_ses);
2215 if (rc < 0) { 2232 if (rc < 0) {
2216 cifs_dbg(VFS, "Error connecting to socket. Aborting operation.\n"); 2233 cifs_dbg(VFS, "Error connecting to socket. Aborting operation.\n");
@@ -2240,7 +2257,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
2240 cifs_fscache_get_client_cookie(tcp_ses); 2257 cifs_fscache_get_client_cookie(tcp_ses);
2241 2258
2242 /* queue echo request delayed work */ 2259 /* queue echo request delayed work */
2243 queue_delayed_work(cifsiod_wq, &tcp_ses->echo, SMB_ECHO_INTERVAL); 2260 queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval);
2244 2261
2245 return tcp_ses; 2262 return tcp_ses;
2246 2263