Skip to content

Commit

Permalink
cifs: Add new parameter "acregmax" for distinct file and directory me…
Browse files Browse the repository at this point in the history
…tadata timeout

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 <[email protected]>
Reviewed-By: Tom Talpey <[email protected]>
Reviewed-by: Ronnie Sahlberg <[email protected]>
Signed-off-by: Steve French <[email protected]>
  • Loading branch information
Steve French committed Feb 25, 2021
1 parent ddaf6d4 commit 5780464
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 13 deletions.
15 changes: 12 additions & 3 deletions fs/cifs/cifsfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
2 changes: 1 addition & 1 deletion fs/cifs/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
23 changes: 18 additions & 5 deletions fs/cifs/fs_context.c
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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 */
Expand Down
6 changes: 4 additions & 2 deletions fs/cifs/fs_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ enum cifs_param {
Opt_wsize,
Opt_actimeo,
Opt_acdirmax,
Opt_acregmax,
Opt_echo_interval,
Opt_max_credits,
Opt_snapshot,
Expand Down Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions fs/cifs/inode.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down

0 comments on commit 5780464

Please sign in to comment.