Blob Blame History Raw
From: Steve French <stfrench@microsoft.com>
Date: Wed, 24 Feb 2021 12:12:53 -0600
Subject: [PATCH] cifs: Add new parameter "acregmax" for distinct file and
 directory metadata timeout
Git-commit: 5780464614f6abe6026f00cf5a0777aa453ba450
References: bsc#1190317
Patch-mainline: v5.12-rc1

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>
Acked-by: Paulo Alcantara <palcantara@suse.de>
---
 fs/cifs/cifs_fs_sb.h |    5 +++--
 fs/cifs/cifsfs.c     |   15 ++++++++++++---
 fs/cifs/cifsglob.h   |    5 +++--
 fs/cifs/connect.c    |   30 ++++++++++++++++++++++++------
 fs/cifs/inode.c      |    4 ++--
 5 files changed, 44 insertions(+), 15 deletions(-)

--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -64,8 +64,9 @@ struct cifs_sb_info {
 	unsigned int bsize;
 	unsigned int rsize;
 	unsigned int wsize;
-	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;
 	atomic_t active;
 	kuid_t	mnt_uid;
 	kgid_t	mnt_gid;
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -600,9 +600,18 @@ cifs_show_options(struct seq_file *s, st
 		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->actimeo / HZ);
-	seq_printf(s, ",acdirmax=%lu", cifs_sb->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->acdirmax == cifs_sb->acregmax)
+		seq_printf(s, ",actimeo=%lu", cifs_sb->acregmax / HZ);
+	else {
+		seq_printf(s, ",acdirmax=%lu", cifs_sb->acdirmax / HZ);
+		seq_printf(s, ",acregmax=%lu", cifs_sb->acregmax / HZ);
+	}
 
 	return 0;
 }
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -610,8 +610,9 @@ struct smb_vol {
 	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;
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -107,7 +107,7 @@ enum {
 	Opt_cruid, Opt_gid, Opt_file_mode,
 	Opt_dirmode, Opt_port,
 	Opt_min_enc_offload,
-	Opt_blocksize, Opt_rsize, Opt_wsize, Opt_actimeo, Opt_acdirmax,
+	Opt_blocksize, Opt_rsize, Opt_wsize, Opt_actimeo, Opt_acdirmax, Opt_acregmax,
 	Opt_echo_interval, Opt_max_credits, Opt_handletimeout,
 	Opt_snapshot,
 
@@ -1645,7 +1645,7 @@ cifs_parse_mount_options(const char *mou
 	/* default is to use strict cifs caching semantics */
 	vol->strict_io = true;
 
-	vol->actimeo = CIFS_DEF_ACTIMEO;
+	vol->acregmax = CIFS_DEF_ACTIMEO;
 	vol->acdirmax = CIFS_DEF_ACTIMEO;
 
 	/* Most clients set timeout to 0, allows server to use its default */
@@ -2062,17 +2062,34 @@ cifs_parse_mount_options(const char *mou
 			}
 			vol->wsize = option;
 			break;
+		case Opt_acregmax:
+			if (get_option_ul(args, &option)) {
+				cifs_dbg(VFS, "%s: Invalid acregmax value\n",
+					 __func__);
+				goto cifs_parse_mount_err;
+			}
+			vol->acregmax = HZ * option;
+			if (vol->acregmax > CIFS_MAX_ACTIMEO) {
+				cifs_dbg(VFS, "acregmax too large\n");
+				goto cifs_parse_mount_err;
+			}
+			break;
 		case Opt_actimeo:
 			if (get_option_ul(args, &option)) {
 				cifs_dbg(VFS, "%s: Invalid actimeo value\n",
 					 __func__);
 				goto cifs_parse_mount_err;
 			}
-			vol->actimeo = HZ * option;
-			if (vol->actimeo > CIFS_MAX_ACTIMEO) {
+			if (HZ * option > CIFS_MAX_ACTIMEO) {
 				cifs_dbg(VFS, "attribute cache timeout too large\n");
 				goto cifs_parse_mount_err;
 			}
+			if ((vol->acdirmax != CIFS_DEF_ACTIMEO) ||
+			    (vol->acregmax != CIFS_DEF_ACTIMEO)) {
+				cifs_dbg(VFS, "actimeo ignored since acregmax or acdirmax specified\n");
+				break;
+			}
+			vol->acdirmax = vol->acregmax = HZ * option;
 			break;
 		case Opt_acdirmax:
 			if (get_option_ul(args, &option)) {
@@ -3622,7 +3639,7 @@ compare_mount_options(struct super_block
 	if (strcmp(old->local_nls->charset, new->local_nls->charset))
 		return 0;
 
-	if (old->actimeo != new->actimeo)
+	if (old->acregmax != new->acregmax)
 		return 0;
 	if (old->acdirmax != new->acdirmax)
 		return 0;
@@ -4086,7 +4103,8 @@ int cifs_setup_cifs_sb(struct smb_vol *p
 	cifs_dbg(FYI, "file mode: %04ho  dir mode: %04ho\n",
 		 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
 
-	cifs_sb->actimeo = pvolume_info->actimeo;
+	cifs_sb->acregmax = pvolume_info->acregmax;
+	cifs_sb->acdirmax = pvolume_info->acdirmax;
 	cifs_sb->local_nls = pvolume_info->local_nls;
 
 	if (pvolume_info->nodfs)
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -2002,10 +2002,10 @@ cifs_inode_needs_reval(struct inode *ino
 				   cifs_i->time + cifs_sb->acdirmax))
 			return true;
 	} else { /* file */
-		if (!cifs_sb->actimeo)
+		if (!cifs_sb->acregmax)
 			return true;
 		if (!time_in_range(jiffies, cifs_i->time,
-				   cifs_i->time + cifs_sb->actimeo))
+				   cifs_i->time + cifs_sb->acregmax))
 			return true;
 	}