cifs: Add new parameter "acregmax" for distinct file and directory metadata timeout
authorSteve French <stfrench@microsoft.com>
Wed, 24 Feb 2021 18:12:53 +0000 (12:12 -0600)
committerSteve French <stfrench@microsoft.com>
Thu, 25 Feb 2021 17:47:49 +0000 (11:47 -0600)
The new optional mount parameter "acregmax" allows a different
timeout for file metadata ("acdirmax" now allows controlling timeout
for directory metadata).  Setting "actimeo" still works as before,
and changes timeout for both files and directories, but
specifying "acregmax" or "acdirmax" allows overriding the
default more granularly which can be a big performance benefit
on some workloads. "acregmax" is already used by NFS as a mount
parameter (albeit with a larger default and thus looser caching).

Suggested-by: Tom Talpey <tom@talpey.com>
Reviewed-By: Tom Talpey <tom@talpey.com>
Reviewed-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
fs/cifs/cifsfs.c
fs/cifs/connect.c
fs/cifs/fs_context.c
fs/cifs/fs_context.h
fs/cifs/inode.c

index 4e0b0b26e8444c0eb747dad71265d1b38f6c3002..3b61f09f3e1bc5aa1d17fe7faa0ce07feae40306 100644 (file)
@@ -637,9 +637,18 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
                seq_printf(s, ",snapshot=%llu", tcon->snapshot_time);
        if (tcon->handle_timeout)
                seq_printf(s, ",handletimeout=%u", tcon->handle_timeout);
-       /* convert actimeo and directory attribute timeout and display in seconds */
-       seq_printf(s, ",actimeo=%lu", cifs_sb->ctx->actimeo / HZ);
-       seq_printf(s, ",acdirmax=%lu", cifs_sb->ctx->acdirmax / HZ);
+
+       /*
+        * Display file and directory attribute timeout in seconds.
+        * If file and directory attribute timeout the same then actimeo
+        * was likely specified on mount
+        */
+       if (cifs_sb->ctx->acdirmax == cifs_sb->ctx->acregmax)
+               seq_printf(s, ",actimeo=%lu", cifs_sb->ctx->acregmax / HZ);
+       else {
+               seq_printf(s, ",acdirmax=%lu", cifs_sb->ctx->acdirmax / HZ);
+               seq_printf(s, ",acregmax=%lu", cifs_sb->ctx->acregmax / HZ);
+       }
 
        if (tcon->ses->chan_max > 1)
                seq_printf(s, ",multichannel,max_channels=%zu",
index a9dc39aee9f4cb69265e6836922ffa0b98650b21..9ecd8098c2b6b193b7c49df27033be78ba9be617 100644 (file)
@@ -2276,7 +2276,7 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
        if (strcmp(old->local_nls->charset, new->local_nls->charset))
                return 0;
 
-       if (old->ctx->actimeo != new->ctx->actimeo)
+       if (old->ctx->acregmax != new->ctx->acregmax)
                return 0;
        if (old->ctx->acdirmax != new->ctx->acdirmax)
                return 0;
index f3be07f4671d4192294ce8f5e4dc0d11c066fed5..14c955a3000646eaab47995a921fad2ee841e8d8 100644 (file)
@@ -141,6 +141,7 @@ const struct fs_parameter_spec smb3_fs_parameters[] = {
        fsparam_u32("wsize", Opt_wsize),
        fsparam_u32("actimeo", Opt_actimeo),
        fsparam_u32("acdirmax", Opt_acdirmax),
+       fsparam_u32("acregmax", Opt_acregmax),
        fsparam_u32("echo_interval", Opt_echo_interval),
        fsparam_u32("max_credits", Opt_max_credits),
        fsparam_u32("handletimeout", Opt_handletimeout),
@@ -930,10 +931,10 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
                ctx->wsize = result.uint_32;
                ctx->got_wsize = true;
                break;
-       case Opt_actimeo:
-               ctx->actimeo = HZ * result.uint_32;
-               if (ctx->actimeo > CIFS_MAX_ACTIMEO) {
-                       cifs_dbg(VFS, "attribute cache timeout too large\n");
+       case Opt_acregmax:
+               ctx->acregmax = HZ * result.uint_32;
+               if (ctx->acregmax > CIFS_MAX_ACTIMEO) {
+                       cifs_dbg(VFS, "acregmax too large\n");
                        goto cifs_parse_mount_err;
                }
                break;
@@ -944,6 +945,18 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
                        goto cifs_parse_mount_err;
                }
                break;
+       case Opt_actimeo:
+               if (HZ * result.uint_32 > CIFS_MAX_ACTIMEO) {
+                       cifs_dbg(VFS, "timeout too large\n");
+                       goto cifs_parse_mount_err;
+               }
+               if ((ctx->acdirmax != CIFS_DEF_ACTIMEO) ||
+                   (ctx->acregmax != CIFS_DEF_ACTIMEO)) {
+                       cifs_dbg(VFS, "actimeo ignored since acregmax or acdirmax specified\n");
+                       break;
+               }
+               ctx->acdirmax = ctx->acregmax = HZ * result.uint_32;
+               break;
        case Opt_echo_interval:
                ctx->echo_interval = result.uint_32;
                break;
@@ -1369,7 +1382,7 @@ int smb3_init_fs_context(struct fs_context *fc)
        /* default is to use strict cifs caching semantics */
        ctx->strict_io = true;
 
-       ctx->actimeo = CIFS_DEF_ACTIMEO;
+       ctx->acregmax = CIFS_DEF_ACTIMEO;
        ctx->acdirmax = CIFS_DEF_ACTIMEO;
 
        /* Most clients set timeout to 0, allows server to use its default */
index 472372fec4e95d2b8193f79bfc0316cefb597cc9..87dd1f7168f26f8d111e6562636e9cfd06feacff 100644 (file)
@@ -119,6 +119,7 @@ enum cifs_param {
        Opt_wsize,
        Opt_actimeo,
        Opt_acdirmax,
+       Opt_acregmax,
        Opt_echo_interval,
        Opt_max_credits,
        Opt_snapshot,
@@ -233,8 +234,9 @@ struct smb3_fs_context {
        unsigned int wsize;
        unsigned int min_offload;
        bool sockopt_tcp_nodelay:1;
-       unsigned long actimeo; /* attribute cache timeout for files (jiffies) */
-       unsigned long acdirmax; /* attribute cache timeout for directories (jiffies) */
+       /* attribute cache timemout for files and directories in jiffies */
+       unsigned long acregmax;
+       unsigned long acdirmax;
        struct smb_version_operations *ops;
        struct smb_version_values *vals;
        char *prepath;
index cfd31cc4520f9161c36afb25cc2857510223af75..0b0b01ef3ecb9054e4a2c3402ed98a7bd9e5d823 100644 (file)
@@ -2209,10 +2209,10 @@ cifs_inode_needs_reval(struct inode *inode)
                                   cifs_i->time + cifs_sb->ctx->acdirmax))
                        return true;
        } else { /* file */
-               if (!cifs_sb->ctx->actimeo)
+               if (!cifs_sb->ctx->acregmax)
                        return true;
                if (!time_in_range(jiffies, cifs_i->time,
-                                  cifs_i->time + cifs_sb->ctx->actimeo))
+                                  cifs_i->time + cifs_sb->ctx->acregmax))
                        return true;
        }