Re: [PATCH] cifs: introduce dns_interval mount option

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

 



On Fri, Jun 10, 2022 at 4:14 AM Enzo Matsumiya <ematsumiya@xxxxxxx> wrote:
>
> This patch introduces a `dns_interval' mount option, used to configure
> the interval that the DNS resolve worker should be run.
>
> Enforces the minimum value SMB_DNS_RESOLVE_INTERVAL_MIN (currently 120s),
> or uses the default SMB_DNS_RESOLVE_INTERVAL_DEFAULT (currently 600s).
>
> Since this is a mount option, each derived connection from it, e.g. DFS
> root targets, will share the same DNS interval from the primary server
> since the TCP session options are passed down to them.
>
> Signed-off-by: Enzo Matsumiya <ematsumiya@xxxxxxx>
> ---
>  fs/cifs/cifsfs.c     |  3 +++
>  fs/cifs/cifsglob.h   |  1 +
>  fs/cifs/connect.c    | 20 ++++++++++++++------
>  fs/cifs/fs_context.c | 11 +++++++++++
>  fs/cifs/fs_context.h |  2 ++
>  fs/cifs/sess.c       |  1 +
>  6 files changed, 32 insertions(+), 6 deletions(-)
>
> diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> index 325423180fd2..ad980b235699 100644
> --- a/fs/cifs/cifsfs.c
> +++ b/fs/cifs/cifsfs.c
> @@ -665,6 +665,9 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
>         if (tcon->ses->server->max_credits != SMB2_MAX_CREDITS_AVAILABLE)
>                 seq_printf(s, ",max_credits=%u", tcon->ses->server->max_credits);
>
> +       if (tcon->ses->server->dns_interval != SMB_DNS_RESOLVE_INTERVAL_DEFAULT)
> +               seq_printf(s, ",dns_interval=%u", tcon->ses->server->dns_interval);
> +
>         if (tcon->snapshot_time)
>                 seq_printf(s, ",snapshot=%llu", tcon->snapshot_time);
>         if (tcon->handle_timeout)
> diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
> index f873379066c7..e28a23b617ef 100644
> --- a/fs/cifs/cifsglob.h
> +++ b/fs/cifs/cifsglob.h
> @@ -679,6 +679,7 @@ struct TCP_Server_Info {
>         struct smbd_connection *smbd_conn;
>         struct delayed_work     echo; /* echo ping workqueue job */
>         struct delayed_work     resolve; /* dns resolution workqueue job */
> +       unsigned int dns_interval; /* interval for resolve worker */
>         char    *smallbuf;      /* pointer to current "small" buffer */
>         char    *bigbuf;        /* pointer to current "big" buffer */
>         /* Total size of this PDU. Only valid from cifs_demultiplex_thread */
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index 06bafba9c3ff..e6bedced576a 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -92,7 +92,7 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
>         int len;
>         char *unc, *ipaddr = NULL;
>         time64_t expiry, now;
> -       unsigned long ttl = SMB_DNS_RESOLVE_INTERVAL_DEFAULT;
> +       unsigned int ttl = server->dns_interval;
>
>         if (!server->hostname ||
>             server->hostname[0] == '\0')
> @@ -129,13 +129,15 @@ static int reconn_set_ipaddr_from_hostname(struct TCP_Server_Info *server)
>                         /*
>                          * To make sure we don't use the cached entry, retry 1s
>                          * after expiry.
> +                        *
> +                        * dns_interval is guaranteed to be >= SMB_DNS_RESOLVE_INTERVAL_MIN
>                          */
> -                       ttl = max_t(unsigned long, expiry - now, SMB_DNS_RESOLVE_INTERVAL_MIN) + 1;
> +                       ttl = max_t(unsigned long, expiry - now, server->dns_interval) + 1;
>         }
>         rc = !rc ? -1 : 0;
>
>  requeue_resolve:
> -       cifs_dbg(FYI, "%s: next dns resolution scheduled for %lu seconds in the future\n",
> +       cifs_dbg(FYI, "%s: next dns resolution scheduled for %u seconds in the future\n",
>                  __func__, ttl);
>         mod_delayed_work(cifsiod_wq, &server->resolve, (ttl * HZ));
>
> @@ -1608,6 +1610,12 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
>                 tcp_ses->echo_interval = ctx->echo_interval * HZ;
>         else
>                 tcp_ses->echo_interval = SMB_ECHO_INTERVAL_DEFAULT * HZ;
> +
> +       if (ctx->dns_interval >= SMB_DNS_RESOLVE_INTERVAL_MIN)
> +               tcp_ses->dns_interval = ctx->dns_interval;
> +       else
> +               tcp_ses->dns_interval = SMB_DNS_RESOLVE_INTERVAL_DEFAULT;
> +
Hi Enzo,

Is the above line a mistake? Shouldn't that be set to
SMB_DNS_RESOLVE_INTERVAL_MIN value in the else case?
Rest looks good to me. You can add my RB.

>         if (tcp_ses->rdma) {
>  #ifndef CONFIG_CIFS_SMB_DIRECT
>                 cifs_dbg(VFS, "CONFIG_CIFS_SMB_DIRECT is not enabled\n");
> @@ -1670,10 +1678,10 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
>         queue_delayed_work(cifsiod_wq, &tcp_ses->echo, tcp_ses->echo_interval);
>
>         /* queue dns resolution delayed work */
> -       cifs_dbg(FYI, "%s: next dns resolution scheduled for %d seconds in the future\n",
> -                __func__, SMB_DNS_RESOLVE_INTERVAL_DEFAULT);
> +       cifs_dbg(FYI, "%s: next dns resolution scheduled for %u seconds in the future\n",
> +                __func__, tcp_ses->dns_interval);
>
> -       queue_delayed_work(cifsiod_wq, &tcp_ses->resolve, (SMB_DNS_RESOLVE_INTERVAL_DEFAULT * HZ));
> +       queue_delayed_work(cifsiod_wq, &tcp_ses->resolve, (tcp_ses->dns_interval * HZ));
>
>         return tcp_ses;
>
> diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
> index 8dc0d923ef6a..91b3424ba722 100644
> --- a/fs/cifs/fs_context.c
> +++ b/fs/cifs/fs_context.c
> @@ -152,6 +152,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = {
>         fsparam_u32("handletimeout", Opt_handletimeout),
>         fsparam_u64("snapshot", Opt_snapshot),
>         fsparam_u32("max_channels", Opt_max_channels),
> +       fsparam_u32("dns_interval", Opt_dns_interval),
>
>         /* Mount options which take string value */
>         fsparam_string("source", Opt_source),
> @@ -1099,6 +1100,14 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
>                 if (result.uint_32 > 1)
>                         ctx->multichannel = true;
>                 break;
> +       case Opt_dns_interval:
> +               if (result.uint_32 < SMB_DNS_RESOLVE_INTERVAL_MIN) {
> +                       cifs_errorf(fc, "%s: Minimum value for dns_interval is %u\n",
> +                                       __func__, SMB_DNS_RESOLVE_INTERVAL_MIN);
> +                       goto cifs_parse_mount_err;
> +               }
> +               ctx->dns_interval = result.uint_32;
> +               break;
>         case Opt_handletimeout:
>                 ctx->handle_timeout = result.uint_32;
>                 if (ctx->handle_timeout > SMB3_MAX_HANDLE_TIMEOUT) {
> @@ -1535,6 +1544,8 @@ int smb3_init_fs_context(struct fs_context *fc)
>         ctx->multichannel = false;
>         ctx->max_channels = 1;
>
> +       ctx->dns_interval = SMB_DNS_RESOLVE_INTERVAL_DEFAULT;
> +
>         ctx->backupuid_specified = false; /* no backup intent for a user */
>         ctx->backupgid_specified = false; /* no backup intent for a group */
>
> diff --git a/fs/cifs/fs_context.h b/fs/cifs/fs_context.h
> index 5f093cb7e9b9..567a2dde6333 100644
> --- a/fs/cifs/fs_context.h
> +++ b/fs/cifs/fs_context.h
> @@ -130,6 +130,7 @@ enum cifs_param {
>         Opt_snapshot,
>         Opt_max_channels,
>         Opt_handletimeout,
> +       Opt_dns_interval,
>
>         /* Mount options which take string value */
>         Opt_source,
> @@ -258,6 +259,7 @@ struct smb3_fs_context {
>         __u32 handle_timeout; /* persistent and durable handle timeout in ms */
>         unsigned int max_credits; /* smb3 max_credits 10 < credits < 60000 */
>         unsigned int max_channels;
> +       unsigned int dns_interval; /* interval to resolve server hostname */
>         __u16 compression; /* compression algorithm 0xFFFF default 0=disabled */
>         bool rootfs:1; /* if it's a SMB root file system */
>         bool witness:1; /* use witness protocol */
> diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
> index 0bece97547d4..d3dad612e2a4 100644
> --- a/fs/cifs/sess.c
> +++ b/fs/cifs/sess.c
> @@ -325,6 +325,7 @@ cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
>         ctx.sockopt_tcp_nodelay = ses->server->tcp_nodelay;
>         ctx.echo_interval = ses->server->echo_interval / HZ;
>         ctx.max_credits = ses->server->max_credits;
> +       ctx.dns_interval = ses->server->dns_interval;
>
>         /*
>          * This will be used for encoding/decoding user/domain/pw
> --
> 2.36.1
>


-- 
Regards,
Shyam



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

  Powered by Linux