Re: [PATCH] cifs: Make echo interval tunable.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Why restrict the echo interval to such a narrow range?  If tunable
might as well allow a larger range, maybe 1 to 600 (ten minutes)?  I
am not certain of the range of possible future uses - maybe a
pseudo-real type workload connected to a really fast server wants
something really low (a few seconds?) and maybe very poor network
connections want something longer?  Not a strong objection, but seems
like we could allow a broader range without confusing the user.

Many years ago, Windows and OS/2 had an oplock break time (which also
controlled how long to wait for acks to come back from the server) -
and it ranged from 34 to 127 seconds for acks and 35 to 640 for oplock
break timeouts.     Don't see any reason to limit it less than that
(that was really old and networks vary a lot in performance now).

Thoughts?

On Mon, Dec 14, 2015 at 6:47 AM, Sachin Prabhu <sprabhu@xxxxxxxxxx> wrote:
> 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.
>
> Signed-off-by: Sachin Prabhu <sprabhu@xxxxxxxxxx>
> ---
>  fs/cifs/cifsfs.c   |  2 ++
>  fs/cifs/cifsglob.h |  8 ++++++--
>  fs/cifs/connect.c  | 33 +++++++++++++++++++++++++++------
>  3 files changed, 35 insertions(+), 8 deletions(-)
>
> diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> index cbc0f4b..eab2de6 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)
>
>         seq_printf(s, ",rsize=%u", cifs_sb->rsize);
>         seq_printf(s, ",wsize=%u", cifs_sb->wsize);
> +       seq_printf(s, ",echo_interval=%lu",
> +                       tcon->ses->server->echo_interval / HZ);
>         /* convert actimeo and display it in seconds */
>         seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
>
> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> index 2b510c5..56d3698 100644
> --- a/fs/cifs/cifsglob.h
> +++ b/fs/cifs/cifsglob.h
> @@ -70,8 +70,10 @@
>  #define SERVER_NAME_LENGTH 40
>  #define SERVER_NAME_LEN_WITH_NULL     (SERVER_NAME_LENGTH + 1)
>
> -/* SMB echo "timeout" -- FIXME: tunable? */
> -#define SMB_ECHO_INTERVAL (60 * HZ)
> +/* echo interval in seconds */
> +#define SMB_ECHO_INTERVAL_MIN 10
> +#define SMB_ECHO_INTERVAL_MAX 120
> +#define SMB_ECHO_INTERVAL_DEFAULT 60
>
>  #include "cifspdu.h"
>
> @@ -507,6 +509,7 @@ struct smb_vol {
>         struct sockaddr_storage dstaddr; /* destination address */
>         struct sockaddr_storage srcaddr; /* allow binding to a local IP */
>         struct nls_table *local_nls;
> +       unsigned int echo_interval; /* echo interval in secs */
>  };
>
>  #define CIFS_MOUNT_MASK (CIFS_MOUNT_NO_PERM | CIFS_MOUNT_SET_UID | \
> @@ -628,6 +631,7 @@ struct TCP_Server_Info {
>         unsigned int    max_read;
>         unsigned int    max_write;
>  #endif /* CONFIG_CIFS_SMB2 */
> +       unsigned long echo_interval;
>  };
>
>  static inline unsigned int
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index ecb0803..3b44e9e 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -95,6 +95,7 @@ enum {
>         Opt_cruid, Opt_gid, Opt_file_mode,
>         Opt_dirmode, Opt_port,
>         Opt_rsize, Opt_wsize, Opt_actimeo,
> +       Opt_echo_interval,
>
>         /* Mount options which take string value */
>         Opt_user, Opt_pass, Opt_ip,
> @@ -188,6 +189,7 @@ static const match_table_t cifs_mount_option_tokens = {
>         { Opt_rsize, "rsize=%s" },
>         { Opt_wsize, "wsize=%s" },
>         { Opt_actimeo, "actimeo=%s" },
> +       { Opt_echo_interval, "echo_interval=%s" },
>
>         { Opt_blank_user, "user=" },
>         { Opt_blank_user, "username=" },
> @@ -418,6 +420,7 @@ cifs_echo_request(struct work_struct *work)
>         int rc;
>         struct TCP_Server_Info *server = container_of(work,
>                                         struct TCP_Server_Info, echo.work);
> +       unsigned long echo_interval = server->echo_interval;
>
>         /*
>          * We cannot send an echo if it is disabled or until the
> @@ -427,7 +430,7 @@ cifs_echo_request(struct work_struct *work)
>          */
>         if (!server->ops->need_neg || server->ops->need_neg(server) ||
>             (server->ops->can_echo && !server->ops->can_echo(server)) ||
> -           time_before(jiffies, server->lstrp + SMB_ECHO_INTERVAL - HZ))
> +           time_before(jiffies, server->lstrp + echo_interval - HZ))
>                 goto requeue_echo;
>
>         rc = server->ops->echo ? server->ops->echo(server) : -ENOSYS;
> @@ -436,7 +439,7 @@ cifs_echo_request(struct work_struct *work)
>                          server->hostname);
>
>  requeue_echo:
> -       queue_delayed_work(cifsiod_wq, &server->echo, SMB_ECHO_INTERVAL);
> +       queue_delayed_work(cifsiod_wq, &server->echo, echo_interval);
>  }
>
>  static bool
> @@ -487,9 +490,9 @@ server_unresponsive(struct TCP_Server_Info *server)
>          *     a response in >60s.
>          */
>         if (server->tcpStatus == CifsGood &&
> -           time_after(jiffies, server->lstrp + 2 * SMB_ECHO_INTERVAL)) {
> -               cifs_dbg(VFS, "Server %s has not responded in %d seconds. Reconnecting...\n",
> -                        server->hostname, (2 * SMB_ECHO_INTERVAL) / HZ);
> +           time_after(jiffies, server->lstrp + 2 * server->echo_interval)) {
> +               cifs_dbg(VFS, "Server %s has not responded in %lu seconds. Reconnecting...\n",
> +                        server->hostname, (2 * server->echo_interval) / HZ);
>                 cifs_reconnect(server);
>                 wake_up(&server->response_q);
>                 return true;
> @@ -1624,6 +1627,14 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
>                                 goto cifs_parse_mount_err;
>                         }
>                         break;
> +               case Opt_echo_interval:
> +                       if (get_option_ul(args, &option)) {
> +                               cifs_dbg(VFS, "%s: Invalid echo interval value\n",
> +                                        __func__);
> +                               goto cifs_parse_mount_err;
> +                       }
> +                       vol->echo_interval = option;
> +                       break;
>
>                 /* String Arguments */
>
> @@ -2089,6 +2100,9 @@ static int match_server(struct TCP_Server_Info *server, struct smb_vol *vol)
>         if (!match_security(server, vol))
>                 return 0;
>
> +       if (server->echo_interval != vol->echo_interval)
> +               return 0;
> +
>         return 1;
>  }
>
> @@ -2208,6 +2222,13 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
>         tcp_ses->tcpStatus = CifsNew;
>         ++tcp_ses->srv_count;
>
> +       /* echo interval should be between 10 and 120 secs */
> +       if (volume_info->echo_interval > SMB_ECHO_INTERVAL_MIN ||
> +               volume_info->echo_interval < SMB_ECHO_INTERVAL_MAX)
> +               tcp_ses->echo_interval = volume_info->echo_interval * HZ;
> +       else
> +               tcp_ses->echo_interval = SMB_ECHO_INTERVAL_DEFAULT * HZ;
> +
>         rc = ip_connect(tcp_ses);
>         if (rc < 0) {
>                 cifs_dbg(VFS, "Error connecting to socket. Aborting operation.\n");
> @@ -2237,7 +2258,7 @@ cifs_get_tcp_session(struct smb_vol *volume_info)
>         cifs_fscache_get_client_cookie(tcp_ses);
>
>         /* queue echo request delayed work */
> -       queue_delayed_work(cifsiod_wq, &tcp_ses->echo, SMB_ECHO_INTERVAL);
> +       queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval);
>
>         return tcp_ses;
>
> --
> 2.4.3
>



-- 
Thanks,

Steve
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux