linux-cifs.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 02/21] cifs: rename dup_vol to smb3_fs_context_dup and move it into fs_context.c
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 03/21] cifs: move the enum for cifs parameters into fs_context.h Ronnie Sahlberg
                   ` (18 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/dfs_cache.c  | 60 +---------------------------------------------------
 fs/cifs/fs_context.c | 41 +++++++++++++++++++++++++++++++++++
 fs/cifs/fs_context.h |  3 ++-
 3 files changed, 44 insertions(+), 60 deletions(-)

diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c
index 3860241dcc03..2b77d39d7d22 100644
--- a/fs/cifs/dfs_cache.c
+++ b/fs/cifs/dfs_cache.c
@@ -1141,64 +1141,6 @@ int dfs_cache_get_tgt_referral(const char *path,
 	return rc;
 }
 
-static int dup_vol(struct smb3_fs_context *ctx, struct smb3_fs_context *new)
-{
-	memcpy(new, ctx, sizeof(*new));
-
-	if (ctx->username) {
-		new->username = kstrndup(ctx->username, strlen(ctx->username),
-					 GFP_KERNEL);
-		if (!new->username)
-			return -ENOMEM;
-	}
-	if (ctx->password) {
-		new->password = kstrndup(ctx->password, strlen(ctx->password),
-					 GFP_KERNEL);
-		if (!new->password)
-			goto err_free_username;
-	}
-	if (ctx->UNC) {
-		cifs_dbg(FYI, "%s: ctx->UNC: %s\n", __func__, ctx->UNC);
-		new->UNC = kstrndup(ctx->UNC, strlen(ctx->UNC), GFP_KERNEL);
-		if (!new->UNC)
-			goto err_free_password;
-	}
-	if (ctx->domainname) {
-		new->domainname = kstrndup(ctx->domainname,
-					   strlen(ctx->domainname), GFP_KERNEL);
-		if (!new->domainname)
-			goto err_free_unc;
-	}
-	if (ctx->iocharset) {
-		new->iocharset = kstrndup(ctx->iocharset,
-					  strlen(ctx->iocharset), GFP_KERNEL);
-		if (!new->iocharset)
-			goto err_free_domainname;
-	}
-	if (ctx->prepath) {
-		cifs_dbg(FYI, "%s: ctx->prepath: %s\n", __func__, ctx->prepath);
-		new->prepath = kstrndup(ctx->prepath, strlen(ctx->prepath),
-					GFP_KERNEL);
-		if (!new->prepath)
-			goto err_free_iocharset;
-	}
-
-	return 0;
-
-err_free_iocharset:
-	kfree(new->iocharset);
-err_free_domainname:
-	kfree(new->domainname);
-err_free_unc:
-	kfree(new->UNC);
-err_free_password:
-	kfree_sensitive(new->password);
-err_free_username:
-	kfree(new->username);
-	kfree(new);
-	return -ENOMEM;
-}
-
 /**
  * dfs_cache_add_vol - add a cifs volume during mount() that will be handled by
  * DFS cache refresh worker.
@@ -1229,7 +1171,7 @@ int dfs_cache_add_vol(char *mntdata, struct smb3_fs_context *ctx, const char *fu
 		goto err_free_vi;
 	}
 
-	rc = dup_vol(ctx, &vi->ctx);
+	rc = smb3_fs_context_dup(&vi->ctx, ctx);
 	if (rc)
 		goto err_free_fullpath;
 
diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
index aa4b85bd5849..301201903b45 100644
--- a/fs/cifs/fs_context.c
+++ b/fs/cifs/fs_context.c
@@ -7,6 +7,7 @@
  */
 
 #include "cifsglob.h"
+#include "cifsproto.h"
 #include "cifs_debug.h"
 #include "fs_context.h"
 
@@ -219,3 +220,43 @@ cifs_parse_cache_flavor(char *value, struct smb3_fs_context *ctx)
 	}
 	return 0;
 }
+
+#define DUP_CTX_STR(field)						\
+do {									\
+	if (ctx->field) {						\
+		new_ctx->field = kstrdup(ctx->field, GFP_ATOMIC);	\
+		if (new_ctx->field == NULL) {				\
+			cifs_cleanup_volume_info_contents(new_ctx);	\
+			return -ENOMEM;					\
+		}							\
+	}								\
+} while (0)
+
+int
+smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx)
+{
+	int rc = 0;
+
+	memcpy(new_ctx, ctx, sizeof(*ctx));
+	new_ctx->prepath = NULL;
+	new_ctx->local_nls = NULL;
+	new_ctx->nodename = NULL;
+	new_ctx->username = NULL;
+	new_ctx->password = NULL;
+	new_ctx->domainname = NULL;
+	new_ctx->UNC = NULL;
+	new_ctx->iocharset = NULL;
+
+	/*
+	 * Make sure to stay in sync with cifs_cleanup_volume_info_contents()
+	 */
+	DUP_CTX_STR(prepath);
+	DUP_CTX_STR(username);
+	DUP_CTX_STR(password);
+	DUP_CTX_STR(UNC);
+	DUP_CTX_STR(domainname);
+	DUP_CTX_STR(nodename);
+	DUP_CTX_STR(iocharset);
+
+	return rc;
+}
diff --git a/fs/cifs/fs_context.h b/fs/cifs/fs_context.h
index f217bd600c1e..1ac5e1d202b6 100644
--- a/fs/cifs/fs_context.h
+++ b/fs/cifs/fs_context.h
@@ -152,6 +152,7 @@ struct smb3_fs_context {
 	bool rootfs:1; /* if it's a SMB root file system */
 };
 
-int cifs_parse_security_flavors(char *value, struct smb3_fs_context *ctx);
+extern int cifs_parse_security_flavors(char *value, struct smb3_fs_context *ctx);
+extern int smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx);
 
 #endif
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 03/21] cifs: move the enum for cifs parameters into fs_context.h
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
  2020-12-07 23:36 ` [PATCH 02/21] cifs: rename dup_vol to smb3_fs_context_dup and move it into fs_context.c Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 04/21] cifs: move cifs_parse_devname to fs_context.c Ronnie Sahlberg
                   ` (17 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/connect.c    | 57 ------------------------------
 fs/cifs/fs_context.h | 97 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 97 insertions(+), 57 deletions(-)

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 35bc1f56f053..17e9e95d54e5 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -73,63 +73,6 @@ extern bool disable_legacy_dialects;
 /* Drop the connection to not overload the server */
 #define NUM_STATUS_IO_TIMEOUT   5
 
-enum {
-	/* Mount options that take no arguments */
-	Opt_user_xattr, Opt_nouser_xattr,
-	Opt_forceuid, Opt_noforceuid,
-	Opt_forcegid, Opt_noforcegid,
-	Opt_noblocksend, Opt_noautotune, Opt_nolease,
-	Opt_hard, Opt_soft, Opt_perm, Opt_noperm, Opt_nodelete,
-	Opt_mapposix, Opt_nomapposix,
-	Opt_mapchars, Opt_nomapchars, Opt_sfu,
-	Opt_nosfu, Opt_nodfs, Opt_posixpaths,
-	Opt_noposixpaths, Opt_nounix, Opt_unix,
-	Opt_nocase,
-	Opt_brl, Opt_nobrl,
-	Opt_handlecache, Opt_nohandlecache,
-	Opt_forcemandatorylock, Opt_setuidfromacl, Opt_setuids,
-	Opt_nosetuids, Opt_dynperm, Opt_nodynperm,
-	Opt_nohard, Opt_nosoft,
-	Opt_nointr, Opt_intr,
-	Opt_nostrictsync, Opt_strictsync,
-	Opt_serverino, Opt_noserverino,
-	Opt_rwpidforward, Opt_cifsacl, Opt_nocifsacl,
-	Opt_acl, Opt_noacl, Opt_locallease,
-	Opt_sign, Opt_ignore_signature, Opt_seal, Opt_noac,
-	Opt_fsc, Opt_mfsymlinks,
-	Opt_multiuser, Opt_sloppy, Opt_nosharesock,
-	Opt_persistent, Opt_nopersistent,
-	Opt_resilient, Opt_noresilient,
-	Opt_domainauto, Opt_rdma, Opt_modesid, Opt_rootfs,
-	Opt_multichannel, Opt_nomultichannel,
-	Opt_compress,
-
-	/* Mount options which take numeric value */
-	Opt_backupuid, Opt_backupgid, Opt_uid,
-	Opt_cruid, Opt_gid, Opt_file_mode,
-	Opt_dirmode, Opt_port,
-	Opt_min_enc_offload,
-	Opt_blocksize, Opt_rsize, Opt_wsize, Opt_actimeo,
-	Opt_echo_interval, Opt_max_credits, Opt_handletimeout,
-	Opt_snapshot, Opt_max_channels,
-
-	/* Mount options which take string value */
-	Opt_user, Opt_pass, Opt_ip,
-	Opt_domain, Opt_srcaddr, Opt_iocharset,
-	Opt_netbiosname, Opt_servern,
-	Opt_ver, Opt_vers, Opt_sec, Opt_cache,
-
-	/* Mount options to be ignored */
-	Opt_ignore,
-
-	/* Options which could be blank */
-	Opt_blank_pass,
-	Opt_blank_user,
-	Opt_blank_ip,
-
-	Opt_err
-};
-
 static const match_table_t cifs_mount_option_tokens = {
 
 	{ Opt_user_xattr, "user_xattr" },
diff --git a/fs/cifs/fs_context.h b/fs/cifs/fs_context.h
index 1ac5e1d202b6..3a66199f3cb7 100644
--- a/fs/cifs/fs_context.h
+++ b/fs/cifs/fs_context.h
@@ -53,6 +53,103 @@ enum cifs_sec_param {
 	Opt_sec_err
 };
 
+enum cifs_param {
+	/* Mount options that take no arguments */
+	Opt_user_xattr, Opt_nouser_xattr,
+	Opt_forceuid, Opt_noforceuid,
+	Opt_forcegid, Opt_noforcegid,
+	Opt_noblocksend,
+	Opt_noautotune,
+	Opt_nolease,
+	Opt_hard, Opt_nohard,
+	Opt_soft, Opt_nosoft,
+	Opt_perm, Opt_noperm,
+	Opt_nodelete,
+	Opt_mapposix, Opt_nomapposix,
+	Opt_mapchars,
+	Opt_nomapchars,
+	Opt_sfu, Opt_nosfu,
+	Opt_nodfs,
+	Opt_posixpaths, Opt_noposixpaths,
+	Opt_unix, Opt_nounix,
+	Opt_nocase,
+	Opt_brl, Opt_nobrl,
+	Opt_handlecache, Opt_nohandlecache,
+	Opt_forcemandatorylock,
+	Opt_setuidfromacl,
+	Opt_setuids, Opt_nosetuids,
+	Opt_dynperm, Opt_nodynperm,
+	Opt_intr, Opt_nointr,
+	Opt_strictsync, Opt_nostrictsync,
+	Opt_serverino, Opt_noserverino,
+	Opt_rwpidforward,
+	Opt_cifsacl, Opt_nocifsacl,
+	Opt_acl, Opt_noacl,
+	Opt_locallease,
+	Opt_sign,
+	Opt_ignore_signature,
+	Opt_seal,
+	Opt_noac,
+	Opt_fsc,
+	Opt_mfsymlinks,
+	Opt_multiuser,
+	Opt_sloppy,
+	Opt_nosharesock,
+	Opt_persistent, Opt_nopersistent,
+	Opt_resilient, Opt_noresilient,
+	Opt_domainauto,
+	Opt_rdma,
+	Opt_modesid,
+	Opt_rootfs,
+	Opt_multichannel, Opt_nomultichannel,
+	Opt_compress,
+
+	/* Mount options which take numeric value */
+	Opt_backupuid,
+	Opt_backupgid,
+	Opt_uid,
+	Opt_cruid,
+	Opt_gid,
+	Opt_port,
+	Opt_file_mode,
+	Opt_dirmode,
+	Opt_min_enc_offload,
+	Opt_blocksize,
+	Opt_rsize,
+	Opt_wsize,
+	Opt_actimeo,
+	Opt_echo_interval,
+	Opt_max_credits,
+	Opt_snapshot,
+	Opt_max_channels,
+	Opt_handletimeout,
+
+	/* Mount options which take string value */
+	Opt_source,
+	Opt_user,
+	Opt_pass,
+	Opt_ip,
+	Opt_domain,
+	Opt_srcaddr,
+	Opt_iocharset,
+	Opt_netbiosname,
+	Opt_servern,
+	Opt_ver,
+	Opt_vers,
+	Opt_sec,
+	Opt_cache,
+
+	/* Mount options to be ignored */
+	Opt_ignore,
+
+	/* Options which could be blank */
+	Opt_blank_pass,
+	Opt_blank_user,
+	Opt_blank_ip,
+
+	Opt_err
+};
+
 struct smb3_fs_context {
 	bool uid_specified;
 	bool gid_specified;
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 04/21] cifs: move cifs_parse_devname to fs_context.c
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
  2020-12-07 23:36 ` [PATCH 02/21] cifs: rename dup_vol to smb3_fs_context_dup and move it into fs_context.c Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 03/21] cifs: move the enum for cifs parameters into fs_context.h Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 05/21] cifs: switch to new mount api Ronnie Sahlberg
                   ` (16 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/cifsproto.h  |  1 +
 fs/cifs/connect.c    | 59 ++--------------------------------------------------
 fs/cifs/fs_context.c | 56 +++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 59 insertions(+), 57 deletions(-)

diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 13ce85af1204..aa66a6b9aaf5 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -89,6 +89,7 @@ extern void cifs_mid_q_entry_release(struct mid_q_entry *midEntry);
 extern void cifs_wake_up_task(struct mid_q_entry *mid);
 extern int cifs_handle_standard(struct TCP_Server_Info *server,
 				struct mid_q_entry *mid);
+extern int smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx);
 extern bool cifs_match_ipaddr(struct sockaddr *srcaddr, struct sockaddr *rhs);
 extern int cifs_discard_remaining_data(struct TCP_Server_Info *server);
 extern int cifs_call_async(struct TCP_Server_Info *server,
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 17e9e95d54e5..c447ace656ed 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1256,61 +1256,6 @@ static int get_option_gid(substring_t args[], kgid_t *result)
 	return 0;
 }
 
-/*
- * Parse a devname into substrings and populate the vol->UNC and vol->prepath
- * fields with the result. Returns 0 on success and an error otherwise.
- */
-static int
-cifs_parse_devname(const char *devname, struct smb3_fs_context *ctx)
-{
-	char *pos;
-	const char *delims = "/\\";
-	size_t len;
-
-	if (unlikely(!devname || !*devname)) {
-		cifs_dbg(VFS, "Device name not specified\n");
-		return -EINVAL;
-	}
-
-	/* make sure we have a valid UNC double delimiter prefix */
-	len = strspn(devname, delims);
-	if (len != 2)
-		return -EINVAL;
-
-	/* find delimiter between host and sharename */
-	pos = strpbrk(devname + 2, delims);
-	if (!pos)
-		return -EINVAL;
-
-	/* skip past delimiter */
-	++pos;
-
-	/* now go until next delimiter or end of string */
-	len = strcspn(pos, delims);
-
-	/* move "pos" up to delimiter or NULL */
-	pos += len;
-	ctx->UNC = kstrndup(devname, pos - devname, GFP_KERNEL);
-	if (!ctx->UNC)
-		return -ENOMEM;
-
-	convert_delimiter(ctx->UNC, '\\');
-
-	/* skip any delimiter */
-	if (*pos == '/' || *pos == '\\')
-		pos++;
-
-	/* If pos is NULL then no prepath */
-	if (!*pos)
-		return 0;
-
-	ctx->prepath = kstrdup(pos, GFP_KERNEL);
-	if (!ctx->prepath)
-		return -ENOMEM;
-
-	return 0;
-}
-
 static int
 cifs_parse_mount_options(const char *mountdata, const char *devname,
 			 struct smb3_fs_context *ctx, bool is_smb3)
@@ -1414,7 +1359,7 @@ cifs_parse_mount_options(const char *mountdata, const char *devname,
 	ctx->backupuid_specified = false; /* no backup intent for a user */
 	ctx->backupgid_specified = false; /* no backup intent for a group */
 
-	switch (cifs_parse_devname(devname, ctx)) {
+	switch (smb3_parse_devname(devname, ctx)) {
 	case 0:
 		break;
 	case -ENOMEM:
@@ -4534,7 +4479,7 @@ static int check_dfs_prepath(struct cifs_sb_info *cifs_sb, struct smb3_fs_contex
 			struct smb3_fs_context v = {NULL};
 			/* if @path contains a tree name, skip it in the prefix path */
 			if (added_treename) {
-				rc = cifs_parse_devname(path, &v);
+				rc = smb3_parse_devname(path, &v);
 				if (rc)
 					break;
 				rc = -EREMOTE;
diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
index 301201903b45..3b15f9a882b2 100644
--- a/fs/cifs/fs_context.c
+++ b/fs/cifs/fs_context.c
@@ -260,3 +260,59 @@ smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx
 
 	return rc;
 }
+
+/*
+ * Parse a devname into substrings and populate the ctx->UNC and ctx->prepath
+ * fields with the result. Returns 0 on success and an error otherwise.
+ */
+int
+smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx)
+{
+	char *pos;
+	const char *delims = "/\\";
+	size_t len;
+
+	if (unlikely(!devname || !*devname)) {
+		cifs_dbg(VFS, "Device name not specified\n");
+		return -EINVAL;
+	}
+
+	/* make sure we have a valid UNC double delimiter prefix */
+	len = strspn(devname, delims);
+	if (len != 2)
+		return -EINVAL;
+
+	/* find delimiter between host and sharename */
+	pos = strpbrk(devname + 2, delims);
+	if (!pos)
+		return -EINVAL;
+
+	/* skip past delimiter */
+	++pos;
+
+	/* now go until next delimiter or end of string */
+	len = strcspn(pos, delims);
+
+	/* move "pos" up to delimiter or NULL */
+	pos += len;
+	ctx->UNC = kstrndup(devname, pos - devname, GFP_KERNEL);
+	if (!ctx->UNC)
+		return -ENOMEM;
+
+	convert_delimiter(ctx->UNC, '\\');
+
+	/* skip any delimiter */
+	if (*pos == '/' || *pos == '\\')
+		pos++;
+
+	/* If pos is NULL then no prepath */
+	if (!*pos)
+		return 0;
+
+	ctx->prepath = kstrdup(pos, GFP_KERNEL);
+	if (!ctx->prepath)
+		return -ENOMEM;
+
+	return 0;
+}
+
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 05/21] cifs: switch to new mount api
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
                   ` (2 preceding siblings ...)
  2020-12-07 23:36 ` [PATCH 04/21] cifs: move cifs_parse_devname to fs_context.c Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 06/21] cifs: remove the devname argument to cifs_compose_mount_options Ronnie Sahlberg
                   ` (15 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/cifs_dfs_ref.c |    4 +
 fs/cifs/cifsencrypt.c  |    5 +
 fs/cifs/cifsfs.c       |   54 +--
 fs/cifs/cifsfs.h       |    4 +
 fs/cifs/cifsproto.h    |    5 +-
 fs/cifs/connect.c      | 1154 +-----------------------------------------------
 fs/cifs/dfs_cache.c    |    8 +-
 fs/cifs/fs_context.c   | 1067 ++++++++++++++++++++++++++++++++++++++++----
 fs/cifs/fs_context.h   |   75 ++--
 fs/cifs/sess.c         |    2 +-
 10 files changed, 1095 insertions(+), 1283 deletions(-)

diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index cc3ada12848d..4b0b9cfe2ab1 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -275,6 +275,10 @@ static struct vfsmount *cifs_dfs_do_mount(struct dentry *mntpt,
 
 	convert_delimiter(devname, '/');
 
+	/* TODO: change to call fs_context_for_mount(), fill in context directly, call fc_mount */
+
+	/* See afs_mntpt_do_automount in fs/afs/mntpt.c for an example */
+
 	/* strip first '\' from fullpath */
 	mountdata = cifs_compose_mount_options(cifs_sb->mountdata,
 					       fullpath + 1, NULL, NULL);
diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c
index 9daa256f69d4..85734de318f6 100644
--- a/fs/cifs/cifsencrypt.c
+++ b/fs/cifs/cifsencrypt.c
@@ -661,6 +661,11 @@ setup_ntlmv2_rsp(struct cifs_ses *ses, const struct nls_table *nls_cp)
 	unsigned char *tiblob = NULL; /* target info blob */
 	__le64 rsp_timestamp;
 
+	if (nls_cp == NULL) {
+		cifs_dbg(VFS, "setup_ntlmv2_rsp called with nls_cp==NULL\n");
+		return -EINVAL;
+	}
+
 	if (ses->server->negflavor == CIFS_NEGFLAVOR_EXTENDED) {
 		if (!ses->domainName) {
 			if (ses->domainAuto) {
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 9fb85fcff6ae..907c82428c42 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -682,13 +682,6 @@ static int cifs_show_stats(struct seq_file *s, struct dentry *root)
 }
 #endif
 
-static int cifs_remount(struct super_block *sb, int *flags, char *data)
-{
-	sync_filesystem(sb);
-	*flags |= SB_NODIRATIME;
-	return 0;
-}
-
 static int cifs_drop_inode(struct inode *inode)
 {
 	struct cifs_sb_info *cifs_sb = CIFS_SB(inode->i_sb);
@@ -710,7 +703,6 @@ static const struct super_operations cifs_super_ops = {
 	as opens */
 	.show_options = cifs_show_options,
 	.umount_begin   = cifs_umount_begin,
-	.remount_fs = cifs_remount,
 #ifdef CONFIG_CIFS_STATS2
 	.show_stats = cifs_show_stats,
 #endif
@@ -778,9 +770,9 @@ static int cifs_set_super(struct super_block *sb, void *data)
 	return set_anon_super(sb, NULL);
 }
 
-static struct dentry *
+struct dentry *
 cifs_smb3_do_mount(struct file_system_type *fs_type,
-	      int flags, const char *dev_name, void *data, bool is_smb3)
+	      int flags, struct smb3_fs_context *old_ctx)
 {
 	int rc;
 	struct super_block *sb;
@@ -794,13 +786,24 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
 	 *	If CIFS_DEBUG && cifs_FYI
 	 */
 	if (cifsFYI)
-		cifs_dbg(FYI, "Devname: %s flags: %d\n", dev_name, flags);
+		cifs_dbg(FYI, "Devname: %s flags: %d\n", old_ctx->UNC, flags);
 	else
-		cifs_info("Attempting to mount %s\n", dev_name);
+		cifs_info("Attempting to mount %s\n", old_ctx->UNC);
+
+	ctx = kzalloc(sizeof(struct smb3_fs_context), GFP_KERNEL);
+	if (!ctx)
+		return ERR_PTR(-ENOMEM);
+	rc = smb3_fs_context_dup(ctx, old_ctx);
+	if (rc) {
+		root = ERR_PTR(rc);
+		goto out;
+	}
 
-	ctx = cifs_get_volume_info((char *)data, dev_name, is_smb3);
-	if (IS_ERR(ctx))
-		return ERR_CAST(ctx);
+	rc = cifs_setup_volume_info(ctx);
+	if (rc) {
+		root = ERR_PTR(rc);
+		goto out;
+	}
 
 	cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
 	if (cifs_sb == NULL) {
@@ -808,7 +811,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
 		goto out_nls;
 	}
 
-	cifs_sb->mountdata = kstrndup(data, PAGE_SIZE, GFP_KERNEL);
+	cifs_sb->mountdata = kstrndup(ctx->mount_options, PAGE_SIZE, GFP_KERNEL);
 	if (cifs_sb->mountdata == NULL) {
 		root = ERR_PTR(-ENOMEM);
 		goto out_free;
@@ -878,19 +881,6 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
 	goto out;
 }
 
-static struct dentry *
-smb3_do_mount(struct file_system_type *fs_type,
-	      int flags, const char *dev_name, void *data)
-{
-	return cifs_smb3_do_mount(fs_type, flags, dev_name, data, true);
-}
-
-static struct dentry *
-cifs_do_mount(struct file_system_type *fs_type,
-	      int flags, const char *dev_name, void *data)
-{
-	return cifs_smb3_do_mount(fs_type, flags, dev_name, data, false);
-}
 
 static ssize_t
 cifs_loose_read_iter(struct kiocb *iocb, struct iov_iter *iter)
@@ -1027,7 +1017,8 @@ cifs_setlease(struct file *file, long arg, struct file_lock **lease, void **priv
 struct file_system_type cifs_fs_type = {
 	.owner = THIS_MODULE,
 	.name = "cifs",
-	.mount = cifs_do_mount,
+	.init_fs_context = smb3_init_fs_context,
+	.parameters = smb3_fs_parameters,
 	.kill_sb = cifs_kill_sb,
 	.fs_flags = FS_RENAME_DOES_D_MOVE,
 };
@@ -1036,7 +1027,8 @@ MODULE_ALIAS_FS("cifs");
 static struct file_system_type smb3_fs_type = {
 	.owner = THIS_MODULE,
 	.name = "smb3",
-	.mount = smb3_do_mount,
+	.init_fs_context = smb3_init_fs_context,
+	.parameters = smb3_fs_parameters,
 	.kill_sb = cifs_kill_sb,
 	.fs_flags = FS_RENAME_DOES_D_MOVE,
 };
diff --git a/fs/cifs/cifsfs.h b/fs/cifs/cifsfs.h
index 99b3180c613a..624449b47cc4 100644
--- a/fs/cifs/cifsfs.h
+++ b/fs/cifs/cifsfs.h
@@ -152,6 +152,10 @@ extern long cifs_ioctl(struct file *filep, unsigned int cmd, unsigned long arg);
 extern void cifs_setsize(struct inode *inode, loff_t offset);
 extern int cifs_truncate_page(struct address_space *mapping, loff_t from);
 
+struct smb3_fs_context;
+extern struct dentry *cifs_smb3_do_mount(struct file_system_type *fs_type,
+					 int flags, struct smb3_fs_context *ctx);
+
 #ifdef CONFIG_CIFS_NFSD_EXPORT
 extern const struct export_operations cifs_export_ops;
 #endif /* CONFIG_CIFS_NFSD_EXPORT */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index aa66a6b9aaf5..49a122978772 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -239,8 +239,6 @@ extern int cifs_setup_cifs_sb(struct smb3_fs_context *ctx,
 			       struct cifs_sb_info *cifs_sb);
 extern int cifs_match_super(struct super_block *, void *);
 extern void cifs_cleanup_volume_info(struct smb3_fs_context *ctx);
-extern struct smb3_fs_context *cifs_get_volume_info(char *mount_data,
-					    const char *devname, bool is_smb3);
 extern int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx);
 extern void cifs_umount(struct cifs_sb_info *);
 extern void cifs_mark_open_files_invalid(struct cifs_tcon *tcon);
@@ -554,8 +552,7 @@ extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8,
 			unsigned char *p24);
 
 extern int
-cifs_setup_volume_info(struct smb3_fs_context *ctx, char *mount_data,
-		       const char *devname, bool is_smb3);
+cifs_setup_volume_info(struct smb3_fs_context *ctx);
 extern void
 cifs_cleanup_volume_info_contents(struct smb3_fs_context *ctx);
 
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index c447ace656ed..081e61a212cd 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -73,156 +73,6 @@ extern bool disable_legacy_dialects;
 /* Drop the connection to not overload the server */
 #define NUM_STATUS_IO_TIMEOUT   5
 
-static const match_table_t cifs_mount_option_tokens = {
-
-	{ Opt_user_xattr, "user_xattr" },
-	{ Opt_nouser_xattr, "nouser_xattr" },
-	{ Opt_forceuid, "forceuid" },
-	{ Opt_noforceuid, "noforceuid" },
-	{ Opt_forcegid, "forcegid" },
-	{ Opt_noforcegid, "noforcegid" },
-	{ Opt_noblocksend, "noblocksend" },
-	{ Opt_noautotune, "noautotune" },
-	{ Opt_nolease, "nolease" },
-	{ Opt_hard, "hard" },
-	{ Opt_soft, "soft" },
-	{ Opt_perm, "perm" },
-	{ Opt_noperm, "noperm" },
-	{ Opt_nodelete, "nodelete" },
-	{ Opt_mapchars, "mapchars" }, /* SFU style */
-	{ Opt_nomapchars, "nomapchars" },
-	{ Opt_mapposix, "mapposix" }, /* SFM style */
-	{ Opt_nomapposix, "nomapposix" },
-	{ Opt_sfu, "sfu" },
-	{ Opt_nosfu, "nosfu" },
-	{ Opt_nodfs, "nodfs" },
-	{ Opt_posixpaths, "posixpaths" },
-	{ Opt_noposixpaths, "noposixpaths" },
-	{ Opt_nounix, "nounix" },
-	{ Opt_nounix, "nolinux" },
-	{ Opt_nounix, "noposix" },
-	{ Opt_unix, "unix" },
-	{ Opt_unix, "linux" },
-	{ Opt_unix, "posix" },
-	{ Opt_nocase, "nocase" },
-	{ Opt_nocase, "ignorecase" },
-	{ Opt_brl, "brl" },
-	{ Opt_nobrl, "nobrl" },
-	{ Opt_handlecache, "handlecache" },
-	{ Opt_nohandlecache, "nohandlecache" },
-	{ Opt_nobrl, "nolock" },
-	{ Opt_forcemandatorylock, "forcemandatorylock" },
-	{ Opt_forcemandatorylock, "forcemand" },
-	{ Opt_setuids, "setuids" },
-	{ Opt_nosetuids, "nosetuids" },
-	{ Opt_setuidfromacl, "idsfromsid" },
-	{ Opt_dynperm, "dynperm" },
-	{ Opt_nodynperm, "nodynperm" },
-	{ Opt_nohard, "nohard" },
-	{ Opt_nosoft, "nosoft" },
-	{ Opt_nointr, "nointr" },
-	{ Opt_intr, "intr" },
-	{ Opt_nostrictsync, "nostrictsync" },
-	{ Opt_strictsync, "strictsync" },
-	{ Opt_serverino, "serverino" },
-	{ Opt_noserverino, "noserverino" },
-	{ Opt_rwpidforward, "rwpidforward" },
-	{ Opt_modesid, "modefromsid" },
-	{ Opt_cifsacl, "cifsacl" },
-	{ Opt_nocifsacl, "nocifsacl" },
-	{ Opt_acl, "acl" },
-	{ Opt_noacl, "noacl" },
-	{ Opt_locallease, "locallease" },
-	{ Opt_sign, "sign" },
-	{ Opt_ignore_signature, "signloosely" },
-	{ Opt_seal, "seal" },
-	{ Opt_noac, "noac" },
-	{ Opt_fsc, "fsc" },
-	{ Opt_mfsymlinks, "mfsymlinks" },
-	{ Opt_multiuser, "multiuser" },
-	{ Opt_sloppy, "sloppy" },
-	{ Opt_nosharesock, "nosharesock" },
-	{ Opt_persistent, "persistenthandles"},
-	{ Opt_nopersistent, "nopersistenthandles"},
-	{ Opt_resilient, "resilienthandles"},
-	{ Opt_noresilient, "noresilienthandles"},
-	{ Opt_domainauto, "domainauto"},
-	{ Opt_rdma, "rdma"},
-	{ Opt_multichannel, "multichannel" },
-	{ Opt_nomultichannel, "nomultichannel" },
-
-	{ Opt_backupuid, "backupuid=%s" },
-	{ Opt_backupgid, "backupgid=%s" },
-	{ Opt_uid, "uid=%s" },
-	{ Opt_cruid, "cruid=%s" },
-	{ Opt_gid, "gid=%s" },
-	{ Opt_file_mode, "file_mode=%s" },
-	{ Opt_dirmode, "dirmode=%s" },
-	{ Opt_dirmode, "dir_mode=%s" },
-	{ Opt_port, "port=%s" },
-	{ Opt_min_enc_offload, "esize=%s" },
-	{ Opt_blocksize, "bsize=%s" },
-	{ Opt_rsize, "rsize=%s" },
-	{ Opt_wsize, "wsize=%s" },
-	{ Opt_actimeo, "actimeo=%s" },
-	{ Opt_handletimeout, "handletimeout=%s" },
-	{ Opt_echo_interval, "echo_interval=%s" },
-	{ Opt_max_credits, "max_credits=%s" },
-	{ Opt_snapshot, "snapshot=%s" },
-	{ Opt_max_channels, "max_channels=%s" },
-	{ Opt_compress, "compress=%s" },
-
-	{ Opt_blank_user, "user=" },
-	{ Opt_blank_user, "username=" },
-	{ Opt_user, "user=%s" },
-	{ Opt_user, "username=%s" },
-	{ Opt_blank_pass, "pass=" },
-	{ Opt_blank_pass, "password=" },
-	{ Opt_pass, "pass=%s" },
-	{ Opt_pass, "password=%s" },
-	{ Opt_blank_ip, "ip=" },
-	{ Opt_blank_ip, "addr=" },
-	{ Opt_ip, "ip=%s" },
-	{ Opt_ip, "addr=%s" },
-	{ Opt_ignore, "unc=%s" },
-	{ Opt_ignore, "target=%s" },
-	{ Opt_ignore, "path=%s" },
-	{ Opt_domain, "dom=%s" },
-	{ Opt_domain, "domain=%s" },
-	{ Opt_domain, "workgroup=%s" },
-	{ Opt_srcaddr, "srcaddr=%s" },
-	{ Opt_ignore, "prefixpath=%s" },
-	{ Opt_iocharset, "iocharset=%s" },
-	{ Opt_netbiosname, "netbiosname=%s" },
-	{ Opt_servern, "servern=%s" },
-	{ Opt_ver, "ver=%s" },
-	{ Opt_vers, "vers=%s" },
-	{ Opt_sec, "sec=%s" },
-	{ Opt_cache, "cache=%s" },
-
-	{ Opt_ignore, "cred" },
-	{ Opt_ignore, "credentials" },
-	{ Opt_ignore, "cred=%s" },
-	{ Opt_ignore, "credentials=%s" },
-	{ Opt_ignore, "guest" },
-	{ Opt_ignore, "rw" },
-	{ Opt_ignore, "ro" },
-	{ Opt_ignore, "suid" },
-	{ Opt_ignore, "nosuid" },
-	{ Opt_ignore, "exec" },
-	{ Opt_ignore, "noexec" },
-	{ Opt_ignore, "nodev" },
-	{ Opt_ignore, "noauto" },
-	{ Opt_ignore, "dev" },
-	{ Opt_ignore, "mand" },
-	{ Opt_ignore, "nomand" },
-	{ Opt_ignore, "relatime" },
-	{ Opt_ignore, "_netdev" },
-	{ Opt_rootfs, "rootfs" },
-
-	{ Opt_err, NULL }
-};
-
 static int ip_connect(struct TCP_Server_Info *server);
 static int generic_ip_connect(struct TCP_Server_Info *server);
 static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink);
@@ -1206,960 +1056,6 @@ extract_hostname(const char *unc)
 	return dst;
 }
 
-static int get_option_ul(substring_t args[], unsigned long *option)
-{
-	int rc;
-	char *string;
-
-	string = match_strdup(args);
-	if (string == NULL)
-		return -ENOMEM;
-	rc = kstrtoul(string, 0, option);
-	kfree(string);
-
-	return rc;
-}
-
-static int get_option_uid(substring_t args[], kuid_t *result)
-{
-	unsigned long value;
-	kuid_t uid;
-	int rc;
-
-	rc = get_option_ul(args, &value);
-	if (rc)
-		return rc;
-
-	uid = make_kuid(current_user_ns(), value);
-	if (!uid_valid(uid))
-		return -EINVAL;
-
-	*result = uid;
-	return 0;
-}
-
-static int get_option_gid(substring_t args[], kgid_t *result)
-{
-	unsigned long value;
-	kgid_t gid;
-	int rc;
-
-	rc = get_option_ul(args, &value);
-	if (rc)
-		return rc;
-
-	gid = make_kgid(current_user_ns(), value);
-	if (!gid_valid(gid))
-		return -EINVAL;
-
-	*result = gid;
-	return 0;
-}
-
-static int
-cifs_parse_mount_options(const char *mountdata, const char *devname,
-			 struct smb3_fs_context *ctx, bool is_smb3)
-{
-	char *data, *end;
-	char *mountdata_copy = NULL, *options;
-	unsigned int  temp_len, i, j;
-	char separator[2];
-	short int override_uid = -1;
-	short int override_gid = -1;
-	bool uid_specified = false;
-	bool gid_specified = false;
-	bool sloppy = false;
-	char *invalid = NULL;
-	char *nodename = utsname()->nodename;
-	char *string = NULL;
-	char *tmp_end, *value;
-	char delim;
-	bool got_ip = false;
-	bool got_version = false;
-	unsigned short port = 0;
-	struct sockaddr *dstaddr = (struct sockaddr *)&ctx->dstaddr;
-
-	separator[0] = ',';
-	separator[1] = 0;
-	delim = separator[0];
-
-	/* ensure we always start with zeroed-out ctx */
-	memset(ctx, 0, sizeof(*ctx));
-
-	/*
-	 * does not have to be perfect mapping since field is
-	 * informational, only used for servers that do not support
-	 * port 445 and it can be overridden at mount time
-	 */
-	memset(ctx->source_rfc1001_name, 0x20, RFC1001_NAME_LEN);
-	for (i = 0; i < strnlen(nodename, RFC1001_NAME_LEN); i++)
-		ctx->source_rfc1001_name[i] = toupper(nodename[i]);
-
-	ctx->source_rfc1001_name[RFC1001_NAME_LEN] = 0;
-	/* null target name indicates to use *SMBSERVR default called name
-	   if we end up sending RFC1001 session initialize */
-	ctx->target_rfc1001_name[0] = 0;
-	ctx->cred_uid = current_uid();
-	ctx->linux_uid = current_uid();
-	ctx->linux_gid = current_gid();
-	ctx->bsize = 1024 * 1024; /* can improve cp performance significantly */
-	/*
-	 * default to SFM style remapping of seven reserved characters
-	 * unless user overrides it or we negotiate CIFS POSIX where
-	 * it is unnecessary.  Can not simultaneously use more than one mapping
-	 * since then readdir could list files that open could not open
-	 */
-	ctx->remap = true;
-
-	/* default to only allowing write access to owner of the mount */
-	ctx->dir_mode = ctx->file_mode = S_IRUGO | S_IXUGO | S_IWUSR;
-
-	/* ctx->retry default is 0 (i.e. "soft" limited retry not hard retry) */
-	/* default is always to request posix paths. */
-	ctx->posix_paths = 1;
-	/* default to using server inode numbers where available */
-	ctx->server_ino = 1;
-
-	/* default is to use strict cifs caching semantics */
-	ctx->strict_io = true;
-
-	ctx->actimeo = CIFS_DEF_ACTIMEO;
-
-	/* Most clients set timeout to 0, allows server to use its default */
-	ctx->handle_timeout = 0; /* See MS-SMB2 spec section 2.2.14.2.12 */
-
-	/* offer SMB2.1 and later (SMB3 etc). Secure and widely accepted */
-	ctx->ops = &smb30_operations;
-	ctx->vals = &smbdefault_values;
-
-	ctx->echo_interval = SMB_ECHO_INTERVAL_DEFAULT;
-
-	/* default to no multichannel (single server connection) */
-	ctx->multichannel = false;
-	ctx->max_channels = 1;
-
-	if (!mountdata)
-		goto cifs_parse_mount_err;
-
-	mountdata_copy = kstrndup(mountdata, PAGE_SIZE, GFP_KERNEL);
-	if (!mountdata_copy)
-		goto cifs_parse_mount_err;
-
-	options = mountdata_copy;
-	end = options + strlen(options);
-
-	if (strncmp(options, "sep=", 4) == 0) {
-		if (options[4] != 0) {
-			separator[0] = options[4];
-			options += 5;
-		} else {
-			cifs_dbg(FYI, "Null separator not allowed\n");
-		}
-	}
-	ctx->backupuid_specified = false; /* no backup intent for a user */
-	ctx->backupgid_specified = false; /* no backup intent for a group */
-
-	switch (smb3_parse_devname(devname, ctx)) {
-	case 0:
-		break;
-	case -ENOMEM:
-		cifs_dbg(VFS, "Unable to allocate memory for devname\n");
-		goto cifs_parse_mount_err;
-	case -EINVAL:
-		cifs_dbg(VFS, "Malformed UNC in devname\n");
-		goto cifs_parse_mount_err;
-	default:
-		cifs_dbg(VFS, "Unknown error parsing devname\n");
-		goto cifs_parse_mount_err;
-	}
-
-	while ((data = strsep(&options, separator)) != NULL) {
-		substring_t args[MAX_OPT_ARGS];
-		unsigned long option;
-		int token;
-
-		if (!*data)
-			continue;
-
-		token = match_token(data, cifs_mount_option_tokens, args);
-
-		switch (token) {
-
-		/* Ingnore the following */
-		case Opt_ignore:
-			break;
-
-		/* Boolean values */
-		case Opt_user_xattr:
-			ctx->no_xattr = 0;
-			break;
-		case Opt_nouser_xattr:
-			ctx->no_xattr = 1;
-			break;
-		case Opt_forceuid:
-			override_uid = 1;
-			break;
-		case Opt_noforceuid:
-			override_uid = 0;
-			break;
-		case Opt_forcegid:
-			override_gid = 1;
-			break;
-		case Opt_noforcegid:
-			override_gid = 0;
-			break;
-		case Opt_noblocksend:
-			ctx->noblocksnd = 1;
-			break;
-		case Opt_noautotune:
-			ctx->noautotune = 1;
-			break;
-		case Opt_nolease:
-			ctx->no_lease = 1;
-			break;
-		case Opt_hard:
-			ctx->retry = 1;
-			break;
-		case Opt_soft:
-			ctx->retry = 0;
-			break;
-		case Opt_perm:
-			ctx->noperm = 0;
-			break;
-		case Opt_noperm:
-			ctx->noperm = 1;
-			break;
-		case Opt_nodelete:
-			ctx->nodelete = 1;
-			break;
-		case Opt_mapchars:
-			ctx->sfu_remap = true;
-			ctx->remap = false; /* disable SFM mapping */
-			break;
-		case Opt_nomapchars:
-			ctx->sfu_remap = false;
-			break;
-		case Opt_mapposix:
-			ctx->remap = true;
-			ctx->sfu_remap = false; /* disable SFU mapping */
-			break;
-		case Opt_nomapposix:
-			ctx->remap = false;
-			break;
-		case Opt_sfu:
-			ctx->sfu_emul = 1;
-			break;
-		case Opt_nosfu:
-			ctx->sfu_emul = 0;
-			break;
-		case Opt_nodfs:
-			ctx->nodfs = 1;
-			break;
-		case Opt_rootfs:
-#ifdef CONFIG_CIFS_ROOT
-			ctx->rootfs = true;
-#endif
-			break;
-		case Opt_posixpaths:
-			ctx->posix_paths = 1;
-			break;
-		case Opt_noposixpaths:
-			ctx->posix_paths = 0;
-			break;
-		case Opt_nounix:
-			if (ctx->linux_ext)
-				cifs_dbg(VFS,
-					"conflicting unix mount options\n");
-			ctx->no_linux_ext = 1;
-			break;
-		case Opt_unix:
-			if (ctx->no_linux_ext)
-				cifs_dbg(VFS,
-					"conflicting unix mount options\n");
-			ctx->linux_ext = 1;
-			break;
-		case Opt_nocase:
-			ctx->nocase = 1;
-			break;
-		case Opt_brl:
-			ctx->nobrl =  0;
-			break;
-		case Opt_nobrl:
-			ctx->nobrl =  1;
-			/*
-			 * turn off mandatory locking in mode
-			 * if remote locking is turned off since the
-			 * local vfs will do advisory
-			 */
-			if (ctx->file_mode ==
-				(S_IALLUGO & ~(S_ISUID | S_IXGRP)))
-				ctx->file_mode = S_IALLUGO;
-			break;
-		case Opt_nohandlecache:
-			ctx->nohandlecache = 1;
-			break;
-		case Opt_handlecache:
-			ctx->nohandlecache = 0;
-			break;
-		case Opt_forcemandatorylock:
-			ctx->mand_lock = 1;
-			break;
-		case Opt_setuids:
-			ctx->setuids = 1;
-			break;
-		case Opt_nosetuids:
-			ctx->setuids = 0;
-			break;
-		case Opt_setuidfromacl:
-			ctx->setuidfromacl = 1;
-			break;
-		case Opt_dynperm:
-			ctx->dynperm = true;
-			break;
-		case Opt_nodynperm:
-			ctx->dynperm = false;
-			break;
-		case Opt_nohard:
-			ctx->retry = 0;
-			break;
-		case Opt_nosoft:
-			ctx->retry = 1;
-			break;
-		case Opt_nointr:
-			ctx->intr = 0;
-			break;
-		case Opt_intr:
-			ctx->intr = 1;
-			break;
-		case Opt_nostrictsync:
-			ctx->nostrictsync = 1;
-			break;
-		case Opt_strictsync:
-			ctx->nostrictsync = 0;
-			break;
-		case Opt_serverino:
-			ctx->server_ino = 1;
-			break;
-		case Opt_noserverino:
-			ctx->server_ino = 0;
-			break;
-		case Opt_rwpidforward:
-			ctx->rwpidforward = 1;
-			break;
-		case Opt_modesid:
-			ctx->mode_ace = 1;
-			break;
-		case Opt_cifsacl:
-			ctx->cifs_acl = 1;
-			break;
-		case Opt_nocifsacl:
-			ctx->cifs_acl = 0;
-			break;
-		case Opt_acl:
-			ctx->no_psx_acl = 0;
-			break;
-		case Opt_noacl:
-			ctx->no_psx_acl = 1;
-			break;
-		case Opt_locallease:
-			ctx->local_lease = 1;
-			break;
-		case Opt_sign:
-			ctx->sign = true;
-			break;
-		case Opt_ignore_signature:
-			ctx->sign = true;
-			ctx->ignore_signature = true;
-			break;
-		case Opt_seal:
-			/* we do not do the following in secFlags because seal
-			 * is a per tree connection (mount) not a per socket
-			 * or per-smb connection option in the protocol
-			 * ctx->secFlg |= CIFSSEC_MUST_SEAL;
-			 */
-			ctx->seal = 1;
-			break;
-		case Opt_noac:
-			pr_warn("Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n");
-			break;
-		case Opt_fsc:
-#ifndef CONFIG_CIFS_FSCACHE
-			cifs_dbg(VFS, "FS-Cache support needs CONFIG_CIFS_FSCACHE kernel config option set\n");
-			goto cifs_parse_mount_err;
-#endif
-			ctx->fsc = true;
-			break;
-		case Opt_mfsymlinks:
-			ctx->mfsymlinks = true;
-			break;
-		case Opt_multiuser:
-			ctx->multiuser = true;
-			break;
-		case Opt_sloppy:
-			sloppy = true;
-			break;
-		case Opt_nosharesock:
-			ctx->nosharesock = true;
-			break;
-		case Opt_nopersistent:
-			ctx->nopersistent = true;
-			if (ctx->persistent) {
-				cifs_dbg(VFS,
-				  "persistenthandles mount options conflict\n");
-				goto cifs_parse_mount_err;
-			}
-			break;
-		case Opt_persistent:
-			ctx->persistent = true;
-			if ((ctx->nopersistent) || (ctx->resilient)) {
-				cifs_dbg(VFS,
-				  "persistenthandles mount options conflict\n");
-				goto cifs_parse_mount_err;
-			}
-			break;
-		case Opt_resilient:
-			ctx->resilient = true;
-			if (ctx->persistent) {
-				cifs_dbg(VFS,
-				  "persistenthandles mount options conflict\n");
-				goto cifs_parse_mount_err;
-			}
-			break;
-		case Opt_noresilient:
-			ctx->resilient = false; /* already the default */
-			break;
-		case Opt_domainauto:
-			ctx->domainauto = true;
-			break;
-		case Opt_rdma:
-			ctx->rdma = true;
-			break;
-		case Opt_multichannel:
-			ctx->multichannel = true;
-			/* if number of channels not specified, default to 2 */
-			if (ctx->max_channels < 2)
-				ctx->max_channels = 2;
-			break;
-		case Opt_nomultichannel:
-			ctx->multichannel = false;
-			ctx->max_channels = 1;
-			break;
-		case Opt_compress:
-			ctx->compression = UNKNOWN_TYPE;
-			cifs_dbg(VFS,
-				"SMB3 compression support is experimental\n");
-			break;
-
-		/* Numeric Values */
-		case Opt_backupuid:
-			if (get_option_uid(args, &ctx->backupuid)) {
-				cifs_dbg(VFS, "%s: Invalid backupuid value\n",
-					 __func__);
-				goto cifs_parse_mount_err;
-			}
-			ctx->backupuid_specified = true;
-			break;
-		case Opt_backupgid:
-			if (get_option_gid(args, &ctx->backupgid)) {
-				cifs_dbg(VFS, "%s: Invalid backupgid value\n",
-					 __func__);
-				goto cifs_parse_mount_err;
-			}
-			ctx->backupgid_specified = true;
-			break;
-		case Opt_uid:
-			if (get_option_uid(args, &ctx->linux_uid)) {
-				cifs_dbg(VFS, "%s: Invalid uid value\n",
-					 __func__);
-				goto cifs_parse_mount_err;
-			}
-			uid_specified = true;
-			break;
-		case Opt_cruid:
-			if (get_option_uid(args, &ctx->cred_uid)) {
-				cifs_dbg(VFS, "%s: Invalid cruid value\n",
-					 __func__);
-				goto cifs_parse_mount_err;
-			}
-			break;
-		case Opt_gid:
-			if (get_option_gid(args, &ctx->linux_gid)) {
-				cifs_dbg(VFS, "%s: Invalid gid value\n",
-					 __func__);
-				goto cifs_parse_mount_err;
-			}
-			gid_specified = true;
-			break;
-		case Opt_file_mode:
-			if (get_option_ul(args, &option)) {
-				cifs_dbg(VFS, "%s: Invalid file_mode value\n",
-					 __func__);
-				goto cifs_parse_mount_err;
-			}
-			ctx->file_mode = option;
-			break;
-		case Opt_dirmode:
-			if (get_option_ul(args, &option)) {
-				cifs_dbg(VFS, "%s: Invalid dir_mode value\n",
-					 __func__);
-				goto cifs_parse_mount_err;
-			}
-			ctx->dir_mode = option;
-			break;
-		case Opt_port:
-			if (get_option_ul(args, &option) ||
-			    option > USHRT_MAX) {
-				cifs_dbg(VFS, "%s: Invalid port value\n",
-					 __func__);
-				goto cifs_parse_mount_err;
-			}
-			port = (unsigned short)option;
-			break;
-		case Opt_min_enc_offload:
-			if (get_option_ul(args, &option)) {
-				cifs_dbg(VFS, "Invalid minimum encrypted read offload size (esize)\n");
-				goto cifs_parse_mount_err;
-			}
-			ctx->min_offload = option;
-			break;
-		case Opt_blocksize:
-			if (get_option_ul(args, &option)) {
-				cifs_dbg(VFS, "%s: Invalid blocksize value\n",
-					__func__);
-				goto cifs_parse_mount_err;
-			}
-			/*
-			 * inode blocksize realistically should never need to be
-			 * less than 16K or greater than 16M and default is 1MB.
-			 * Note that small inode block sizes (e.g. 64K) can lead
-			 * to very poor performance of common tools like cp and scp
-			 */
-			if ((option < CIFS_MAX_MSGSIZE) ||
-			   (option > (4 * SMB3_DEFAULT_IOSIZE))) {
-				cifs_dbg(VFS, "%s: Invalid blocksize\n",
-					__func__);
-				goto cifs_parse_mount_err;
-			}
-			ctx->bsize = option;
-			break;
-		case Opt_rsize:
-			if (get_option_ul(args, &option)) {
-				cifs_dbg(VFS, "%s: Invalid rsize value\n",
-					 __func__);
-				goto cifs_parse_mount_err;
-			}
-			ctx->rsize = option;
-			break;
-		case Opt_wsize:
-			if (get_option_ul(args, &option)) {
-				cifs_dbg(VFS, "%s: Invalid wsize value\n",
-					 __func__);
-				goto cifs_parse_mount_err;
-			}
-			ctx->wsize = option;
-			break;
-		case Opt_actimeo:
-			if (get_option_ul(args, &option)) {
-				cifs_dbg(VFS, "%s: Invalid actimeo value\n",
-					 __func__);
-				goto cifs_parse_mount_err;
-			}
-			ctx->actimeo = HZ * option;
-			if (ctx->actimeo > CIFS_MAX_ACTIMEO) {
-				cifs_dbg(VFS, "attribute cache timeout too large\n");
-				goto cifs_parse_mount_err;
-			}
-			break;
-		case Opt_handletimeout:
-			if (get_option_ul(args, &option)) {
-				cifs_dbg(VFS, "%s: Invalid handletimeout value\n",
-					 __func__);
-				goto cifs_parse_mount_err;
-			}
-			ctx->handle_timeout = option;
-			if (ctx->handle_timeout > SMB3_MAX_HANDLE_TIMEOUT) {
-				cifs_dbg(VFS, "Invalid handle cache timeout, longer than 16 minutes\n");
-				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;
-			}
-			ctx->echo_interval = option;
-			break;
-		case Opt_snapshot:
-			if (get_option_ul(args, &option)) {
-				cifs_dbg(VFS, "%s: Invalid snapshot time\n",
-					 __func__);
-				goto cifs_parse_mount_err;
-			}
-			ctx->snapshot_time = option;
-			break;
-		case Opt_max_credits:
-			if (get_option_ul(args, &option) || (option < 20) ||
-			    (option > 60000)) {
-				cifs_dbg(VFS, "%s: Invalid max_credits value\n",
-					 __func__);
-				goto cifs_parse_mount_err;
-			}
-			ctx->max_credits = option;
-			break;
-		case Opt_max_channels:
-			if (get_option_ul(args, &option) || option < 1 ||
-				option > CIFS_MAX_CHANNELS) {
-				cifs_dbg(VFS, "%s: Invalid max_channels value, needs to be 1-%d\n",
-					 __func__, CIFS_MAX_CHANNELS);
-				goto cifs_parse_mount_err;
-			}
-			ctx->max_channels = option;
-			break;
-
-		/* String Arguments */
-
-		case Opt_blank_user:
-			/* null user, ie. anonymous authentication */
-			ctx->nullauth = 1;
-			ctx->username = NULL;
-			break;
-		case Opt_user:
-			string = match_strdup(args);
-			if (string == NULL)
-				goto out_nomem;
-
-			if (strnlen(string, CIFS_MAX_USERNAME_LEN) >
-							CIFS_MAX_USERNAME_LEN) {
-				pr_warn("username too long\n");
-				goto cifs_parse_mount_err;
-			}
-
-			kfree(ctx->username);
-			ctx->username = kstrdup(string, GFP_KERNEL);
-			if (!ctx->username)
-				goto cifs_parse_mount_err;
-			break;
-		case Opt_blank_pass:
-			/* passwords have to be handled differently
-			 * to allow the character used for deliminator
-			 * to be passed within them
-			 */
-
-			/*
-			 * Check if this is a case where the  password
-			 * starts with a delimiter
-			 */
-			tmp_end = strchr(data, '=');
-			tmp_end++;
-			if (!(tmp_end < end && tmp_end[1] == delim)) {
-				/* No it is not. Set the password to NULL */
-				kfree_sensitive(ctx->password);
-				ctx->password = NULL;
-				break;
-			}
-			fallthrough;	/* to Opt_pass below */
-		case Opt_pass:
-			/* Obtain the value string */
-			value = strchr(data, '=');
-			value++;
-
-			/* Set tmp_end to end of the string */
-			tmp_end = (char *) value + strlen(value);
-
-			/* Check if following character is the deliminator
-			 * If yes, we have encountered a double deliminator
-			 * reset the NULL character to the deliminator
-			 */
-			if (tmp_end < end && tmp_end[1] == delim) {
-				tmp_end[0] = delim;
-
-				/* Keep iterating until we get to a single
-				 * deliminator OR the end
-				 */
-				while ((tmp_end = strchr(tmp_end, delim))
-					!= NULL && (tmp_end[1] == delim)) {
-						tmp_end = (char *) &tmp_end[2];
-				}
-
-				/* Reset var options to point to next element */
-				if (tmp_end) {
-					tmp_end[0] = '\0';
-					options = (char *) &tmp_end[1];
-				} else
-					/* Reached the end of the mount option
-					 * string */
-					options = end;
-			}
-
-			kfree_sensitive(ctx->password);
-			/* Now build new password string */
-			temp_len = strlen(value);
-			ctx->password = kzalloc(temp_len+1, GFP_KERNEL);
-			if (ctx->password == NULL) {
-				pr_warn("no memory for password\n");
-				goto cifs_parse_mount_err;
-			}
-
-			for (i = 0, j = 0; i < temp_len; i++, j++) {
-				ctx->password[j] = value[i];
-				if ((value[i] == delim) &&
-				     value[i+1] == delim)
-					/* skip the second deliminator */
-					i++;
-			}
-			ctx->password[j] = '\0';
-			break;
-		case Opt_blank_ip:
-			/* FIXME: should this be an error instead? */
-			got_ip = false;
-			break;
-		case Opt_ip:
-			string = match_strdup(args);
-			if (string == NULL)
-				goto out_nomem;
-
-			if (!cifs_convert_address(dstaddr, string,
-					strlen(string))) {
-				pr_err("bad ip= option (%s)\n", string);
-				goto cifs_parse_mount_err;
-			}
-			got_ip = true;
-			break;
-		case Opt_domain:
-			string = match_strdup(args);
-			if (string == NULL)
-				goto out_nomem;
-
-			if (strnlen(string, CIFS_MAX_DOMAINNAME_LEN)
-					== CIFS_MAX_DOMAINNAME_LEN) {
-				pr_warn("domain name too long\n");
-				goto cifs_parse_mount_err;
-			}
-
-			kfree(ctx->domainname);
-			ctx->domainname = kstrdup(string, GFP_KERNEL);
-			if (!ctx->domainname) {
-				pr_warn("no memory for domainname\n");
-				goto cifs_parse_mount_err;
-			}
-			cifs_dbg(FYI, "Domain name set\n");
-			break;
-		case Opt_srcaddr:
-			string = match_strdup(args);
-			if (string == NULL)
-				goto out_nomem;
-
-			if (!cifs_convert_address(
-					(struct sockaddr *)&ctx->srcaddr,
-					string, strlen(string))) {
-				pr_warn("Could not parse srcaddr: %s\n",
-					string);
-				goto cifs_parse_mount_err;
-			}
-			break;
-		case Opt_iocharset:
-			string = match_strdup(args);
-			if (string == NULL)
-				goto out_nomem;
-
-			if (strnlen(string, 1024) >= 65) {
-				pr_warn("iocharset name too long\n");
-				goto cifs_parse_mount_err;
-			}
-
-			 if (strncasecmp(string, "default", 7) != 0) {
-				kfree(ctx->iocharset);
-				ctx->iocharset = kstrdup(string,
-							 GFP_KERNEL);
-				if (!ctx->iocharset) {
-					pr_warn("no memory for charset\n");
-					goto cifs_parse_mount_err;
-				}
-			}
-			/* if iocharset not set then load_nls_default
-			 * is used by caller
-			 */
-			 cifs_dbg(FYI, "iocharset set to %s\n", string);
-			break;
-		case Opt_netbiosname:
-			string = match_strdup(args);
-			if (string == NULL)
-				goto out_nomem;
-
-			memset(ctx->source_rfc1001_name, 0x20,
-				RFC1001_NAME_LEN);
-			/*
-			 * FIXME: are there cases in which a comma can
-			 * be valid in workstation netbios name (and
-			 * need special handling)?
-			 */
-			for (i = 0; i < RFC1001_NAME_LEN; i++) {
-				/* don't ucase netbiosname for user */
-				if (string[i] == 0)
-					break;
-				ctx->source_rfc1001_name[i] = string[i];
-			}
-			/* The string has 16th byte zero still from
-			 * set at top of the function
-			 */
-			if (i == RFC1001_NAME_LEN && string[i] != 0)
-				pr_warn("netbiosname longer than 15 truncated\n");
-			break;
-		case Opt_servern:
-			/* servernetbiosname specified override *SMBSERVER */
-			string = match_strdup(args);
-			if (string == NULL)
-				goto out_nomem;
-
-			/* last byte, type, is 0x20 for servr type */
-			memset(ctx->target_rfc1001_name, 0x20,
-				RFC1001_NAME_LEN_WITH_NULL);
-
-			/* BB are there cases in which a comma can be
-			   valid in this workstation netbios name
-			   (and need special handling)? */
-
-			/* user or mount helper must uppercase the
-			   netbios name */
-			for (i = 0; i < 15; i++) {
-				if (string[i] == 0)
-					break;
-				ctx->target_rfc1001_name[i] = string[i];
-			}
-			/* The string has 16th byte zero still from
-			   set at top of the function  */
-			if (i == RFC1001_NAME_LEN && string[i] != 0)
-				pr_warn("server netbiosname longer than 15 truncated\n");
-			break;
-		case Opt_ver:
-			/* version of mount userspace tools, not dialect */
-			string = match_strdup(args);
-			if (string == NULL)
-				goto out_nomem;
-
-			/* If interface changes in mount.cifs bump to new ver */
-			if (strncasecmp(string, "1", 1) == 0) {
-				if (strlen(string) > 1) {
-					pr_warn("Bad mount helper ver=%s. Did you want SMB1 (CIFS) dialect and mean to type vers=1.0 instead?\n",
-						string);
-					goto cifs_parse_mount_err;
-				}
-				/* This is the default */
-				break;
-			}
-			/* For all other value, error */
-			pr_warn("Invalid mount helper version specified\n");
-			goto cifs_parse_mount_err;
-		case Opt_vers:
-			/* protocol version (dialect) */
-			string = match_strdup(args);
-			if (string == NULL)
-				goto out_nomem;
-
-			if (cifs_parse_smb_version(string, ctx, is_smb3) != 0)
-				goto cifs_parse_mount_err;
-			got_version = true;
-			break;
-		case Opt_sec:
-			string = match_strdup(args);
-			if (string == NULL)
-				goto out_nomem;
-
-			if (cifs_parse_security_flavors(string, ctx) != 0)
-				goto cifs_parse_mount_err;
-			break;
-		case Opt_cache:
-			string = match_strdup(args);
-			if (string == NULL)
-				goto out_nomem;
-
-			if (cifs_parse_cache_flavor(string, ctx) != 0)
-				goto cifs_parse_mount_err;
-			break;
-		default:
-			/*
-			 * An option we don't recognize. Save it off for later
-			 * if we haven't already found one
-			 */
-			if (!invalid)
-				invalid = data;
-			break;
-		}
-		/* Free up any allocated string */
-		kfree(string);
-		string = NULL;
-	}
-
-	if (!sloppy && invalid) {
-		pr_err("Unknown mount option \"%s\"\n", invalid);
-		goto cifs_parse_mount_err;
-	}
-
-	if (ctx->rdma && ctx->vals->protocol_id < SMB30_PROT_ID) {
-		cifs_dbg(VFS, "SMB Direct requires Version >=3.0\n");
-		goto cifs_parse_mount_err;
-	}
-
-#ifndef CONFIG_KEYS
-	/* Muliuser mounts require CONFIG_KEYS support */
-	if (ctx->multiuser) {
-		cifs_dbg(VFS, "Multiuser mounts require kernels with CONFIG_KEYS enabled\n");
-		goto cifs_parse_mount_err;
-	}
-#endif
-	if (!ctx->UNC) {
-		cifs_dbg(VFS, "CIFS mount error: No usable UNC path provided in device string!\n");
-		goto cifs_parse_mount_err;
-	}
-
-	/* make sure UNC has a share name */
-	if (!strchr(ctx->UNC + 3, '\\')) {
-		cifs_dbg(VFS, "Malformed UNC. Unable to find share name.\n");
-		goto cifs_parse_mount_err;
-	}
-
-	if (!got_ip) {
-		int len;
-		const char *slash;
-
-		/* No ip= option specified? Try to get it from UNC */
-		/* Use the address part of the UNC. */
-		slash = strchr(&ctx->UNC[2], '\\');
-		len = slash - &ctx->UNC[2];
-		if (!cifs_convert_address(dstaddr, &ctx->UNC[2], len)) {
-			pr_err("Unable to determine destination address\n");
-			goto cifs_parse_mount_err;
-		}
-	}
-
-	/* set the port that we got earlier */
-	cifs_set_port(dstaddr, port);
-
-	if (uid_specified)
-		ctx->override_uid = override_uid;
-	else if (override_uid == 1)
-		pr_notice("ignoring forceuid mount option specified with no uid= option\n");
-
-	if (gid_specified)
-		ctx->override_gid = override_gid;
-	else if (override_gid == 1)
-		pr_notice("ignoring forcegid mount option specified with no gid= option\n");
-
-	if (got_version == false)
-		pr_warn_once("No dialect specified on mount. Default has changed to a more secure dialect, SMB2.1 or later (e.g. SMB3.1.1), from CIFS (SMB1). To use the less secure SMB1 dialect to access old servers which do not support SMB3.1.1 (or even SMB3 or SMB2.1) specify vers=1.0 on mount.\n");
-
-	kfree(mountdata_copy);
-	return 0;
-
-out_nomem:
-	pr_warn("Could not allocate temporary buffer\n");
-cifs_parse_mount_err:
-	kfree(string);
-	kfree(mountdata_copy);
-	return 1;
-}
-
 /** Returns true if srcaddr isn't specified and rhs isn't
  * specified, or if srcaddr is specified and
  * matches the IP address of the rhs argument.
@@ -3890,12 +2786,25 @@ int cifs_setup_cifs_sb(struct smb3_fs_context *ctx,
 void
 cifs_cleanup_volume_info_contents(struct smb3_fs_context *ctx)
 {
+	/*
+	 * Make sure this stays in sync with smb3_fs_context_dup()
+	 */
+	kfree(ctx->mount_options);
+	ctx->mount_options = NULL;
 	kfree(ctx->username);
+	ctx->username = NULL;
 	kfree_sensitive(ctx->password);
+	ctx->password = NULL;
 	kfree(ctx->UNC);
+	ctx->UNC = NULL;
 	kfree(ctx->domainname);
+	ctx->domainname = NULL;
+	kfree(ctx->nodename);
+	ctx->nodename = NULL;
 	kfree(ctx->iocharset);
+	ctx->iocharset = NULL;
 	kfree(ctx->prepath);
+	ctx->prepath = NULL;
 }
 
 void
@@ -4122,8 +3031,7 @@ expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
 			mdata = NULL;
 		} else {
 			cifs_cleanup_volume_info_contents(ctx);
-			rc = cifs_setup_volume_info(ctx, mdata,
-						    fake_devname, false);
+			rc = cifs_setup_volume_info(ctx);
 		}
 		kfree(fake_devname);
 		kfree(cifs_sb->mountdata);
@@ -4193,9 +3101,7 @@ static int setup_dfs_tgt_conn(const char *path, const char *full_path,
 		rc = PTR_ERR(mdata);
 		mdata = NULL;
 	} else {
-		cifs_dbg(FYI, "%s: fake_devname: %s\n", __func__, fake_devname);
-		rc = cifs_setup_volume_info((struct smb3_fs_context *)&fake_ctx, mdata, fake_devname,
-					    false);
+		rc = cifs_setup_volume_info(&fake_ctx);
 	}
 	kfree(mdata);
 	kfree(fake_devname);
@@ -4217,7 +3123,7 @@ static int setup_dfs_tgt_conn(const char *path, const char *full_path,
 			rc = update_vol_info(tgt_it, &fake_ctx, ctx);
 		}
 	}
-	cifs_cleanup_volume_info_contents((struct smb3_fs_context *)&fake_ctx);
+	cifs_cleanup_volume_info_contents(&fake_ctx);
 	return rc;
 }
 
@@ -4263,15 +3169,14 @@ static int do_dfs_failover(const char *path, const char *full_path, struct cifs_
 }
 #endif
 
+/* TODO: all callers to this are broken. We are not parsing mount_options here
+ * we should pass a clone of the original context?
+ */
 int
-cifs_setup_volume_info(struct smb3_fs_context *ctx, char *mount_data,
-			const char *devname, bool is_smb3)
+cifs_setup_volume_info(struct smb3_fs_context *ctx)
 {
 	int rc = 0;
 
-	if (cifs_parse_mount_options(mount_data, devname, ctx, is_smb3))
-		return -EINVAL;
-
 	if (ctx->nullauth) {
 		cifs_dbg(FYI, "Anonymous login\n");
 		kfree(ctx->username);
@@ -4302,25 +3207,6 @@ cifs_setup_volume_info(struct smb3_fs_context *ctx, char *mount_data,
 	return rc;
 }
 
-struct smb3_fs_context *
-cifs_get_volume_info(char *mount_data, const char *devname, bool is_smb3)
-{
-	int rc;
-	struct smb3_fs_context *ctx;
-
-	ctx = kmalloc(sizeof(*ctx), GFP_KERNEL);
-	if (!ctx)
-		return ERR_PTR(-ENOMEM);
-
-	rc = cifs_setup_volume_info(ctx, mount_data, devname, is_smb3);
-	if (rc) {
-		cifs_cleanup_volume_info(ctx);
-		ctx = ERR_PTR(rc);
-	}
-
-	return ctx;
-}
-
 static int
 cifs_are_all_path_components_accessible(struct TCP_Server_Info *server,
 					unsigned int xid,
diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c
index 2b77d39d7d22..dde859c21f1a 100644
--- a/fs/cifs/dfs_cache.c
+++ b/fs/cifs/dfs_cache.c
@@ -18,9 +18,9 @@
 #include "cifs_debug.h"
 #include "cifs_unicode.h"
 #include "smb2glob.h"
+#include "fs_context.h"
 
 #include "dfs_cache.h"
-#include "fs_context.h"
 
 #define CACHE_HTABLE_SIZE 32
 #define CACHE_MAX_ENTRIES 64
@@ -1142,14 +1142,14 @@ int dfs_cache_get_tgt_referral(const char *path,
 }
 
 /**
- * dfs_cache_add_vol - add a cifs volume during mount() that will be handled by
+ * dfs_cache_add_vol - add a cifs context during mount() that will be handled by
  * DFS cache refresh worker.
  *
  * @mntdata: mount data.
  * @ctx: cifs context.
  * @fullpath: origin full path.
  *
- * Return zero if volume was set up correctly, otherwise non-zero.
+ * Return zero if context was set up correctly, otherwise non-zero.
  */
 int dfs_cache_add_vol(char *mntdata, struct smb3_fs_context *ctx, const char *fullpath)
 {
@@ -1453,7 +1453,7 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi,
 		goto out;
 	}
 
-	rc = cifs_setup_volume_info(&ctx, mdata, devname, false);
+	rc = cifs_setup_volume_info(&ctx);
 	kfree(devname);
 
 	if (rc) {
diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
index 3b15f9a882b2..1e69fdbe76d8 100644
--- a/fs/cifs/fs_context.c
+++ b/fs/cifs/fs_context.c
@@ -6,9 +6,32 @@
  *              David Howells <dhowells@redhat.com>
  */
 
+/*
+#include <linux/module.h>
+#include <linux/nsproxy.h>
+#include <linux/slab.h>
+#include <linux/magic.h>
+#include <linux/security.h>
+#include <net/net_namespace.h>
+*/
+
+#include <linux/ctype.h>
+#include <linux/fs_context.h>
+#include <linux/fs_parser.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/parser.h>
+#include <linux/utsname.h>
+#include "cifsfs.h"
+#include "cifspdu.h"
 #include "cifsglob.h"
 #include "cifsproto.h"
+#include "cifs_unicode.h"
 #include "cifs_debug.h"
+#include "cifs_fs_sb.h"
+#include "ntlmssp.h"
+#include "nterr.h"
+#include "rfc1002pdu.h"
 #include "fs_context.h"
 
 static const match_table_t cifs_smb_version_tokens = {
@@ -25,77 +48,6 @@ static const match_table_t cifs_smb_version_tokens = {
 	{ Smb_version_err, NULL }
 };
 
-int
-cifs_parse_smb_version(char *value, struct smb3_fs_context *ctx, bool is_smb3)
-{
-	substring_t args[MAX_OPT_ARGS];
-
-	switch (match_token(value, cifs_smb_version_tokens, args)) {
-#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
-	case Smb_1:
-		if (disable_legacy_dialects) {
-			cifs_dbg(VFS, "mount with legacy dialect disabled\n");
-			return 1;
-		}
-		if (is_smb3) {
-			cifs_dbg(VFS, "vers=1.0 (cifs) not permitted when mounting with smb3\n");
-			return 1;
-		}
-		cifs_dbg(VFS, "Use of the less secure dialect vers=1.0 is not recommended unless required for access to very old servers\n");
-		ctx->ops = &smb1_operations;
-		ctx->vals = &smb1_values;
-		break;
-	case Smb_20:
-		if (disable_legacy_dialects) {
-			cifs_dbg(VFS, "mount with legacy dialect disabled\n");
-			return 1;
-		}
-		if (is_smb3) {
-			cifs_dbg(VFS, "vers=2.0 not permitted when mounting with smb3\n");
-			return 1;
-		}
-		ctx->ops = &smb20_operations;
-		ctx->vals = &smb20_values;
-		break;
-#else
-	case Smb_1:
-		cifs_dbg(VFS, "vers=1.0 (cifs) mount not permitted when legacy dialects disabled\n");
-		return 1;
-	case Smb_20:
-		cifs_dbg(VFS, "vers=2.0 mount not permitted when legacy dialects disabled\n");
-		return 1;
-#endif /* CIFS_ALLOW_INSECURE_LEGACY */
-	case Smb_21:
-		ctx->ops = &smb21_operations;
-		ctx->vals = &smb21_values;
-		break;
-	case Smb_30:
-		ctx->ops = &smb30_operations;
-		ctx->vals = &smb30_values;
-		break;
-	case Smb_302:
-		ctx->ops = &smb30_operations; /* currently identical with 3.0 */
-		ctx->vals = &smb302_values;
-		break;
-	case Smb_311:
-		ctx->ops = &smb311_operations;
-		ctx->vals = &smb311_values;
-		break;
-	case Smb_3any:
-		ctx->ops = &smb30_operations; /* currently identical with 3.0 */
-		ctx->vals = &smb3any_values;
-		break;
-	case Smb_default:
-		ctx->ops = &smb30_operations; /* currently identical with 3.0 */
-		ctx->vals = &smbdefault_values;
-		break;
-	default:
-		cifs_dbg(VFS, "Unknown vers= option specified: %s\n", value);
-		return 1;
-	}
-	return 0;
-}
-
 static const match_table_t cifs_secflavor_tokens = {
 	{ Opt_sec_krb5, "krb5" },
 	{ Opt_sec_krb5i, "krb5i" },
@@ -113,7 +65,117 @@ static const match_table_t cifs_secflavor_tokens = {
 	{ Opt_sec_err, NULL }
 };
 
-int cifs_parse_security_flavors(char *value, struct smb3_fs_context *ctx)
+const struct fs_parameter_spec smb3_fs_parameters[] = {
+	/* Mount options that take no arguments */
+	fsparam_flag_no("user_xattr", Opt_user_xattr),
+	fsparam_flag_no("forceuid", Opt_forceuid),
+	fsparam_flag_no("multichannel", Opt_multichannel),
+	fsparam_flag_no("forcegid", Opt_forcegid),
+	fsparam_flag("noblocksend", Opt_noblocksend),
+	fsparam_flag("noautotune", Opt_noautotune),
+	fsparam_flag("nolease", Opt_nolease),
+	fsparam_flag_no("hard", Opt_hard),
+	fsparam_flag_no("soft", Opt_soft),
+	fsparam_flag_no("perm", Opt_perm),
+	fsparam_flag("nodelete", Opt_nodelete),
+	fsparam_flag_no("mapposix", Opt_mapposix),
+	fsparam_flag("mapchars", Opt_mapchars),
+	fsparam_flag("nomapchars", Opt_nomapchars),
+	fsparam_flag_no("sfu", Opt_sfu),
+	fsparam_flag("nodfs", Opt_nodfs),
+	fsparam_flag_no("posixpaths", Opt_posixpaths),
+	fsparam_flag_no("unix", Opt_unix),
+	fsparam_flag_no("linux", Opt_unix),
+	fsparam_flag_no("posix", Opt_unix),
+	fsparam_flag("nocase", Opt_nocase),
+	fsparam_flag("ignorecase", Opt_nocase),
+	fsparam_flag_no("brl", Opt_brl),
+	fsparam_flag_no("handlecache", Opt_handlecache),
+	fsparam_flag("forcemandatorylock", Opt_forcemandatorylock),
+	fsparam_flag("forcemand", Opt_forcemandatorylock),
+	fsparam_flag("setuidfromacl", Opt_setuidfromacl),
+	fsparam_flag_no("setuids", Opt_setuids),
+	fsparam_flag_no("dynperm", Opt_dynperm),
+	fsparam_flag_no("intr", Opt_intr),
+	fsparam_flag_no("strictsync", Opt_strictsync),
+	fsparam_flag_no("serverino", Opt_serverino),
+	fsparam_flag("rwpidforward", Opt_rwpidforward),
+	fsparam_flag("cifsacl", Opt_cifsacl),
+	fsparam_flag_no("acl", Opt_acl),
+	fsparam_flag("locallease", Opt_locallease),
+	fsparam_flag("sign", Opt_sign),
+	fsparam_flag("ignore_signature", Opt_ignore_signature),
+	fsparam_flag("seal", Opt_seal),
+	fsparam_flag("noac", Opt_noac),
+	fsparam_flag("fsc", Opt_fsc),
+	fsparam_flag("mfsymlinks", Opt_mfsymlinks),
+	fsparam_flag("multiuser", Opt_multiuser),
+	fsparam_flag("sloppy", Opt_sloppy),
+	fsparam_flag("nosharesock", Opt_nosharesock),
+	fsparam_flag_no("persistent", Opt_persistent),
+	fsparam_flag_no("resilient", Opt_resilient),
+	fsparam_flag("domainauto", Opt_domainauto),
+	fsparam_flag("rdma", Opt_rdma),
+	fsparam_flag("modesid", Opt_modesid),
+	fsparam_flag("rootfs", Opt_rootfs),
+	fsparam_flag("compress", Opt_compress),
+
+	/* Mount options which take numeric value */
+	fsparam_u32("backupuid", Opt_backupuid),
+	fsparam_u32("backupgid", Opt_backupgid),
+	fsparam_u32("uid", Opt_uid),
+	fsparam_u32("cruid", Opt_cruid),
+	fsparam_u32("gid", Opt_gid),
+	fsparam_u32("file_mode", Opt_file_mode),
+	fsparam_u32("dirmode", Opt_dirmode),
+	fsparam_u32("dir_mode", Opt_dirmode),
+	fsparam_u32("port", Opt_port),
+	fsparam_u32("min_enc_offload", Opt_min_enc_offload),
+	fsparam_u32("bsize", Opt_blocksize),
+	fsparam_u32("rsize", Opt_rsize),
+	fsparam_u32("wsize", Opt_wsize),
+	fsparam_u32("actimeo", Opt_actimeo),
+	fsparam_u32("echo_interval", Opt_echo_interval),
+	fsparam_u32("max_credits", Opt_max_credits),
+	fsparam_u32("handletimeout", Opt_handletimeout),
+	fsparam_u32("snapshot", Opt_snapshot),
+	fsparam_u32("max_channels", Opt_max_channels),
+
+	/* Mount options which take string value */
+	fsparam_string("source", Opt_source),
+	fsparam_string("unc", Opt_source),
+	fsparam_string("user", Opt_user),
+	fsparam_string("username", Opt_user),
+	fsparam_string("pass", Opt_pass),
+	fsparam_string("password", Opt_pass),
+	fsparam_string("ip", Opt_ip),
+	fsparam_string("addr", Opt_ip),
+	fsparam_string("domain", Opt_domain),
+	fsparam_string("dom", Opt_domain),
+	fsparam_string("srcaddr", Opt_srcaddr),
+	fsparam_string("iocharset", Opt_iocharset),
+	fsparam_string("netbiosname", Opt_netbiosname),
+	fsparam_string("servern", Opt_servern),
+	fsparam_string("ver", Opt_ver),
+	fsparam_string("vers", Opt_vers),
+	fsparam_string("sec", Opt_sec),
+	fsparam_string("cache", Opt_cache),
+
+	/* Arguments that should be ignored */
+	fsparam_flag("guest", Opt_ignore),
+	fsparam_flag("noatime", Opt_ignore),
+	fsparam_flag("relatime", Opt_ignore),
+	fsparam_flag("_netdev", Opt_ignore),
+	fsparam_flag_no("suid", Opt_ignore),
+	fsparam_flag_no("exec", Opt_ignore),
+	fsparam_flag_no("dev", Opt_ignore),
+	fsparam_flag_no("mand", Opt_ignore),
+	fsparam_string("cred", Opt_ignore),
+	fsparam_string("credentials", Opt_ignore),
+};
+
+int
+cifs_parse_security_flavors(char *value, struct smb3_fs_context *ctx)
 {
 
 	substring_t args[MAX_OPT_ARGS];
@@ -131,25 +193,25 @@ int cifs_parse_security_flavors(char *value, struct smb3_fs_context *ctx)
 		return 1;
 	case Opt_sec_krb5i:
 		ctx->sign = true;
-		fallthrough;
+		/* Fallthrough */
 	case Opt_sec_krb5:
 		ctx->sectype = Kerberos;
 		break;
 	case Opt_sec_ntlmsspi:
 		ctx->sign = true;
-		fallthrough;
+		/* Fallthrough */
 	case Opt_sec_ntlmssp:
 		ctx->sectype = RawNTLMSSP;
 		break;
 	case Opt_sec_ntlmi:
 		ctx->sign = true;
-		fallthrough;
+		/* Fallthrough */
 	case Opt_ntlm:
 		ctx->sectype = NTLM;
 		break;
 	case Opt_sec_ntlmv2i:
 		ctx->sign = true;
-		fallthrough;
+		/* Fallthrough */
 	case Opt_sec_ntlmv2:
 		ctx->sectype = NTLMv2;
 		break;
@@ -239,6 +301,7 @@ smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx
 
 	memcpy(new_ctx, ctx, sizeof(*ctx));
 	new_ctx->prepath = NULL;
+	new_ctx->mount_options = NULL;
 	new_ctx->local_nls = NULL;
 	new_ctx->nodename = NULL;
 	new_ctx->username = NULL;
@@ -251,6 +314,7 @@ smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx
 	 * Make sure to stay in sync with cifs_cleanup_volume_info_contents()
 	 */
 	DUP_CTX_STR(prepath);
+	DUP_CTX_STR(mount_options);
 	DUP_CTX_STR(username);
 	DUP_CTX_STR(password);
 	DUP_CTX_STR(UNC);
@@ -261,6 +325,77 @@ smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx
 	return rc;
 }
 
+static int
+cifs_parse_smb_version(char *value, struct smb3_fs_context *ctx, bool is_smb3)
+{
+	substring_t args[MAX_OPT_ARGS];
+
+	switch (match_token(value, cifs_smb_version_tokens, args)) {
+#ifdef CONFIG_CIFS_ALLOW_INSECURE_LEGACY
+	case Smb_1:
+		if (disable_legacy_dialects) {
+			cifs_dbg(VFS, "mount with legacy dialect disabled\n");
+			return 1;
+		}
+		if (is_smb3) {
+			cifs_dbg(VFS, "vers=1.0 (cifs) not permitted when mounting with smb3\n");
+			return 1;
+		}
+		cifs_dbg(VFS, "Use of the less secure dialect vers=1.0 is not recommended unless required for access to very old servers\n");
+		ctx->ops = &smb1_operations;
+		ctx->vals = &smb1_values;
+		break;
+	case Smb_20:
+		if (disable_legacy_dialects) {
+			cifs_dbg(VFS, "mount with legacy dialect disabled\n");
+			return 1;
+		}
+		if (is_smb3) {
+			cifs_dbg(VFS, "vers=2.0 not permitted when mounting with smb3\n");
+			return 1;
+		}
+		ctx->ops = &smb20_operations;
+		ctx->vals = &smb20_values;
+		break;
+#else
+	case Smb_1:
+		cifs_dbg(VFS, "vers=1.0 (cifs) mount not permitted when legacy dialects disabled\n");
+		return 1;
+	case Smb_20:
+		cifs_dbg(VFS, "vers=2.0 mount not permitted when legacy dialects disabled\n");
+		return 1;
+#endif /* CIFS_ALLOW_INSECURE_LEGACY */
+	case Smb_21:
+		ctx->ops = &smb21_operations;
+		ctx->vals = &smb21_values;
+		break;
+	case Smb_30:
+		ctx->ops = &smb30_operations;
+		ctx->vals = &smb30_values;
+		break;
+	case Smb_302:
+		ctx->ops = &smb30_operations; /* currently identical with 3.0 */
+		ctx->vals = &smb302_values;
+		break;
+	case Smb_311:
+		ctx->ops = &smb311_operations;
+		ctx->vals = &smb311_values;
+		break;
+	case Smb_3any:
+		ctx->ops = &smb30_operations; /* currently identical with 3.0 */
+		ctx->vals = &smb3any_values;
+		break;
+	case Smb_default:
+		ctx->ops = &smb30_operations; /* currently identical with 3.0 */
+		ctx->vals = &smbdefault_values;
+		break;
+	default:
+		cifs_dbg(VFS, "Unknown vers= option specified: %s\n", value);
+		return 1;
+	}
+	return 0;
+}
+
 /*
  * Parse a devname into substrings and populate the ctx->UNC and ctx->prepath
  * fields with the result. Returns 0 on success and an error otherwise.
@@ -316,3 +451,783 @@ smb3_parse_devname(const char *devname, struct smb3_fs_context *ctx)
 	return 0;
 }
 
+static void smb3_fs_context_free(struct fs_context *fc);
+static int smb3_fs_context_parse_param(struct fs_context *fc,
+				       struct fs_parameter *param);
+static int smb3_fs_context_parse_monolithic(struct fs_context *fc,
+					    void *data);
+static int smb3_get_tree(struct fs_context *fc);
+static int smb3_reconfigure(struct fs_context *fc);
+
+static const struct fs_context_operations smb3_fs_context_ops = {
+	.free			= smb3_fs_context_free,
+	.parse_param		= smb3_fs_context_parse_param,
+	.parse_monolithic	= smb3_fs_context_parse_monolithic,
+	.get_tree		= smb3_get_tree,
+	.reconfigure		= smb3_reconfigure,
+};
+
+/*
+ * Parse a monolithic block of data from sys_mount().
+ * smb3_fs_context_parse_monolithic - Parse key[=val][,key[=val]]* mount data
+ * @ctx: The superblock configuration to fill in.
+ * @data: The data to parse
+ *
+ * Parse a blob of data that's in key[=val][,key[=val]]* form.  This can be
+ * called from the ->monolithic_mount_data() fs_context operation.
+ *
+ * Returns 0 on success or the error returned by the ->parse_option() fs_context
+ * operation on failure.
+ */
+static int smb3_fs_context_parse_monolithic(struct fs_context *fc,
+					   void *data)
+{
+	struct smb3_fs_context *ctx = smb3_fc2context(fc);
+	char *options = data, *key;
+	int ret = 0;
+
+	if (!options)
+		return 0;
+
+	ctx->mount_options = kstrdup(data, GFP_KERNEL);
+	if (ctx->mount_options == NULL)
+		return -ENOMEM;
+
+	ret = security_sb_eat_lsm_opts(options, &fc->security);
+	if (ret)
+		return ret;
+
+	/* BB Need to add support for sep= here TBD */
+	while ((key = strsep(&options, ",")) != NULL) {
+		if (*key) {
+			size_t v_len = 0;
+			char *value = strchr(key, '=');
+
+			if (value) {
+				if (value == key)
+					continue;
+				*value++ = 0;
+				v_len = strlen(value);
+			}
+			ret = vfs_parse_fs_string(fc, key, value, v_len);
+			if (ret < 0)
+				break;
+		}
+	}
+
+	return ret;
+}
+
+/*
+ * Validate the preparsed information in the config.
+ */
+static int smb3_fs_context_validate(struct fs_context *fc)
+{
+	struct smb3_fs_context *ctx = smb3_fc2context(fc);
+
+	if (ctx->rdma && ctx->vals->protocol_id < SMB30_PROT_ID) {
+		cifs_dbg(VFS, "SMB Direct requires Version >=3.0\n");
+		return -1;
+	}
+
+#ifndef CONFIG_KEYS
+	/* Muliuser mounts require CONFIG_KEYS support */
+	if (ctx->multiuser) {
+		cifs_dbg(VFS, "Multiuser mounts require kernels with CONFIG_KEYS enabled\n");
+		return -1;
+	}
+#endif
+
+	if (ctx->got_version == false)
+		pr_warn_once("No dialect specified on mount. Default has changed to a more secure dialect, SMB2.1 or later (e.g. SMB3.1.1), from CIFS (SMB1). To use the less secure SMB1 dialect to access old servers which do not support SMB3.1.1 (or even SMB3 or SMB2.1) specify vers=1.0 on mount.\n");
+
+
+	if (!ctx->UNC) {
+		cifs_dbg(VFS, "CIFS mount error: No usable UNC path provided in device string!\n");
+		return -1;
+	}
+
+	/* make sure UNC has a share name */
+	if (strlen(ctx->UNC) < 3 || !strchr(ctx->UNC + 3, '\\')) {
+		cifs_dbg(VFS, "Malformed UNC. Unable to find share name.\n");
+		return -1;
+	}
+
+	if (!ctx->got_ip) {
+		int len;
+		const char *slash;
+
+		/* No ip= option specified? Try to get it from UNC */
+		/* Use the address part of the UNC. */
+		slash = strchr(&ctx->UNC[2], '\\');
+		len = slash - &ctx->UNC[2];
+		if (!cifs_convert_address((struct sockaddr *)&ctx->dstaddr,
+					  &ctx->UNC[2], len)) {
+			pr_err("Unable to determine destination address\n");
+			return -1;
+		}
+	}
+
+	/* set the port that we got earlier */
+	cifs_set_port((struct sockaddr *)&ctx->dstaddr, ctx->port);
+
+	if (ctx->override_uid && !ctx->uid_specified) {
+		ctx->override_uid = 0;
+		pr_notice("ignoring forceuid mount option specified with no uid= option\n");
+	}
+
+	if (ctx->override_gid && !ctx->gid_specified) {
+		ctx->override_gid = 0;
+		pr_notice("ignoring forcegid mount option specified with no gid= option\n");
+	}
+
+	return 0;
+}
+
+static int smb3_get_tree_common(struct fs_context *fc)
+{
+	struct smb3_fs_context *ctx = smb3_fc2context(fc);
+	struct dentry *root;
+	int rc = 0;
+
+	root = cifs_smb3_do_mount(fc->fs_type, 0, ctx);
+	if (IS_ERR(root))
+		return PTR_ERR(root);
+
+	fc->root = root;
+
+	return rc;
+}
+
+/*
+ * Create an SMB3 superblock from the parameters passed.
+ */
+static int smb3_get_tree(struct fs_context *fc)
+{
+	int err = smb3_fs_context_validate(fc);
+
+	if (err)
+		return err;
+	return smb3_get_tree_common(fc);
+}
+
+static void smb3_fs_context_free(struct fs_context *fc)
+{
+	struct smb3_fs_context *ctx = smb3_fc2context(fc);
+
+	cifs_cleanup_volume_info(ctx);		
+}
+
+static int smb3_reconfigure(struct fs_context *fc)
+{
+	// TODO:  struct smb3_fs_context *ctx = smb3_fc2context(fc);
+
+	/* FIXME : add actual reconfigure */
+	return 0;
+}
+
+static int smb3_fs_context_parse_param(struct fs_context *fc,
+				      struct fs_parameter *param)
+{
+	struct fs_parse_result result;
+	struct smb3_fs_context *ctx = smb3_fc2context(fc);
+	int i, opt;
+	bool is_smb3 = !strcmp(fc->fs_type->name, "smb3");
+	bool skip_parsing = false;
+
+	cifs_dbg(FYI, "CIFS: parsing cifs mount option '%s'\n", param->key);
+
+	/*
+	 * fs_parse can not handle string options with an empty value so
+	 * we will need special handling of them.
+	 */
+	if (param->type == fs_value_is_string && param->string[0] == 0) {
+		if (!strcmp("pass", param->key) || !strcmp("password", param->key))
+			skip_parsing = true;
+	}
+
+	if (!skip_parsing) {
+		opt = fs_parse(fc, smb3_fs_parameters, param, &result);
+		if (opt < 0)
+			return ctx->sloppy ? 1 : opt;
+	}
+
+	switch (opt) {
+	case Opt_compress:
+		ctx->compression = UNKNOWN_TYPE;
+		cifs_dbg(VFS,
+			"SMB3 compression support is experimental\n");
+		break;
+	case Opt_nodfs:
+		ctx->nodfs = 1;
+		break;
+	case Opt_hard:
+		if (result.negated)
+			ctx->retry = 0;
+		else
+			ctx->retry = 1;
+		break;
+	case Opt_soft:
+		if (result.negated)
+			ctx->retry = 1;
+		else
+			ctx->retry = 0;
+		break;
+	case Opt_mapposix:
+		if (result.negated)
+			ctx->remap = false;
+		else {
+			ctx->remap = true;
+			ctx->sfu_remap = false; /* disable SFU mapping */
+		}
+		break;
+	case Opt_user_xattr:
+		if (result.negated)
+			ctx->no_xattr = 1;
+		else
+			ctx->no_xattr = 0;
+		break;
+	case Opt_forceuid:
+		if (result.negated)
+			ctx->override_uid = 0;
+		else
+			ctx->override_uid = 1;
+		break;
+	case Opt_forcegid:
+		if (result.negated)
+			ctx->override_gid = 0;
+		else
+			ctx->override_gid = 1;
+		break;
+	case Opt_perm:
+		if (result.negated)
+			ctx->noperm = 1;
+		else
+			ctx->noperm = 0;
+		break;
+	case Opt_dynperm:
+		if (result.negated)
+			ctx->dynperm = 0;
+		else
+			ctx->dynperm = 1;
+		break;
+	case Opt_sfu:
+		if (result.negated)
+			ctx->sfu_emul = 0;
+		else
+			ctx->sfu_emul = 1;
+		break;
+	case Opt_noblocksend:
+		ctx->noblocksnd = 1;
+		break;
+	case Opt_noautotune:
+		ctx->noautotune = 1;
+		break;
+	case Opt_nolease:
+		ctx->no_lease = 1;
+		break;
+	case Opt_nodelete:
+		ctx->nodelete = 1;
+		break;
+	case Opt_multichannel:
+		if (result.negated) {
+			ctx->multichannel = false;
+			ctx->max_channels = 1;
+		} else {
+			ctx->multichannel = true;
+			/* if number of channels not specified, default to 2 */
+			if (ctx->max_channels < 2)
+				ctx->max_channels = 2;
+		}
+		break;
+	case Opt_uid:
+		ctx->linux_uid.val = result.uint_32;
+		ctx->uid_specified = true;
+		break;
+	case Opt_cruid:
+		ctx->cred_uid.val = result.uint_32;
+		break;
+	case Opt_backupgid:
+		ctx->backupgid.val = result.uint_32;
+		ctx->backupgid_specified = true;
+		break;
+	case Opt_gid:
+		ctx->linux_gid.val = result.uint_32;
+		ctx->gid_specified = true;
+		break;
+	case Opt_port:
+		ctx->port = result.uint_32;
+		break;
+	case Opt_file_mode:
+		ctx->file_mode = result.uint_32;
+		break;
+	case Opt_dirmode:
+		ctx->dir_mode = result.uint_32;
+		break;
+	case Opt_min_enc_offload:
+		ctx->min_offload = result.uint_32;
+		break;
+	case Opt_blocksize:
+		/*
+		 * inode blocksize realistically should never need to be
+		 * less than 16K or greater than 16M and default is 1MB.
+		 * Note that small inode block sizes (e.g. 64K) can lead
+		 * to very poor performance of common tools like cp and scp
+		 */
+		if ((result.uint_32 < CIFS_MAX_MSGSIZE) ||
+		   (result.uint_32 > (4 * SMB3_DEFAULT_IOSIZE))) {
+			cifs_dbg(VFS, "%s: Invalid blocksize\n",
+				__func__);
+			goto cifs_parse_mount_err;
+		}
+		ctx->bsize = result.uint_32;
+		break;
+	case Opt_rsize:
+		ctx->rsize = result.uint_32;
+		break;
+	case Opt_wsize:
+		ctx->wsize = result.uint_32;
+		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");
+			goto cifs_parse_mount_err;
+		}
+		break;
+	case Opt_echo_interval:
+		ctx->echo_interval = result.uint_32;
+		break;
+	case Opt_snapshot:
+		ctx->snapshot_time = result.uint_32;
+		break;
+	case Opt_max_credits:
+		if (result.uint_32 < 20 || result.uint_32 > 60000) {
+			cifs_dbg(VFS, "%s: Invalid max_credits value\n",
+				 __func__);
+			goto cifs_parse_mount_err;
+		}
+		ctx->max_credits = result.uint_32;
+		break;
+	case Opt_max_channels:
+		if (result.uint_32 < 1 || result.uint_32 > CIFS_MAX_CHANNELS) {
+			cifs_dbg(VFS, "%s: Invalid max_channels value, needs to be 1-%d\n",
+				 __func__, CIFS_MAX_CHANNELS);
+			goto cifs_parse_mount_err;
+		}
+		ctx->max_channels = result.uint_32;
+		break;
+	case Opt_handletimeout:
+		ctx->handle_timeout = result.uint_32;
+		if (ctx->handle_timeout > SMB3_MAX_HANDLE_TIMEOUT) {
+			cifs_dbg(VFS, "Invalid handle cache timeout, longer than 16 minutes\n");
+			goto cifs_parse_mount_err;
+		}
+		break;
+	case Opt_source:
+		kfree(ctx->UNC);
+		ctx->UNC = NULL;
+		switch (smb3_parse_devname(param->string, ctx)) {
+		case 0:
+			break;
+		case -ENOMEM:
+			cifs_dbg(VFS, "Unable to allocate memory for devname\n");
+			goto cifs_parse_mount_err;
+		case -EINVAL:
+			cifs_dbg(VFS, "Malformed UNC in devname\n");
+			goto cifs_parse_mount_err;
+		default:
+			cifs_dbg(VFS, "Unknown error parsing devname\n");
+			goto cifs_parse_mount_err;
+		}
+		fc->source = kstrdup(param->string, GFP_KERNEL);
+		if (fc->source == NULL) {
+			cifs_dbg(VFS, "OOM when copying UNC string\n");
+			goto cifs_parse_mount_err;
+		}
+		break;
+	case Opt_user:
+		kfree(ctx->username);
+		ctx->username = NULL;
+		if (strlen(param->string) == 0) {
+			/* null user, ie. anonymous authentication */
+			ctx->nullauth = 1;
+			break;
+		}
+
+		if (strnlen(param->string, CIFS_MAX_USERNAME_LEN) >
+		    CIFS_MAX_USERNAME_LEN) {
+			pr_warn("username too long\n");
+			goto cifs_parse_mount_err;
+		}
+		ctx->username = kstrdup(param->string, GFP_KERNEL);
+		if (ctx->username == NULL) {
+			cifs_dbg(VFS, "OOM when copying username string\n");
+			goto cifs_parse_mount_err;
+		}
+		break;
+	case Opt_pass:
+		kzfree(ctx->password);
+		ctx->password = NULL;
+		if (strlen(param->string) == 0) {
+			break;
+		}
+		ctx->password = kstrdup(param->string, GFP_KERNEL);
+		if (ctx->password == NULL) {
+			cifs_dbg(VFS, "OOM when copying password string\n");
+			goto cifs_parse_mount_err;
+		}
+		break;
+	case Opt_ip:
+		if (strlen(param->string) == 0) {
+			ctx->got_ip = false;
+			break;
+		}
+		if (!cifs_convert_address((struct sockaddr *)&ctx->dstaddr,
+					  param->string,
+					  strlen(param->string))) {
+			pr_err("bad ip= option (%s)\n", param->string);
+			goto cifs_parse_mount_err;
+		}
+		ctx->got_ip = true;
+		break;
+	case Opt_domain:
+		if (strnlen(param->string, CIFS_MAX_DOMAINNAME_LEN)
+				== CIFS_MAX_DOMAINNAME_LEN) {
+			pr_warn("domain name too long\n");
+			goto cifs_parse_mount_err;
+		}
+
+		kfree(ctx->domainname);
+		ctx->domainname = kstrdup(param->string, GFP_KERNEL);
+		if (ctx->domainname == NULL) {
+			cifs_dbg(VFS, "OOM when copying domainname string\n");
+			goto cifs_parse_mount_err;
+		}
+		cifs_dbg(FYI, "Domain name set\n");
+		break;
+	case Opt_srcaddr:
+		if (!cifs_convert_address(
+				(struct sockaddr *)&ctx->srcaddr,
+				param->string, strlen(param->string))) {
+			pr_warn("Could not parse srcaddr: %s\n",
+				param->string);
+			goto cifs_parse_mount_err;
+		}
+		break;
+	case Opt_iocharset:
+		if (strnlen(param->string, 1024) >= 65) {
+			pr_warn("iocharset name too long\n");
+			goto cifs_parse_mount_err;
+		}
+
+		 if (strncasecmp(param->string, "default", 7) != 0) {
+			kfree(ctx->iocharset);
+			ctx->iocharset = kstrdup(param->string, GFP_KERNEL);
+			if (ctx->iocharset == NULL) {
+				cifs_dbg(VFS, "OOM when copying iocharset string\n");
+				goto cifs_parse_mount_err;
+			}
+		}
+		/* if iocharset not set then load_nls_default
+		 * is used by caller
+		 */
+		 cifs_dbg(FYI, "iocharset set to %s\n", ctx->iocharset);
+		break;
+	case Opt_netbiosname:
+		memset(ctx->source_rfc1001_name, 0x20,
+			RFC1001_NAME_LEN);
+		/*
+		 * FIXME: are there cases in which a comma can
+		 * be valid in workstation netbios name (and
+		 * need special handling)?
+		 */
+		for (i = 0; i < RFC1001_NAME_LEN; i++) {
+			/* don't ucase netbiosname for user */
+			if (param->string[i] == 0)
+				break;
+			ctx->source_rfc1001_name[i] = param->string[i];
+		}
+		/* The string has 16th byte zero still from
+		 * set at top of the function
+		 */
+		if (i == RFC1001_NAME_LEN && param->string[i] != 0)
+			pr_warn("netbiosname longer than 15 truncated\n");
+		break;
+	case Opt_servern:
+		/* last byte, type, is 0x20 for servr type */
+		memset(ctx->target_rfc1001_name, 0x20,
+			RFC1001_NAME_LEN_WITH_NULL);
+		/* BB are there cases in which a comma can be
+		   valid in this workstation netbios name
+		   (and need special handling)? */
+
+		/* user or mount helper must uppercase the
+		   netbios name */
+		for (i = 0; i < 15; i++) {
+			if (param->string[i] == 0)
+				break;
+			ctx->target_rfc1001_name[i] = param->string[i];
+		}
+		/* The string has 16th byte zero still from
+		   set at top of the function  */
+		if (i == RFC1001_NAME_LEN && param->string[i] != 0)
+			pr_warn("server netbiosname longer than 15 truncated\n");
+		break;
+	case Opt_ver:
+		/* version of mount userspace tools, not dialect */
+		/* If interface changes in mount.cifs bump to new ver */
+		if (strncasecmp(param->string, "1", 1) == 0) {
+			if (strlen(param->string) > 1) {
+				pr_warn("Bad mount helper ver=%s. Did you want SMB1 (CIFS) dialect and mean to type vers=1.0 instead?\n",
+					param->string);
+				goto cifs_parse_mount_err;
+			}
+			/* This is the default */
+			break;
+		}
+		/* For all other value, error */
+		pr_warn("Invalid mount helper version specified\n");
+		goto cifs_parse_mount_err;
+	case Opt_vers:
+		/* protocol version (dialect) */
+		if (cifs_parse_smb_version(param->string, ctx, is_smb3) != 0)
+			goto cifs_parse_mount_err;
+		ctx->got_version = true;
+		break;
+	case Opt_sec:
+		if (cifs_parse_security_flavors(param->string, ctx) != 0)
+			goto cifs_parse_mount_err;
+		break;
+	case Opt_cache:
+		if (cifs_parse_cache_flavor(param->string, ctx) != 0)
+			goto cifs_parse_mount_err;
+		break;
+	case Opt_rootfs:
+#ifdef CONFIG_CIFS_ROOT
+		ctx->rootfs = true;
+#endif
+		break;
+	case Opt_posixpaths:
+		if (result.negated)
+			ctx->posix_paths = 0;
+		else
+			ctx->posix_paths = 1;
+		break;
+	case Opt_unix:
+		if (result.negated)
+			ctx->linux_ext = 0;
+		else
+			ctx->no_linux_ext = 1;
+		break;
+	case Opt_nocase:
+		ctx->nocase = 1;
+		break;
+	case Opt_brl:
+		if (result.negated) {
+			/*
+			 * turn off mandatory locking in mode
+			 * if remote locking is turned off since the
+			 * local vfs will do advisory
+			 */
+			if (ctx->file_mode ==
+				(S_IALLUGO & ~(S_ISUID | S_IXGRP)))
+				ctx->file_mode = S_IALLUGO;
+			ctx->nobrl =  1;
+		} else
+			ctx->nobrl =  0;
+		break;
+	case Opt_handlecache:
+		if (result.negated)
+			ctx->nohandlecache = 1;
+		else
+			ctx->nohandlecache = 0;
+		break;
+	case Opt_forcemandatorylock:
+		ctx->mand_lock = 1;
+		break;
+	case Opt_setuids:
+		ctx->setuids = result.negated;
+		break;
+	case Opt_intr:
+		ctx->intr = !result.negated;
+		break;
+	case Opt_setuidfromacl:
+		ctx->setuidfromacl = 1;
+		break;
+	case Opt_strictsync:
+		ctx->nostrictsync = result.negated;
+		break;
+	case Opt_serverino:
+		ctx->server_ino = !result.negated;
+		break;
+	case Opt_rwpidforward:
+		ctx->rwpidforward = 1;
+		break;
+	case Opt_modesid:
+		ctx->mode_ace = 1;
+		break;
+	case Opt_cifsacl:
+		ctx->cifs_acl = !result.negated;
+		break;
+	case Opt_acl:
+		ctx->no_psx_acl = result.negated;
+		break;
+	case Opt_locallease:
+		ctx->local_lease = 1;
+		break;
+	case Opt_sign:
+		ctx->sign = true;
+		break;
+	case Opt_ignore_signature:
+		ctx->sign = true;
+		ctx->ignore_signature = true;
+		break;
+	case Opt_seal:
+		/* we do not do the following in secFlags because seal
+		 * is a per tree connection (mount) not a per socket
+		 * or per-smb connection option in the protocol
+		 * vol->secFlg |= CIFSSEC_MUST_SEAL;
+		 */
+		ctx->seal = 1;
+		break;
+	case Opt_noac:
+		pr_warn("Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n");
+		break;
+	case Opt_fsc:
+#ifndef CONFIG_CIFS_FSCACHE
+		cifs_dbg(VFS, "FS-Cache support needs CONFIG_CIFS_FSCACHE kernel config option set\n");
+		goto cifs_parse_mount_err;
+#endif
+		ctx->fsc = true;
+		break;
+	case Opt_mfsymlinks:
+		ctx->mfsymlinks = true;
+		break;
+	case Opt_multiuser:
+		ctx->multiuser = true;
+		break;
+	case Opt_sloppy:
+		ctx->sloppy = true;
+		break;
+	case Opt_nosharesock:
+		ctx->nosharesock = true;
+		break;
+	case Opt_persistent:
+		if (result.negated) {
+			if ((ctx->nopersistent) || (ctx->resilient)) {
+				cifs_dbg(VFS,
+				  "persistenthandles mount options conflict\n");
+				goto cifs_parse_mount_err;
+			}
+		} else {
+			ctx->nopersistent = true;
+			if (ctx->persistent) {
+				cifs_dbg(VFS,
+				  "persistenthandles mount options conflict\n");
+				goto cifs_parse_mount_err;
+			}
+		}
+		break;
+	case Opt_resilient:
+		if (result.negated) {
+			ctx->resilient = false; /* already the default */
+		} else {
+			ctx->resilient = true;
+			if (ctx->persistent) {
+				cifs_dbg(VFS,
+				  "persistenthandles mount options conflict\n");
+				goto cifs_parse_mount_err;
+			}
+		}
+		break;
+	case Opt_domainauto:
+		ctx->domainauto = true;
+		break;
+	case Opt_rdma:
+		ctx->rdma = true;
+		break;
+	}
+
+	return 0;
+
+ cifs_parse_mount_err:
+	return 1;
+}
+
+int smb3_init_fs_context(struct fs_context *fc)
+{
+	struct smb3_fs_context *ctx;
+	char *nodename = utsname()->nodename;
+	int i;
+
+	ctx = kzalloc(sizeof(struct smb3_fs_context), GFP_KERNEL);
+	if (unlikely(!ctx))
+		return -ENOMEM;
+
+	/*
+	 * does not have to be perfect mapping since field is
+	 * informational, only used for servers that do not support
+	 * port 445 and it can be overridden at mount time
+	 */
+	memset(ctx->source_rfc1001_name, 0x20, RFC1001_NAME_LEN);
+	for (i = 0; i < strnlen(nodename, RFC1001_NAME_LEN); i++)
+		ctx->source_rfc1001_name[i] = toupper(nodename[i]);
+
+	ctx->source_rfc1001_name[RFC1001_NAME_LEN] = 0;
+	/* null target name indicates to use *SMBSERVR default called name
+	   if we end up sending RFC1001 session initialize */
+	ctx->target_rfc1001_name[0] = 0;
+	ctx->cred_uid = current_uid();
+	ctx->linux_uid = current_uid();
+	ctx->linux_gid = current_gid();
+	ctx->bsize = 1024 * 1024; /* can improve cp performance significantly */
+
+	/*
+	 * default to SFM style remapping of seven reserved characters
+	 * unless user overrides it or we negotiate CIFS POSIX where
+	 * it is unnecessary.  Can not simultaneously use more than one mapping
+	 * since then readdir could list files that open could not open
+	 */
+	ctx->remap = true;
+
+	/* default to only allowing write access to owner of the mount */
+	ctx->dir_mode = ctx->file_mode = S_IRUGO | S_IXUGO | S_IWUSR;
+
+	/* ctx->retry default is 0 (i.e. "soft" limited retry not hard retry) */
+	/* default is always to request posix paths. */
+	ctx->posix_paths = 1;
+	/* default to using server inode numbers where available */
+	ctx->server_ino = 1;
+
+	/* default is to use strict cifs caching semantics */
+	ctx->strict_io = true;
+
+	ctx->actimeo = CIFS_DEF_ACTIMEO;
+
+	/* Most clients set timeout to 0, allows server to use its default */
+	ctx->handle_timeout = 0; /* See MS-SMB2 spec section 2.2.14.2.12 */
+
+	/* offer SMB2.1 and later (SMB3 etc). Secure and widely accepted */
+	ctx->ops = &smb30_operations;
+	ctx->vals = &smbdefault_values;
+
+	ctx->echo_interval = SMB_ECHO_INTERVAL_DEFAULT;
+
+	/* default to no multichannel (single server connection) */
+	ctx->multichannel = false;
+	ctx->max_channels = 1;
+
+	ctx->backupuid_specified = false; /* no backup intent for a user */
+	ctx->backupgid_specified = false; /* no backup intent for a group */
+
+/*	short int override_uid = -1;
+	short int override_gid = -1;
+	char *nodename = strdup(utsname()->nodename);
+	struct sockaddr *dstaddr = (struct sockaddr *)&vol->dstaddr;
+*/
+
+	fc->fs_private = ctx;
+	fc->ops = &smb3_fs_context_ops;
+	return 0;
+}
diff --git a/fs/cifs/fs_context.h b/fs/cifs/fs_context.h
index 3a66199f3cb7..6e98ef526895 100644
--- a/fs/cifs/fs_context.h
+++ b/fs/cifs/fs_context.h
@@ -9,8 +9,11 @@
 #ifndef _FS_CONTEXT_H
 #define _FS_CONTEXT_H
 
-#include <linux/parser.h>
 #include "cifsglob.h"
+#include <linux/parser.h>
+#include <linux/fs_parser.h>
+
+#define cifs_invalf(fc, fmt, ...) invalf(fc, fmt, ## __VA_ARGS__)
 
 enum smb_version {
 	Smb_1 = 1,
@@ -24,8 +27,6 @@ enum smb_version {
 	Smb_version_err
 };
 
-int cifs_parse_smb_version(char *value, struct smb3_fs_context *ctx, bool is_smb3);
-
 enum {
 	Opt_cache_loose,
 	Opt_cache_strict,
@@ -35,8 +36,6 @@ enum {
 	Opt_cache_err
 };
 
-int cifs_parse_cache_flavor(char *value, struct smb3_fs_context *ctx);
-
 enum cifs_sec_param {
 	Opt_sec_krb5,
 	Opt_sec_krb5i,
@@ -55,36 +54,36 @@ enum cifs_sec_param {
 
 enum cifs_param {
 	/* Mount options that take no arguments */
-	Opt_user_xattr, Opt_nouser_xattr,
-	Opt_forceuid, Opt_noforceuid,
-	Opt_forcegid, Opt_noforcegid,
+	Opt_user_xattr,
+	Opt_forceuid,
+	Opt_forcegid,
 	Opt_noblocksend,
 	Opt_noautotune,
 	Opt_nolease,
-	Opt_hard, Opt_nohard,
-	Opt_soft, Opt_nosoft,
-	Opt_perm, Opt_noperm,
+	Opt_hard,
+	Opt_soft,
+	Opt_perm,
 	Opt_nodelete,
-	Opt_mapposix, Opt_nomapposix,
+	Opt_mapposix,
 	Opt_mapchars,
 	Opt_nomapchars,
-	Opt_sfu, Opt_nosfu,
+	Opt_sfu,
 	Opt_nodfs,
-	Opt_posixpaths, Opt_noposixpaths,
-	Opt_unix, Opt_nounix,
+	Opt_posixpaths,
+	Opt_unix,
 	Opt_nocase,
-	Opt_brl, Opt_nobrl,
-	Opt_handlecache, Opt_nohandlecache,
+	Opt_brl,
+	Opt_handlecache,
 	Opt_forcemandatorylock,
 	Opt_setuidfromacl,
-	Opt_setuids, Opt_nosetuids,
-	Opt_dynperm, Opt_nodynperm,
-	Opt_intr, Opt_nointr,
-	Opt_strictsync, Opt_nostrictsync,
-	Opt_serverino, Opt_noserverino,
+	Opt_setuids,
+	Opt_dynperm,
+	Opt_intr,
+	Opt_strictsync,
+	Opt_serverino,
 	Opt_rwpidforward,
-	Opt_cifsacl, Opt_nocifsacl,
-	Opt_acl, Opt_noacl,
+	Opt_cifsacl,
+	Opt_acl,
 	Opt_locallease,
 	Opt_sign,
 	Opt_ignore_signature,
@@ -95,13 +94,13 @@ enum cifs_param {
 	Opt_multiuser,
 	Opt_sloppy,
 	Opt_nosharesock,
-	Opt_persistent, Opt_nopersistent,
-	Opt_resilient, Opt_noresilient,
+	Opt_persistent,
+	Opt_resilient,
 	Opt_domainauto,
 	Opt_rdma,
 	Opt_modesid,
 	Opt_rootfs,
-	Opt_multichannel, Opt_nomultichannel,
+	Opt_multichannel,
 	Opt_compress,
 
 	/* Mount options which take numeric value */
@@ -142,11 +141,6 @@ enum cifs_param {
 	/* Mount options to be ignored */
 	Opt_ignore,
 
-	/* Options which could be blank */
-	Opt_blank_pass,
-	Opt_blank_user,
-	Opt_blank_ip,
-
 	Opt_err
 };
 
@@ -247,9 +241,24 @@ struct smb3_fs_context {
 	unsigned int max_channels;
 	__u16 compression; /* compression algorithm 0xFFFF default 0=disabled */
 	bool rootfs:1; /* if it's a SMB root file system */
+
+	char *mount_options;
 };
 
-extern int cifs_parse_security_flavors(char *value, struct smb3_fs_context *ctx);
+extern const struct fs_parameter_spec smb3_fs_parameters[];
+
+extern int cifs_parse_cache_flavor(char *value,
+				   struct smb3_fs_context *ctx);
+extern int cifs_parse_security_flavors(char *value,
+				       struct smb3_fs_context *ctx);
+extern int smb3_init_fs_context(struct fs_context *fc);
+
+static inline struct smb3_fs_context *smb3_fc2context(const struct fs_context *fc \
+						    )
+{
+  return fc->fs_private;
+}
+
 extern int smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx);
 
 #endif
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index f2055f99cc7b..b0e4bf2cd473 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -195,7 +195,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface)
 	 * We need to setup at least the fields used for negprot and
 	 * sesssetup.
 	 *
-	 * We only need the volume here, so we can reuse memory from
+	 * We only need the ctx here, so we can reuse memory from
 	 * the session and server without caring about memory
 	 * management.
 	 */
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 06/21] cifs: remove the devname argument to cifs_compose_mount_options
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
                   ` (3 preceding siblings ...)
  2020-12-07 23:36 ` [PATCH 05/21] cifs: switch to new mount api Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 07/21] cifs: add an smb3_fs_context to cifs_sb Ronnie Sahlberg
                   ` (14 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

none of the callers use this argument any more.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/cifs_dfs_ref.c | 11 +++--------
 fs/cifs/cifsproto.h    |  3 +--
 fs/cifs/connect.c      | 11 +++--------
 fs/cifs/dfs_cache.c    |  6 ++----
 4 files changed, 9 insertions(+), 22 deletions(-)

diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index 4b0b9cfe2ab1..81f6066d5865 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -124,7 +124,6 @@ cifs_build_devname(char *nodename, const char *prepath)
  * @sb_mountdata:	parent/root DFS mount options (template)
  * @fullpath:		full path in UNC format
  * @ref:		optional server's referral
- * @devname:		optional pointer for saving device name
  *
  * creates mount options for submount based on template options sb_mountdata
  * and replacing unc,ip,prefixpath options with ones we've got form ref_unc.
@@ -134,8 +133,7 @@ cifs_build_devname(char *nodename, const char *prepath)
  */
 char *cifs_compose_mount_options(const char *sb_mountdata,
 				   const char *fullpath,
-				   const struct dfs_info3_param *ref,
-				   char **devname)
+				   const struct dfs_info3_param *ref)
 {
 	int rc;
 	char *name;
@@ -232,10 +230,7 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
 	strcat(mountdata, "ip=");
 	strcat(mountdata, srvIP);
 
-	if (devname)
-		*devname = name;
-	else
-		kfree(name);
+	kfree(name);
 
 	/*cifs_dbg(FYI, "%s: parent mountdata: %s\n", __func__, sb_mountdata);*/
 	/*cifs_dbg(FYI, "%s: submount mountdata: %s\n", __func__, mountdata );*/
@@ -281,7 +276,7 @@ static struct vfsmount *cifs_dfs_do_mount(struct dentry *mntpt,
 
 	/* strip first '\' from fullpath */
 	mountdata = cifs_compose_mount_options(cifs_sb->mountdata,
-					       fullpath + 1, NULL, NULL);
+					       fullpath + 1, NULL);
 	if (IS_ERR(mountdata)) {
 		kfree(devname);
 		return (struct vfsmount *)mountdata;
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 49a122978772..19ee76f3a96f 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -78,8 +78,7 @@ extern char *cifs_build_path_to_root(struct smb3_fs_context *ctx,
 				     int add_treename);
 extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
 extern char *cifs_compose_mount_options(const char *sb_mountdata,
-		const char *fullpath, const struct dfs_info3_param *ref,
-		char **devname);
+		const char *fullpath, const struct dfs_info3_param *ref);
 /* extern void renew_parental_timestamps(struct dentry *direntry);*/
 extern struct mid_q_entry *AllocMidQEntry(const struct smb_hdr *smb_buffer,
 					struct TCP_Server_Info *server);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 081e61a212cd..dd7c2058ecf6 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -3019,11 +3019,8 @@ expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
 	rc = dfs_cache_find(xid, ses, cifs_sb->local_nls, cifs_remap(cifs_sb),
 			    ref_path, &referral, NULL);
 	if (!rc) {
-		char *fake_devname = NULL;
-
 		mdata = cifs_compose_mount_options(cifs_sb->mountdata,
-						   full_path + 1, &referral,
-						   &fake_devname);
+						   full_path + 1, &referral);
 		free_dfs_info_param(&referral);
 
 		if (IS_ERR(mdata)) {
@@ -3033,7 +3030,6 @@ expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
 			cifs_cleanup_volume_info_contents(ctx);
 			rc = cifs_setup_volume_info(ctx);
 		}
-		kfree(fake_devname);
 		kfree(cifs_sb->mountdata);
 		cifs_sb->mountdata = mdata;
 	}
@@ -3085,7 +3081,7 @@ static int setup_dfs_tgt_conn(const char *path, const char *full_path,
 {
 	int rc;
 	struct dfs_info3_param ref = {0};
-	char *mdata = NULL, *fake_devname = NULL;
+	char *mdata = NULL;
 	struct smb3_fs_context fake_ctx = {NULL};
 
 	cifs_dbg(FYI, "%s: dfs path: %s\n", __func__, path);
@@ -3094,7 +3090,7 @@ static int setup_dfs_tgt_conn(const char *path, const char *full_path,
 	if (rc)
 		return rc;
 
-	mdata = cifs_compose_mount_options(cifs_sb->mountdata, full_path + 1, &ref, &fake_devname);
+	mdata = cifs_compose_mount_options(cifs_sb->mountdata, full_path + 1, &ref);
 	free_dfs_info_param(&ref);
 
 	if (IS_ERR(mdata)) {
@@ -3104,7 +3100,6 @@ static int setup_dfs_tgt_conn(const char *path, const char *full_path,
 		rc = cifs_setup_volume_info(&fake_ctx);
 	}
 	kfree(mdata);
-	kfree(fake_devname);
 
 	if (!rc) {
 		/*
diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c
index dde859c21f1a..6bccff4596bf 100644
--- a/fs/cifs/dfs_cache.c
+++ b/fs/cifs/dfs_cache.c
@@ -1416,7 +1416,7 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi,
 	int rc;
 	struct cache_entry *ce;
 	struct dfs_info3_param ref = {0};
-	char *mdata = NULL, *devname = NULL;
+	char *mdata = NULL;
 	struct TCP_Server_Info *server;
 	struct cifs_ses *ses;
 	struct smb3_fs_context ctx = {NULL};
@@ -1443,8 +1443,7 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi,
 
 	up_read(&htable_rw_lock);
 
-	mdata = cifs_compose_mount_options(vi->mntdata, rpath, &ref,
-					   &devname);
+	mdata = cifs_compose_mount_options(vi->mntdata, rpath, &ref);
 	free_dfs_info_param(&ref);
 
 	if (IS_ERR(mdata)) {
@@ -1454,7 +1453,6 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi,
 	}
 
 	rc = cifs_setup_volume_info(&ctx);
-	kfree(devname);
 
 	if (rc) {
 		ses = ERR_PTR(rc);
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 07/21] cifs: add an smb3_fs_context to cifs_sb
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
                   ` (4 preceding siblings ...)
  2020-12-07 23:36 ` [PATCH 06/21] cifs: remove the devname argument to cifs_compose_mount_options Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 08/21] cifs: get rid of cifs_sb->mountdata Ronnie Sahlberg
                   ` (13 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

and populate it during mount in cifs_smb3_do_mount()

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/cifs_fs_sb.h |  1 +
 fs/cifs/cifsfs.c     | 60 +++++++++++++++++++++++++---------------------------
 fs/cifs/connect.c    | 13 +++++++++---
 3 files changed, 40 insertions(+), 34 deletions(-)

diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 6e7c4427369d..34d0229c0519 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -61,6 +61,7 @@ struct cifs_sb_info {
 	spinlock_t tlink_tree_lock;
 	struct tcon_link *master_tlink;
 	struct nls_table *local_nls;
+	struct smb3_fs_context *ctx;
 	unsigned int bsize;
 	unsigned int rsize;
 	unsigned int wsize;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 907c82428c42..7fe6502e1672 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -776,8 +776,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
 {
 	int rc;
 	struct super_block *sb;
-	struct cifs_sb_info *cifs_sb;
-	struct smb3_fs_context *ctx;
+	struct cifs_sb_info *cifs_sb = NULL;
 	struct cifs_mnt_data mnt_data;
 	struct dentry *root;
 
@@ -790,49 +789,51 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
 	else
 		cifs_info("Attempting to mount %s\n", old_ctx->UNC);
 
-	ctx = kzalloc(sizeof(struct smb3_fs_context), GFP_KERNEL);
-	if (!ctx)
-		return ERR_PTR(-ENOMEM);
-	rc = smb3_fs_context_dup(ctx, old_ctx);
-	if (rc) {
-		root = ERR_PTR(rc);
+	cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
+	if (cifs_sb == NULL) {
+		root = ERR_PTR(-ENOMEM);
 		goto out;
 	}
 
-	rc = cifs_setup_volume_info(ctx);
+	cifs_sb->ctx = kzalloc(sizeof(struct smb3_fs_context), GFP_KERNEL);
+	if (!cifs_sb->ctx) {
+		root = ERR_PTR(-ENOMEM);
+		goto out;
+	}
+	rc = smb3_fs_context_dup(cifs_sb->ctx, old_ctx);
 	if (rc) {
 		root = ERR_PTR(rc);
 		goto out;
 	}
 
-	cifs_sb = kzalloc(sizeof(struct cifs_sb_info), GFP_KERNEL);
-	if (cifs_sb == NULL) {
-		root = ERR_PTR(-ENOMEM);
-		goto out_nls;
+	rc = cifs_setup_volume_info(cifs_sb->ctx);
+	if (rc) {
+		root = ERR_PTR(rc);
+		goto out;
 	}
 
-	cifs_sb->mountdata = kstrndup(ctx->mount_options, PAGE_SIZE, GFP_KERNEL);
+	cifs_sb->mountdata = kstrndup(cifs_sb->ctx->mount_options, PAGE_SIZE, GFP_KERNEL);
 	if (cifs_sb->mountdata == NULL) {
 		root = ERR_PTR(-ENOMEM);
-		goto out_free;
+		goto out;
 	}
 
-	rc = cifs_setup_cifs_sb(ctx, cifs_sb);
+	rc = cifs_setup_cifs_sb(cifs_sb->ctx, cifs_sb);
 	if (rc) {
 		root = ERR_PTR(rc);
-		goto out_free;
+		goto out;
 	}
 
-	rc = cifs_mount(cifs_sb, ctx);
+	rc = cifs_mount(cifs_sb, cifs_sb->ctx);
 	if (rc) {
 		if (!(flags & SB_SILENT))
 			cifs_dbg(VFS, "cifs_mount failed w/return code = %d\n",
 				 rc);
 		root = ERR_PTR(rc);
-		goto out_free;
+		goto out;
 	}
 
-	mnt_data.ctx = ctx;
+	mnt_data.ctx = cifs_sb->ctx;
 	mnt_data.cifs_sb = cifs_sb;
 	mnt_data.flags = flags;
 
@@ -859,26 +860,23 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
 		sb->s_flags |= SB_ACTIVE;
 	}
 
-	root = cifs_get_root(ctx, sb);
+	root = cifs_get_root(cifs_sb->ctx, sb);
 	if (IS_ERR(root))
 		goto out_super;
 
 	cifs_dbg(FYI, "dentry root is: %p\n", root);
-	goto out;
+	return root;
 
 out_super:
 	deactivate_locked_super(sb);
 out:
-	cifs_cleanup_volume_info(ctx);
+	if (cifs_sb) {
+		kfree(cifs_sb->prepath);
+		kfree(cifs_sb->mountdata);
+		cifs_cleanup_volume_info(cifs_sb->ctx);
+		kfree(cifs_sb);
+	}
 	return root;
-
-out_free:
-	kfree(cifs_sb->prepath);
-	kfree(cifs_sb->mountdata);
-	kfree(cifs_sb);
-out_nls:
-	unload_nls(ctx->local_nls);
-	goto out;
 }
 
 
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index dd7c2058ecf6..20acd741fda2 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2786,6 +2786,9 @@ int cifs_setup_cifs_sb(struct smb3_fs_context *ctx,
 void
 cifs_cleanup_volume_info_contents(struct smb3_fs_context *ctx)
 {
+	if (ctx == NULL)
+		return;
+
 	/*
 	 * Make sure this stays in sync with smb3_fs_context_dup()
 	 */
@@ -2805,6 +2808,9 @@ cifs_cleanup_volume_info_contents(struct smb3_fs_context *ctx)
 	ctx->iocharset = NULL;
 	kfree(ctx->prepath);
 	ctx->prepath = NULL;
+
+	unload_nls(ctx->local_nls);
+	ctx->local_nls = NULL;
 }
 
 void
@@ -3725,9 +3731,10 @@ CIFSTCon(const unsigned int xid, struct cifs_ses *ses,
 
 static void delayed_free(struct rcu_head *p)
 {
-	struct cifs_sb_info *sbi = container_of(p, struct cifs_sb_info, rcu);
-	unload_nls(sbi->local_nls);
-	kfree(sbi);
+	struct cifs_sb_info *cifs_sb = container_of(p, struct cifs_sb_info, rcu);
+	unload_nls(cifs_sb->local_nls);
+	cifs_cleanup_volume_info(cifs_sb->ctx);
+	kfree(cifs_sb);
 }
 
 void
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 08/21] cifs: get rid of cifs_sb->mountdata
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
                   ` (5 preceding siblings ...)
  2020-12-07 23:36 ` [PATCH 07/21] cifs: add an smb3_fs_context to cifs_sb Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 09/21] cifs: remove [gu]id/backup[gu]id/file_mode/dir_mode from cifs_sb Ronnie Sahlberg
                   ` (12 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

as we now have a full smb3_fs_context as part of the cifs superblock
we no longer need a local copy of the mount options and can just
reference the copy in the smb3_fs_context.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/cifs_dfs_ref.c |  3 ++-
 fs/cifs/cifs_fs_sb.h   |  1 -
 fs/cifs/cifsfs.c       |  7 -------
 fs/cifs/connect.c      | 19 ++++++++++---------
 4 files changed, 12 insertions(+), 18 deletions(-)

diff --git a/fs/cifs/cifs_dfs_ref.c b/fs/cifs/cifs_dfs_ref.c
index 81f6066d5865..6f7187b90fda 100644
--- a/fs/cifs/cifs_dfs_ref.c
+++ b/fs/cifs/cifs_dfs_ref.c
@@ -23,6 +23,7 @@
 #include "cifs_debug.h"
 #include "cifs_unicode.h"
 #include "dfs_cache.h"
+#include "fs_context.h"
 
 static LIST_HEAD(cifs_dfs_automount_list);
 
@@ -275,7 +276,7 @@ static struct vfsmount *cifs_dfs_do_mount(struct dentry *mntpt,
 	/* See afs_mntpt_do_automount in fs/afs/mntpt.c for an example */
 
 	/* strip first '\' from fullpath */
-	mountdata = cifs_compose_mount_options(cifs_sb->mountdata,
+	mountdata = cifs_compose_mount_options(cifs_sb->ctx->mount_options,
 					       fullpath + 1, NULL);
 	if (IS_ERR(mountdata)) {
 		kfree(devname);
diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 34d0229c0519..8ee37c80880a 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -74,7 +74,6 @@ struct cifs_sb_info {
 	umode_t	mnt_file_mode;
 	umode_t	mnt_dir_mode;
 	unsigned int mnt_cifs_flags;
-	char   *mountdata; /* options received at mount time or via DFS refs */
 	struct delayed_work prune_tlinks;
 	struct rcu_head rcu;
 
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 7fe6502e1672..4f27f77d3053 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -812,12 +812,6 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
 		goto out;
 	}
 
-	cifs_sb->mountdata = kstrndup(cifs_sb->ctx->mount_options, PAGE_SIZE, GFP_KERNEL);
-	if (cifs_sb->mountdata == NULL) {
-		root = ERR_PTR(-ENOMEM);
-		goto out;
-	}
-
 	rc = cifs_setup_cifs_sb(cifs_sb->ctx, cifs_sb);
 	if (rc) {
 		root = ERR_PTR(rc);
@@ -872,7 +866,6 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
 out:
 	if (cifs_sb) {
 		kfree(cifs_sb->prepath);
-		kfree(cifs_sb->mountdata);
 		cifs_cleanup_volume_info(cifs_sb->ctx);
 		kfree(cifs_sb);
 	}
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 20acd741fda2..7fc27fb49789 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2999,7 +2999,7 @@ build_unc_path_to_root(const struct smb3_fs_context *ctx,
  * expand_dfs_referral - Perform a dfs referral query and update the cifs_sb
  *
  *
- * If a referral is found, cifs_sb->mountdata will be (re-)allocated
+ * If a referral is found, cifs_sb->ctx->mount_options will be (re-)allocated
  * to a string containing updated options for the submount.  Otherwise it
  * will be left untouched.
  *
@@ -3025,7 +3025,7 @@ expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
 	rc = dfs_cache_find(xid, ses, cifs_sb->local_nls, cifs_remap(cifs_sb),
 			    ref_path, &referral, NULL);
 	if (!rc) {
-		mdata = cifs_compose_mount_options(cifs_sb->mountdata,
+		mdata = cifs_compose_mount_options(cifs_sb->ctx->mount_options,
 						   full_path + 1, &referral);
 		free_dfs_info_param(&referral);
 
@@ -3036,8 +3036,8 @@ expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
 			cifs_cleanup_volume_info_contents(ctx);
 			rc = cifs_setup_volume_info(ctx);
 		}
-		kfree(cifs_sb->mountdata);
-		cifs_sb->mountdata = mdata;
+		kfree(cifs_sb->ctx->mount_options);
+		cifs_sb->ctx->mount_options = mdata;
 	}
 	kfree(full_path);
 	return rc;
@@ -3096,7 +3096,8 @@ static int setup_dfs_tgt_conn(const char *path, const char *full_path,
 	if (rc)
 		return rc;
 
-	mdata = cifs_compose_mount_options(cifs_sb->mountdata, full_path + 1, &ref);
+	mdata = cifs_compose_mount_options(cifs_sb->ctx->mount_options,
+					   full_path + 1, &ref);
 	free_dfs_info_param(&ref);
 
 	if (IS_ERR(mdata)) {
@@ -3424,7 +3425,8 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
 			goto error;
 	}
 	/* Save mount options */
-	mntdata = kstrndup(cifs_sb->mountdata, strlen(cifs_sb->mountdata), GFP_KERNEL);
+	mntdata = kstrndup(cifs_sb->ctx->mount_options,
+			   strlen(cifs_sb->ctx->mount_options), GFP_KERNEL);
 	if (!mntdata) {
 		rc = -ENOMEM;
 		goto error;
@@ -3448,12 +3450,12 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
 			break;
 		}
 		/* Chase referral */
-		oldmnt = cifs_sb->mountdata;
+		oldmnt = cifs_sb->ctx->mount_options;
 		rc = expand_dfs_referral(xid, root_ses, ctx, cifs_sb, ref_path + 1);
 		if (rc)
 			break;
 		/* Connect to new DFS target only if we were redirected */
-		if (oldmnt != cifs_sb->mountdata) {
+		if (oldmnt != cifs_sb->ctx->mount_options) {
 			mount_put_conns(cifs_sb, xid, server, ses, tcon);
 			rc = mount_get_conns(ctx, cifs_sb, &xid, &server, &ses, &tcon);
 		}
@@ -3759,7 +3761,6 @@ cifs_umount(struct cifs_sb_info *cifs_sb)
 	}
 	spin_unlock(&cifs_sb->tlink_tree_lock);
 
-	kfree(cifs_sb->mountdata);
 	kfree(cifs_sb->prepath);
 #ifdef CONFIG_CIFS_DFS_UPCALL
 	dfs_cache_del_vol(cifs_sb->origin_fullpath);
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 09/21] cifs: remove [gu]id/backup[gu]id/file_mode/dir_mode from cifs_sb
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
                   ` (6 preceding siblings ...)
  2020-12-07 23:36 ` [PATCH 08/21] cifs: get rid of cifs_sb->mountdata Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-12 19:42   ` Steve French
  2020-12-07 23:36 ` [PATCH 10/21] cifs: remove actimeo " Ronnie Sahlberg
                   ` (11 subsequent siblings)
  19 siblings, 1 reply; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

We can already access these from cifs_sb->ctx so we no longer need
a local copy in cifs_sb.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/cifs_fs_sb.h |  6 ------
 fs/cifs/cifsacl.c    |  7 ++++---
 fs/cifs/cifsfs.c     | 12 ++++++------
 fs/cifs/connect.c    | 15 +++++----------
 fs/cifs/file.c       |  5 +++--
 fs/cifs/inode.c      | 29 +++++++++++++++--------------
 fs/cifs/misc.c       |  5 +++--
 fs/cifs/readdir.c    |  9 +++++----
 8 files changed, 41 insertions(+), 47 deletions(-)

diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 8ee37c80880a..3f4f1487f714 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -67,12 +67,6 @@ struct cifs_sb_info {
 	unsigned int wsize;
 	unsigned long actimeo; /* attribute cache timeout (jiffies) */
 	atomic_t active;
-	kuid_t	mnt_uid;
-	kgid_t	mnt_gid;
-	kuid_t	mnt_backupuid;
-	kgid_t	mnt_backupgid;
-	umode_t	mnt_file_mode;
-	umode_t	mnt_dir_mode;
 	unsigned int mnt_cifs_flags;
 	struct delayed_work prune_tlinks;
 	struct rcu_head rcu;
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index 23b21e943652..d4e33bba4713 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -32,6 +32,7 @@
 #include "cifsacl.h"
 #include "cifsproto.h"
 #include "cifs_debug.h"
+#include "fs_context.h"
 
 /* security id for everyone/world system group */
 static const struct cifs_sid sid_everyone = {
@@ -346,8 +347,8 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
 	struct key *sidkey;
 	char *sidstr;
 	const struct cred *saved_cred;
-	kuid_t fuid = cifs_sb->mnt_uid;
-	kgid_t fgid = cifs_sb->mnt_gid;
+	kuid_t fuid = cifs_sb->ctx->linux_uid;
+	kgid_t fgid = cifs_sb->ctx->linux_gid;
 
 	/*
 	 * If we have too many subauthorities, then something is really wrong.
@@ -448,7 +449,7 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
 
 	/*
 	 * Note that we return 0 here unconditionally. If the mapping
-	 * fails then we just fall back to using the mnt_uid/mnt_gid.
+	 * fails then we just fall back to using the ctx->linux_uid/linux_gid.
 	 */
 got_valid_id:
 	rc = 0;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 4f27f77d3053..4ea8c3c3bce1 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -515,14 +515,14 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
 	}
 
 	seq_printf(s, ",uid=%u",
-		   from_kuid_munged(&init_user_ns, cifs_sb->mnt_uid));
+		   from_kuid_munged(&init_user_ns, cifs_sb->ctx->linux_uid));
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
 		seq_puts(s, ",forceuid");
 	else
 		seq_puts(s, ",noforceuid");
 
 	seq_printf(s, ",gid=%u",
-		   from_kgid_munged(&init_user_ns, cifs_sb->mnt_gid));
+		   from_kgid_munged(&init_user_ns, cifs_sb->ctx->linux_gid));
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
 		seq_puts(s, ",forcegid");
 	else
@@ -532,8 +532,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
 
 	if (!tcon->unix_ext)
 		seq_printf(s, ",file_mode=0%ho,dir_mode=0%ho",
-					   cifs_sb->mnt_file_mode,
-					   cifs_sb->mnt_dir_mode);
+					   cifs_sb->ctx->file_mode,
+					   cifs_sb->ctx->dir_mode);
 
 	cifs_show_nls(s, cifs_sb->local_nls);
 
@@ -606,11 +606,11 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID)
 		seq_printf(s, ",backupuid=%u",
 			   from_kuid_munged(&init_user_ns,
-					    cifs_sb->mnt_backupuid));
+					    cifs_sb->ctx->backupuid));
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID)
 		seq_printf(s, ",backupgid=%u",
 			   from_kgid_munged(&init_user_ns,
-					    cifs_sb->mnt_backupgid));
+					    cifs_sb->ctx->backupgid));
 
 	seq_printf(s, ",rsize=%u", cifs_sb->rsize);
 	seq_printf(s, ",wsize=%u", cifs_sb->wsize);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 7fc27fb49789..96c5b66d4b44 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2225,11 +2225,12 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
 	if (new->rsize && new->rsize < old->rsize)
 		return 0;
 
-	if (!uid_eq(old->mnt_uid, new->mnt_uid) || !gid_eq(old->mnt_gid, new->mnt_gid))
+	if (!uid_eq(old->ctx->linux_uid, new->ctx->linux_uid) ||
+	    !gid_eq(old->ctx->linux_gid, new->ctx->linux_gid))
 		return 0;
 
-	if (old->mnt_file_mode != new->mnt_file_mode ||
-	    old->mnt_dir_mode != new->mnt_dir_mode)
+	if (old->ctx->file_mode != new->ctx->file_mode ||
+	    old->ctx->dir_mode != new->ctx->dir_mode)
 		return 0;
 
 	if (strcmp(old->local_nls->charset, new->local_nls->charset))
@@ -2678,12 +2679,8 @@ int cifs_setup_cifs_sb(struct smb3_fs_context *ctx,
 	cifs_sb->rsize = ctx->rsize;
 	cifs_sb->wsize = ctx->wsize;
 
-	cifs_sb->mnt_uid = ctx->linux_uid;
-	cifs_sb->mnt_gid = ctx->linux_gid;
-	cifs_sb->mnt_file_mode = ctx->file_mode;
-	cifs_sb->mnt_dir_mode = ctx->dir_mode;
 	cifs_dbg(FYI, "file mode: %04ho  dir mode: %04ho\n",
-		 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
+		 cifs_sb->ctx->file_mode, cifs_sb->ctx->dir_mode);
 
 	cifs_sb->actimeo = ctx->actimeo;
 	cifs_sb->local_nls = ctx->local_nls;
@@ -2722,11 +2719,9 @@ int cifs_setup_cifs_sb(struct smb3_fs_context *ctx,
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
 	if (ctx->backupuid_specified) {
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID;
-		cifs_sb->mnt_backupuid = ctx->backupuid;
 	}
 	if (ctx->backupgid_specified) {
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID;
-		cifs_sb->mnt_backupgid = ctx->backupgid;
 	}
 	if (ctx->override_uid)
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index be46fab4c96d..3ee510d3dab8 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -44,6 +44,7 @@
 #include "cifs_fs_sb.h"
 #include "fscache.h"
 #include "smbdirect.h"
+#include "fs_context.h"
 
 static inline int cifs_convert_flags(unsigned int flags)
 {
@@ -566,7 +567,7 @@ int cifs_open(struct inode *inode, struct file *file)
 				le64_to_cpu(tcon->fsUnixInfo.Capability))) {
 		/* can not refresh inode info since size could be stale */
 		rc = cifs_posix_open(full_path, &inode, inode->i_sb,
-				cifs_sb->mnt_file_mode /* ignored */,
+				cifs_sb->ctx->file_mode /* ignored */,
 				file->f_flags, &oplock, &fid.netfid, xid);
 		if (rc == 0) {
 			cifs_dbg(FYI, "posix open succeeded\n");
@@ -735,7 +736,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
 						~(O_CREAT | O_EXCL | O_TRUNC);
 
 		rc = cifs_posix_open(full_path, NULL, inode->i_sb,
-				     cifs_sb->mnt_file_mode /* ignored */,
+				     cifs_sb->ctx->file_mode /* ignored */,
 				     oflags, &oplock, &cfile->fid.netfid, xid);
 		if (rc == 0) {
 			cifs_dbg(FYI, "posix reopen succeeded\n");
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index daec31be8571..e8a7110db2a6 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -37,6 +37,7 @@
 #include "cifs_fs_sb.h"
 #include "cifs_unicode.h"
 #include "fscache.h"
+#include "fs_context.h"
 
 
 static void cifs_set_ops(struct inode *inode)
@@ -294,7 +295,7 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
 		break;
 	}
 
-	fattr->cf_uid = cifs_sb->mnt_uid;
+	fattr->cf_uid = cifs_sb->ctx->linux_uid;
 	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) {
 		u64 id = le64_to_cpu(info->Uid);
 		if (id < ((uid_t)-1)) {
@@ -304,7 +305,7 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
 		}
 	}
 	
-	fattr->cf_gid = cifs_sb->mnt_gid;
+	fattr->cf_gid = cifs_sb->ctx->linux_gid;
 	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) {
 		u64 id = le64_to_cpu(info->Gid);
 		if (id < ((gid_t)-1)) {
@@ -333,8 +334,8 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
 
 	memset(fattr, 0, sizeof(*fattr));
 	fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
-	fattr->cf_uid = cifs_sb->mnt_uid;
-	fattr->cf_gid = cifs_sb->mnt_gid;
+	fattr->cf_uid = cifs_sb->ctx->linux_uid;
+	fattr->cf_gid = cifs_sb->ctx->linux_gid;
 	ktime_get_coarse_real_ts64(&fattr->cf_mtime);
 	fattr->cf_atime = fattr->cf_ctime = fattr->cf_mtime;
 	fattr->cf_nlink = 2;
@@ -644,8 +645,8 @@ smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct smb311_posix_qinfo *
 	}
 	/* else if reparse point ... TODO: add support for FIFO and blk dev; special file types */
 
-	fattr->cf_uid = cifs_sb->mnt_uid; /* TODO: map uid and gid from SID */
-	fattr->cf_gid = cifs_sb->mnt_gid;
+	fattr->cf_uid = cifs_sb->ctx->linux_uid; /* TODO: map uid and gid from SID */
+	fattr->cf_gid = cifs_sb->ctx->linux_gid;
 
 	cifs_dbg(FYI, "POSIX query info: mode 0x%x uniqueid 0x%llx nlink %d\n",
 		fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink);
@@ -689,7 +690,7 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
 		fattr->cf_mode = S_IFLNK;
 		fattr->cf_dtype = DT_LNK;
 	} else if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
-		fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
+		fattr->cf_mode = S_IFDIR | cifs_sb->ctx->dir_mode;
 		fattr->cf_dtype = DT_DIR;
 		/*
 		 * Server can return wrong NumberOfLinks value for directories
@@ -698,7 +699,7 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
 		if (!tcon->unix_ext)
 			fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK;
 	} else {
-		fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
+		fattr->cf_mode = S_IFREG | cifs_sb->ctx->file_mode;
 		fattr->cf_dtype = DT_REG;
 
 		/* clear write bits if ATTR_READONLY is set */
@@ -717,8 +718,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
 		}
 	}
 
-	fattr->cf_uid = cifs_sb->mnt_uid;
-	fattr->cf_gid = cifs_sb->mnt_gid;
+	fattr->cf_uid = cifs_sb->ctx->linux_uid;
+	fattr->cf_gid = cifs_sb->ctx->linux_gid;
 }
 
 static int
@@ -1358,8 +1359,8 @@ struct inode *cifs_root_iget(struct super_block *sb)
 		set_nlink(inode, 2);
 		inode->i_op = &cifs_ipc_inode_ops;
 		inode->i_fop = &simple_dir_operations;
-		inode->i_uid = cifs_sb->mnt_uid;
-		inode->i_gid = cifs_sb->mnt_gid;
+		inode->i_uid = cifs_sb->ctx->linux_uid;
+		inode->i_gid = cifs_sb->ctx->linux_gid;
 		spin_unlock(&inode->i_lock);
 	} else if (rc) {
 		iget_failed(inode);
@@ -2834,10 +2835,10 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
 				attrs->ia_mode &= ~(S_IALLUGO);
 				if (S_ISDIR(inode->i_mode))
 					attrs->ia_mode |=
-						cifs_sb->mnt_dir_mode;
+						cifs_sb->ctx->dir_mode;
 				else
 					attrs->ia_mode |=
-						cifs_sb->mnt_file_mode;
+						cifs_sb->ctx->file_mode;
 			}
 		} else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
 			/* ignore mode change - ATTR_READONLY hasn't changed */
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 1c14cf01dbef..82e176720ca6 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -35,6 +35,7 @@
 #ifdef CONFIG_CIFS_DFS_UPCALL
 #include "dns_resolve.h"
 #endif
+#include "fs_context.h"
 
 extern mempool_t *cifs_sm_req_poolp;
 extern mempool_t *cifs_req_poolp;
@@ -632,11 +633,11 @@ bool
 backup_cred(struct cifs_sb_info *cifs_sb)
 {
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) {
-		if (uid_eq(cifs_sb->mnt_backupuid, current_fsuid()))
+		if (uid_eq(cifs_sb->ctx->backupuid, current_fsuid()))
 			return true;
 	}
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) {
-		if (in_group_p(cifs_sb->mnt_backupgid))
+		if (in_group_p(cifs_sb->ctx->backupgid))
 			return true;
 	}
 
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 5abf1ea21abe..70676843e169 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -33,6 +33,7 @@
 #include "cifs_fs_sb.h"
 #include "cifsfs.h"
 #include "smb2proto.h"
+#include "fs_context.h"
 
 /*
  * To be safe - for UCS to UTF-8 with strings loaded with the rare long
@@ -165,14 +166,14 @@ static bool reparse_file_needs_reval(const struct cifs_fattr *fattr)
 static void
 cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
 {
-	fattr->cf_uid = cifs_sb->mnt_uid;
-	fattr->cf_gid = cifs_sb->mnt_gid;
+	fattr->cf_uid = cifs_sb->ctx->linux_uid;
+	fattr->cf_gid = cifs_sb->ctx->linux_gid;
 
 	if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
-		fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
+		fattr->cf_mode = S_IFDIR | cifs_sb->ctx->dir_mode;
 		fattr->cf_dtype = DT_DIR;
 	} else {
-		fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
+		fattr->cf_mode = S_IFREG | cifs_sb->ctx->file_mode;
 		fattr->cf_dtype = DT_REG;
 	}
 
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 10/21] cifs: remove actimeo from cifs_sb
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
                   ` (7 preceding siblings ...)
  2020-12-07 23:36 ` [PATCH 09/21] cifs: remove [gu]id/backup[gu]id/file_mode/dir_mode from cifs_sb Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-12 19:44   ` Steve French
  2020-12-07 23:36 ` [PATCH 11/21] cifs: move cifs_cleanup_volume_info[_content] to fs_context.c Ronnie Sahlberg
                   ` (10 subsequent siblings)
  19 siblings, 1 reply; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/cifs_fs_sb.h | 1 -
 fs/cifs/cifsfs.c     | 2 +-
 fs/cifs/connect.c    | 3 +--
 fs/cifs/inode.c      | 4 ++--
 4 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 3f4f1487f714..69d26313d350 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -65,7 +65,6 @@ struct cifs_sb_info {
 	unsigned int bsize;
 	unsigned int rsize;
 	unsigned int wsize;
-	unsigned long actimeo; /* attribute cache timeout (jiffies) */
 	atomic_t active;
 	unsigned int mnt_cifs_flags;
 	struct delayed_work prune_tlinks;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 4ea8c3c3bce1..e432de7c6ca1 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -629,7 +629,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
 	if (tcon->handle_timeout)
 		seq_printf(s, ",handletimeout=%u", tcon->handle_timeout);
 	/* convert actimeo and display it in seconds */
-	seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
+	seq_printf(s, ",actimeo=%lu", cifs_sb->ctx->actimeo / HZ);
 
 	if (tcon->ses->chan_max > 1)
 		seq_printf(s, ",multichannel,max_channels=%zu",
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 96c5b66d4b44..47e2fe8c19a2 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2236,7 +2236,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->actimeo != new->actimeo)
+	if (old->ctx->actimeo != new->ctx->actimeo)
 		return 0;
 
 	return 1;
@@ -2682,7 +2682,6 @@ int cifs_setup_cifs_sb(struct smb3_fs_context *ctx,
 	cifs_dbg(FYI, "file mode: %04ho  dir mode: %04ho\n",
 		 cifs_sb->ctx->file_mode, cifs_sb->ctx->dir_mode);
 
-	cifs_sb->actimeo = ctx->actimeo;
 	cifs_sb->local_nls = ctx->local_nls;
 
 	if (ctx->nodfs)
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index e8a7110db2a6..fb07e0828958 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -2165,11 +2165,11 @@ cifs_inode_needs_reval(struct inode *inode)
 	if (!lookupCacheEnabled)
 		return true;
 
-	if (!cifs_sb->actimeo)
+	if (!cifs_sb->ctx->actimeo)
 		return true;
 
 	if (!time_in_range(jiffies, cifs_i->time,
-				cifs_i->time + cifs_sb->actimeo))
+				cifs_i->time + cifs_sb->ctx->actimeo))
 		return true;
 
 	/* hardlinked files w/ noserverino get "special" treatment */
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 11/21] cifs: move cifs_cleanup_volume_info[_content] to fs_context.c
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
                   ` (8 preceding siblings ...)
  2020-12-07 23:36 ` [PATCH 10/21] cifs: remove actimeo " Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 12/21] cifs: move [brw]size from cifs_sb to cifs_sb->ctx Ronnie Sahlberg
                   ` (9 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

and rename it to smb3_cleanup_fs_context[_content]

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/cifsfs.c     |  2 +-
 fs/cifs/cifsproto.h  |  3 ---
 fs/cifs/connect.c    | 47 ++++-------------------------------------------
 fs/cifs/dfs_cache.c  |  4 ++--
 fs/cifs/fs_context.c | 45 ++++++++++++++++++++++++++++++++++++++++++---
 fs/cifs/fs_context.h |  2 ++
 6 files changed, 51 insertions(+), 52 deletions(-)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index e432de7c6ca1..0288632233f6 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -866,7 +866,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
 out:
 	if (cifs_sb) {
 		kfree(cifs_sb->prepath);
-		cifs_cleanup_volume_info(cifs_sb->ctx);
+		smb3_cleanup_fs_context(cifs_sb->ctx);
 		kfree(cifs_sb);
 	}
 	return root;
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 19ee76f3a96f..b04f7270e04a 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -237,7 +237,6 @@ extern int cifs_read_page_from_socket(struct TCP_Server_Info *server,
 extern int cifs_setup_cifs_sb(struct smb3_fs_context *ctx,
 			       struct cifs_sb_info *cifs_sb);
 extern int cifs_match_super(struct super_block *, void *);
-extern void cifs_cleanup_volume_info(struct smb3_fs_context *ctx);
 extern int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx);
 extern void cifs_umount(struct cifs_sb_info *);
 extern void cifs_mark_open_files_invalid(struct cifs_tcon *tcon);
@@ -552,8 +551,6 @@ extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8,
 
 extern int
 cifs_setup_volume_info(struct smb3_fs_context *ctx);
-extern void
-cifs_cleanup_volume_info_contents(struct smb3_fs_context *ctx);
 
 extern struct TCP_Server_Info *
 cifs_find_tcp_session(struct smb3_fs_context *ctx);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 47e2fe8c19a2..054cb09b8087 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2777,45 +2777,6 @@ int cifs_setup_cifs_sb(struct smb3_fs_context *ctx,
 	return 0;
 }
 
-void
-cifs_cleanup_volume_info_contents(struct smb3_fs_context *ctx)
-{
-	if (ctx == NULL)
-		return;
-
-	/*
-	 * Make sure this stays in sync with smb3_fs_context_dup()
-	 */
-	kfree(ctx->mount_options);
-	ctx->mount_options = NULL;
-	kfree(ctx->username);
-	ctx->username = NULL;
-	kfree_sensitive(ctx->password);
-	ctx->password = NULL;
-	kfree(ctx->UNC);
-	ctx->UNC = NULL;
-	kfree(ctx->domainname);
-	ctx->domainname = NULL;
-	kfree(ctx->nodename);
-	ctx->nodename = NULL;
-	kfree(ctx->iocharset);
-	ctx->iocharset = NULL;
-	kfree(ctx->prepath);
-	ctx->prepath = NULL;
-
-	unload_nls(ctx->local_nls);
-	ctx->local_nls = NULL;
-}
-
-void
-cifs_cleanup_volume_info(struct smb3_fs_context *ctx)
-{
-	if (!ctx)
-		return;
-	cifs_cleanup_volume_info_contents(ctx);
-	kfree(ctx);
-}
-
 /* Release all succeed connections */
 static inline void mount_put_conns(struct cifs_sb_info *cifs_sb,
 				   unsigned int xid,
@@ -3027,7 +2988,7 @@ expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
 			rc = PTR_ERR(mdata);
 			mdata = NULL;
 		} else {
-			cifs_cleanup_volume_info_contents(ctx);
+			smb3_cleanup_fs_context_contents(ctx);
 			rc = cifs_setup_volume_info(ctx);
 		}
 		kfree(cifs_sb->ctx->mount_options);
@@ -3119,7 +3080,7 @@ static int setup_dfs_tgt_conn(const char *path, const char *full_path,
 			rc = update_vol_info(tgt_it, &fake_ctx, ctx);
 		}
 	}
-	cifs_cleanup_volume_info_contents(&fake_ctx);
+	smb3_cleanup_fs_context_contents(&fake_ctx);
 	return rc;
 }
 
@@ -3366,7 +3327,7 @@ static int check_dfs_prepath(struct cifs_sb_info *cifs_sb, struct smb3_fs_contex
 					break;
 				rc = -EREMOTE;
 				npath = build_unc_path_to_root(&v, cifs_sb, true);
-				cifs_cleanup_volume_info_contents(&v);
+				smb3_cleanup_fs_context_contents(&v);
 			} else {
 				v.UNC = ctx->UNC;
 				v.prepath = path + 1;
@@ -3729,7 +3690,7 @@ static void delayed_free(struct rcu_head *p)
 {
 	struct cifs_sb_info *cifs_sb = container_of(p, struct cifs_sb_info, rcu);
 	unload_nls(cifs_sb->local_nls);
-	cifs_cleanup_volume_info(cifs_sb->ctx);
+	smb3_cleanup_fs_context(cifs_sb->ctx);
 	kfree(cifs_sb);
 }
 
diff --git a/fs/cifs/dfs_cache.c b/fs/cifs/dfs_cache.c
index 6bccff4596bf..6ad6ba5f6ebe 100644
--- a/fs/cifs/dfs_cache.c
+++ b/fs/cifs/dfs_cache.c
@@ -587,7 +587,7 @@ static void __vol_release(struct vol_info *vi)
 {
 	kfree(vi->fullpath);
 	kfree(vi->mntdata);
-	cifs_cleanup_volume_info_contents(&vi->ctx);
+	smb3_cleanup_fs_context_contents(&vi->ctx);
 	kfree(vi);
 }
 
@@ -1468,7 +1468,7 @@ static struct cifs_ses *find_root_ses(struct vol_info *vi,
 	ses = cifs_get_smb_ses(server, &ctx);
 
 out:
-	cifs_cleanup_volume_info_contents(&ctx);
+	smb3_cleanup_fs_context_contents(&ctx);
 	kfree(mdata);
 	kfree(rpath);
 
diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
index 1e69fdbe76d8..8b74b87d7af7 100644
--- a/fs/cifs/fs_context.c
+++ b/fs/cifs/fs_context.c
@@ -288,7 +288,7 @@ do {									\
 	if (ctx->field) {						\
 		new_ctx->field = kstrdup(ctx->field, GFP_ATOMIC);	\
 		if (new_ctx->field == NULL) {				\
-			cifs_cleanup_volume_info_contents(new_ctx);	\
+			smb3_cleanup_fs_context_contents(new_ctx);	\
 			return -ENOMEM;					\
 		}							\
 	}								\
@@ -311,7 +311,7 @@ smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx
 	new_ctx->iocharset = NULL;
 
 	/*
-	 * Make sure to stay in sync with cifs_cleanup_volume_info_contents()
+	 * Make sure to stay in sync with smb3_cleanup_fs_context_contents()
 	 */
 	DUP_CTX_STR(prepath);
 	DUP_CTX_STR(mount_options);
@@ -615,7 +615,7 @@ static void smb3_fs_context_free(struct fs_context *fc)
 {
 	struct smb3_fs_context *ctx = smb3_fc2context(fc);
 
-	cifs_cleanup_volume_info(ctx);		
+	smb3_cleanup_fs_context(ctx);
 }
 
 static int smb3_reconfigure(struct fs_context *fc)
@@ -1231,3 +1231,42 @@ int smb3_init_fs_context(struct fs_context *fc)
 	fc->ops = &smb3_fs_context_ops;
 	return 0;
 }
+
+void
+smb3_cleanup_fs_context_contents(struct smb3_fs_context *ctx)
+{
+	if (ctx == NULL)
+		return;
+
+	/*
+	 * Make sure this stays in sync with smb3_fs_context_dup()
+	 */
+	kfree(ctx->mount_options);
+	ctx->mount_options = NULL;
+	kfree(ctx->username);
+	ctx->username = NULL;
+	kfree_sensitive(ctx->password);
+	ctx->password = NULL;
+	kfree(ctx->UNC);
+	ctx->UNC = NULL;
+	kfree(ctx->domainname);
+	ctx->domainname = NULL;
+	kfree(ctx->nodename);
+	ctx->nodename = NULL;
+	kfree(ctx->iocharset);
+	ctx->iocharset = NULL;
+	kfree(ctx->prepath);
+	ctx->prepath = NULL;
+
+	unload_nls(ctx->local_nls);
+	ctx->local_nls = NULL;
+}
+
+void
+smb3_cleanup_fs_context(struct smb3_fs_context *ctx)
+{
+	if (!ctx)
+		return;
+	smb3_cleanup_fs_context_contents(ctx);
+	kfree(ctx);
+}
diff --git a/fs/cifs/fs_context.h b/fs/cifs/fs_context.h
index 6e98ef526895..bb3fdce6d7f2 100644
--- a/fs/cifs/fs_context.h
+++ b/fs/cifs/fs_context.h
@@ -252,6 +252,8 @@ extern int cifs_parse_cache_flavor(char *value,
 extern int cifs_parse_security_flavors(char *value,
 				       struct smb3_fs_context *ctx);
 extern int smb3_init_fs_context(struct fs_context *fc);
+extern void smb3_cleanup_fs_context_contents(struct smb3_fs_context *ctx);
+extern void smb3_cleanup_fs_context(struct smb3_fs_context *ctx);
 
 static inline struct smb3_fs_context *smb3_fc2context(const struct fs_context *fc \
 						    )
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 12/21] cifs: move [brw]size from cifs_sb to cifs_sb->ctx
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
                   ` (9 preceding siblings ...)
  2020-12-07 23:36 ` [PATCH 11/21] cifs: move cifs_cleanup_volume_info[_content] to fs_context.c Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 13/21] cifs: add initial reconfigure support Ronnie Sahlberg
                   ` (8 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/cifs_fs_sb.h |  3 ---
 fs/cifs/cifsfs.c     | 11 +++++++----
 fs/cifs/connect.c    | 21 +++++++++------------
 fs/cifs/file.c       | 12 ++++++------
 fs/cifs/fs_context.c |  3 +++
 fs/cifs/fs_context.h |  3 +++
 fs/cifs/inode.c      |  2 +-
 fs/cifs/smb1ops.c    |  2 +-
 fs/cifs/smb2ops.c    |  2 +-
 9 files changed, 31 insertions(+), 28 deletions(-)

diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 69d26313d350..aa77edc12212 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -62,9 +62,6 @@ struct cifs_sb_info {
 	struct tcon_link *master_tlink;
 	struct nls_table *local_nls;
 	struct smb3_fs_context *ctx;
-	unsigned int bsize;
-	unsigned int rsize;
-	unsigned int wsize;
 	atomic_t active;
 	unsigned int mnt_cifs_flags;
 	struct delayed_work prune_tlinks;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 0288632233f6..80117e9d35f9 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -215,7 +215,7 @@ cifs_read_super(struct super_block *sb)
 	if (rc)
 		goto out_no_root;
 	/* tune readahead according to rsize */
-	sb->s_bdi->ra_pages = cifs_sb->rsize / PAGE_SIZE;
+	sb->s_bdi->ra_pages = cifs_sb->ctx->rsize / PAGE_SIZE;
 
 	sb->s_blocksize = CIFS_MAX_MSGSIZE;
 	sb->s_blocksize_bits = 14;	/* default 2**14 = CIFS_MAX_MSGSIZE */
@@ -612,9 +612,12 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
 			   from_kgid_munged(&init_user_ns,
 					    cifs_sb->ctx->backupgid));
 
-	seq_printf(s, ",rsize=%u", cifs_sb->rsize);
-	seq_printf(s, ",wsize=%u", cifs_sb->wsize);
-	seq_printf(s, ",bsize=%u", cifs_sb->bsize);
+	if (cifs_sb->ctx->got_rsize)
+		seq_printf(s, ",rsize=%u", cifs_sb->ctx->rsize);
+	if (cifs_sb->ctx->got_wsize)
+		seq_printf(s, ",wsize=%u", cifs_sb->ctx->wsize);
+	if (cifs_sb->ctx->got_bsize)
+		seq_printf(s, ",bsize=%u", cifs_sb->ctx->bsize);
 	if (tcon->ses->server->min_offload)
 		seq_printf(s, ",esize=%u", tcon->ses->server->min_offload);
 	seq_printf(s, ",echo_interval=%lu",
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 054cb09b8087..f28067696a2c 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2219,10 +2219,10 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
 	 * We want to share sb only if we don't specify an r/wsize or
 	 * specified r/wsize is greater than or equal to existing one.
 	 */
-	if (new->wsize && new->wsize < old->wsize)
+	if (new->ctx->wsize && new->ctx->wsize < old->ctx->wsize)
 		return 0;
 
-	if (new->rsize && new->rsize < old->rsize)
+	if (new->ctx->rsize && new->ctx->rsize < old->ctx->rsize)
 		return 0;
 
 	if (!uid_eq(old->ctx->linux_uid, new->ctx->linux_uid) ||
@@ -2671,14 +2671,6 @@ int cifs_setup_cifs_sb(struct smb3_fs_context *ctx,
 	spin_lock_init(&cifs_sb->tlink_tree_lock);
 	cifs_sb->tlink_tree = RB_ROOT;
 
-	cifs_sb->bsize = ctx->bsize;
-	/*
-	 * Temporarily set r/wsize for matching superblock. If we end up using
-	 * new sb then client will later negotiate it downward if needed.
-	 */
-	cifs_sb->rsize = ctx->rsize;
-	cifs_sb->wsize = ctx->wsize;
-
 	cifs_dbg(FYI, "file mode: %04ho  dir mode: %04ho\n",
 		 cifs_sb->ctx->file_mode, cifs_sb->ctx->dir_mode);
 
@@ -2882,8 +2874,13 @@ static int mount_get_conns(struct smb3_fs_context *ctx, struct cifs_sb_info *cif
 		}
 	}
 
-	cifs_sb->wsize = server->ops->negotiate_wsize(tcon, ctx);
-	cifs_sb->rsize = server->ops->negotiate_rsize(tcon, ctx);
+	/*
+	 * Clamp the rsize/wsize mount arguments if they are too big for the server
+	 */
+	if (cifs_sb->ctx->wsize > server->ops->negotiate_wsize(tcon, ctx))
+		cifs_sb->ctx->wsize = server->ops->negotiate_wsize(tcon, ctx);
+	if (cifs_sb->ctx->rsize > server->ops->negotiate_rsize(tcon, ctx))
+		cifs_sb->ctx->rsize = server->ops->negotiate_rsize(tcon, ctx);
 
 	return 0;
 }
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 3ee510d3dab8..2bcbb142ffbd 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2331,7 +2331,7 @@ static int cifs_writepages(struct address_space *mapping,
 	 * If wsize is smaller than the page cache size, default to writing
 	 * one page at a time via cifs_writepage
 	 */
-	if (cifs_sb->wsize < PAGE_SIZE)
+	if (cifs_sb->ctx->wsize < PAGE_SIZE)
 		return generic_writepages(mapping, wbc);
 
 	xid = get_xid();
@@ -2364,7 +2364,7 @@ static int cifs_writepages(struct address_space *mapping,
 		if (rc)
 			get_file_rc = rc;
 
-		rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize,
+		rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->wsize,
 						   &wsize, credits);
 		if (rc != 0) {
 			done = true;
@@ -2906,7 +2906,7 @@ cifs_write_from_iter(loff_t offset, size_t len, struct iov_iter *from,
 				break;
 		}
 
-		rc = server->ops->wait_mtu_credits(server, cifs_sb->wsize,
+		rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->wsize,
 						   &wsize, credits);
 		if (rc)
 			break;
@@ -3637,7 +3637,7 @@ cifs_send_async_read(loff_t offset, size_t len, struct cifsFileInfo *open_file,
 				break;
 		}
 
-		rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize,
+		rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->rsize,
 						   &rsize, credits);
 		if (rc)
 			break;
@@ -4023,7 +4023,7 @@ cifs_read(struct file *file, char *read_data, size_t read_size, loff_t *offset)
 	cifs_sb = CIFS_FILE_SB(file);
 
 	/* FIXME: set up handlers for larger reads and/or convert to async */
-	rsize = min_t(unsigned int, cifs_sb->rsize, CIFSMaxBufSize);
+	rsize = min_t(unsigned int, cifs_sb->ctx->rsize, CIFSMaxBufSize);
 
 	if (file->private_data == NULL) {
 		rc = -EBADF;
@@ -4408,7 +4408,7 @@ static int cifs_readpages(struct file *file, struct address_space *mapping,
 				break;
 		}
 
-		rc = server->ops->wait_mtu_credits(server, cifs_sb->rsize,
+		rc = server->ops->wait_mtu_credits(server, cifs_sb->ctx->rsize,
 						   &rsize, credits);
 		if (rc)
 			break;
diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
index 8b74b87d7af7..752b7da43f4c 100644
--- a/fs/cifs/fs_context.c
+++ b/fs/cifs/fs_context.c
@@ -781,12 +781,15 @@ static int smb3_fs_context_parse_param(struct fs_context *fc,
 			goto cifs_parse_mount_err;
 		}
 		ctx->bsize = result.uint_32;
+		ctx->got_bsize = true;
 		break;
 	case Opt_rsize:
 		ctx->rsize = result.uint_32;
+		ctx->got_rsize = true;
 		break;
 	case Opt_wsize:
 		ctx->wsize = result.uint_32;
+		ctx->got_wsize = true;
 		break;
 	case Opt_actimeo:
 		ctx->actimeo = HZ * result.uint_32;
diff --git a/fs/cifs/fs_context.h b/fs/cifs/fs_context.h
index bb3fdce6d7f2..aa1d952fd5ce 100644
--- a/fs/cifs/fs_context.h
+++ b/fs/cifs/fs_context.h
@@ -151,6 +151,9 @@ struct smb3_fs_context {
 	char *nodename;
 	bool got_ip;
 	bool got_version;
+	bool got_rsize;
+	bool got_wsize;
+	bool got_bsize;
 	unsigned short port;
 
 	char *username;
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index fb07e0828958..7e07a0aaaade 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -2374,7 +2374,7 @@ int cifs_getattr(const struct path *path, struct kstat *stat,
 	}
 
 	generic_fillattr(inode, stat);
-	stat->blksize = cifs_sb->bsize;
+	stat->blksize = cifs_sb->ctx->bsize;
 	stat->ino = CIFS_I(inode)->uniqueid;
 
 	/* old CIFS Unix Extensions doesn't return create time */
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index 359a0ef796de..e31b939e628c 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -1006,7 +1006,7 @@ cifs_is_read_op(__u32 oplock)
 static unsigned int
 cifs_wp_retry_size(struct inode *inode)
 {
-	return CIFS_SB(inode->i_sb)->wsize;
+	return CIFS_SB(inode->i_sb)->ctx->wsize;
 }
 
 static bool
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index f60240bbaa81..7040805adfdc 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -3802,7 +3802,7 @@ smb3_parse_lease_buf(void *buf, unsigned int *epoch, char *lease_key)
 static unsigned int
 smb2_wp_retry_size(struct inode *inode)
 {
-	return min_t(unsigned int, CIFS_SB(inode->i_sb)->wsize,
+	return min_t(unsigned int, CIFS_SB(inode->i_sb)->ctx->wsize,
 		     SMB2_MAX_BUFFER_SIZE);
 }
 
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 13/21] cifs: add initial reconfigure support
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
                   ` (10 preceding siblings ...)
  2020-12-07 23:36 ` [PATCH 12/21] cifs: move [brw]size from cifs_sb to cifs_sb->ctx Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 14/21] cifs: we do not allow changing username/password/unc/... during remount Ronnie Sahlberg
                   ` (7 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/fs_context.c | 36 +++++++++++++++++++++++++++++++++---
 1 file changed, 33 insertions(+), 3 deletions(-)

diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
index 752b7da43f4c..edfdea129fcc 100644
--- a/fs/cifs/fs_context.c
+++ b/fs/cifs/fs_context.c
@@ -618,14 +618,44 @@ static void smb3_fs_context_free(struct fs_context *fc)
 	smb3_cleanup_fs_context(ctx);
 }
 
-static int smb3_reconfigure(struct fs_context *fc)
+/*
+ * Compare the old and new proposed context during reconfigure
+ * and check if the changes are compatible.
+ */
+static int smb3_verify_reconfigure_ctx(struct smb3_fs_context *new_ctx,
+				       struct smb3_fs_context *old_ctx)
 {
-	// TODO:  struct smb3_fs_context *ctx = smb3_fc2context(fc);
+	if (new_ctx->sectype != old_ctx->sectype) {
+		cifs_dbg(VFS, "can not change sec during remount\n");
+		return -EINVAL;
+	}
 
-	/* FIXME : add actual reconfigure */
 	return 0;
 }
 
+static int smb3_reconfigure(struct fs_context *fc)
+{
+	struct smb3_fs_context *ctx = smb3_fc2context(fc);
+	struct dentry *root = fc->root;
+	struct cifs_sb_info *cifs_sb = CIFS_SB(root->d_sb);
+	int rc;
+
+	rc = smb3_verify_reconfigure_ctx(ctx, cifs_sb->ctx);
+	if (rc)
+		return rc;
+
+	/*
+	 * Steal the UNC from the old and to be destroyed context.
+	 */
+	ctx->UNC = cifs_sb->ctx->UNC;
+	cifs_sb->ctx->UNC = NULL;
+
+	smb3_cleanup_fs_context_contents(cifs_sb->ctx);
+	rc = smb3_fs_context_dup(cifs_sb->ctx, ctx);
+
+	return rc;
+}
+
 static int smb3_fs_context_parse_param(struct fs_context *fc,
 				      struct fs_parameter *param)
 {
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 14/21] cifs: we do not allow changing username/password/unc/... during remount
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
                   ` (11 preceding siblings ...)
  2020-12-07 23:36 ` [PATCH 13/21] cifs: add initial reconfigure support Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-08  5:06   ` Steve French
  2020-12-07 23:36 ` [PATCH 15/21] cifs: simplify handling of cifs_sb/ctx->local_nls Ronnie Sahlberg
                   ` (6 subsequent siblings)
  19 siblings, 1 reply; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/cifsfs.c     |  2 +-
 fs/cifs/fs_context.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++---
 fs/cifs/fs_context.h |  2 +-
 3 files changed, 54 insertions(+), 5 deletions(-)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 80117e9d35f9..13d7f4a3c836 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -490,7 +490,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
 
 	if (tcon->no_lease)
 		seq_puts(s, ",nolease");
-	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)
+	if (cifs_sb->ctx->multiuser)
 		seq_puts(s, ",multiuser");
 	else if (tcon->ses->user_name)
 		seq_show_option(s, "username", tcon->ses->user_name);
diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
index edfdea129fcc..542fa75b74aa 100644
--- a/fs/cifs/fs_context.c
+++ b/fs/cifs/fs_context.c
@@ -629,10 +629,53 @@ static int smb3_verify_reconfigure_ctx(struct smb3_fs_context *new_ctx,
 		cifs_dbg(VFS, "can not change sec during remount\n");
 		return -EINVAL;
 	}
+	if (new_ctx->multiuser != old_ctx->multiuser) {
+		cifs_dbg(VFS, "can not change multiuser during remount\n");
+		return -EINVAL;
+	}
+	if (new_ctx->UNC &&
+	    (!old_ctx->UNC || strcmp(new_ctx->UNC, old_ctx->UNC))) {
+		cifs_dbg(VFS, "can not change UNC during remount\n");
+		return -EINVAL;
+	}
+	if (new_ctx->username &&
+	    (!old_ctx->username || strcmp(new_ctx->username, old_ctx->username))) {
+		cifs_dbg(VFS, "can not change username during remount\n");
+		return -EINVAL;
+	}
+	if (new_ctx->password &&
+	    (!old_ctx->password || strcmp(new_ctx->password, old_ctx->password))) {
+		cifs_dbg(VFS, "can not change password during remount\n");
+		return -EINVAL;
+	}
+	if (new_ctx->domainname &&
+	    (!old_ctx->domainname || strcmp(new_ctx->domainname, old_ctx->domainname))) {
+		cifs_dbg(VFS, "can not change domainname during remount\n");
+		return -EINVAL;
+	}
+	if (new_ctx->nodename &&
+	    (!old_ctx->nodename || strcmp(new_ctx->nodename, old_ctx->nodename))) {
+		cifs_dbg(VFS, "can not change nodename during remount\n");
+		return -EINVAL;
+	}
+	if (new_ctx->iocharset &&
+	    (!old_ctx->iocharset || strcmp(new_ctx->iocharset, old_ctx->iocharset))) {
+		cifs_dbg(VFS, "can not change iocharset during remount\n");
+		return -EINVAL;
+	}
 
 	return 0;
 }
 
+#define STEAL_STRING(cifs_sb, ctx, field)				\
+do {									\
+	if (ctx->field) {						\
+		kfree(ctx->field);					\
+		ctx->field = cifs_sb->ctx->field;			\
+		cifs_sb->ctx->field = NULL;				\
+	}								\
+} while (0)
+
 static int smb3_reconfigure(struct fs_context *fc)
 {
 	struct smb3_fs_context *ctx = smb3_fc2context(fc);
@@ -645,10 +688,16 @@ static int smb3_reconfigure(struct fs_context *fc)
 		return rc;
 
 	/*
-	 * Steal the UNC from the old and to be destroyed context.
+	 * We can not change UNC/username/password/domainname/nodename/iocharset
+	 * during reconnect so ignore what we have in the new context and
+	 * just use what we already have in cifs_sb->ctx.
 	 */
-	ctx->UNC = cifs_sb->ctx->UNC;
-	cifs_sb->ctx->UNC = NULL;
+	STEAL_STRING(cifs_sb, ctx, UNC);
+	STEAL_STRING(cifs_sb, ctx, username);
+	STEAL_STRING(cifs_sb, ctx, password);
+	STEAL_STRING(cifs_sb, ctx, domainname);
+	STEAL_STRING(cifs_sb, ctx, nodename);
+	STEAL_STRING(cifs_sb, ctx, iocharset);
 
 	smb3_cleanup_fs_context_contents(cifs_sb->ctx);
 	rc = smb3_fs_context_dup(cifs_sb->ctx, ctx);
diff --git a/fs/cifs/fs_context.h b/fs/cifs/fs_context.h
index aa1d952fd5ce..62f5a8d98df6 100644
--- a/fs/cifs/fs_context.h
+++ b/fs/cifs/fs_context.h
@@ -148,7 +148,6 @@ struct smb3_fs_context {
 	bool uid_specified;
 	bool gid_specified;
 	bool sloppy;
-	char *nodename;
 	bool got_ip;
 	bool got_version;
 	bool got_rsize;
@@ -160,6 +159,7 @@ struct smb3_fs_context {
 	char *password;
 	char *domainname;
 	char *UNC;
+	char *nodename;
 	char *iocharset;  /* local code page for mapping to and from Unicode */
 	char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
 	char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 15/21] cifs: simplify handling of cifs_sb/ctx->local_nls
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
                   ` (12 preceding siblings ...)
  2020-12-07 23:36 ` [PATCH 14/21] cifs: we do not allow changing username/password/unc/... during remount Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 16/21] cifs: don't create a temp nls in cifs_setup_ipc Ronnie Sahlberg
                   ` (5 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

Only load/unload local_nls from cifs_sb and just make the ctx
contain a pointer to cifs_sb->ctx.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/cifsproto.h  |  4 +---
 fs/cifs/connect.c    | 29 ++++++++++++++---------------
 fs/cifs/fs_context.c |  4 ----
 fs/cifs/fs_context.h |  2 +-
 fs/cifs/sess.c       | 23 +++++++++++------------
 5 files changed, 27 insertions(+), 35 deletions(-)

diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index b04f7270e04a..2b5401e1ce20 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -598,9 +598,7 @@ extern void rqst_page_get_length(struct smb_rqst *rqst, unsigned int page,
 				unsigned int *len, unsigned int *offset);
 struct cifs_chan *
 cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server);
-int cifs_try_adding_channels(struct cifs_ses *ses);
-int cifs_ses_add_channel(struct cifs_ses *ses,
-				struct cifs_server_iface *iface);
+int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses);
 bool is_server_using_iface(struct TCP_Server_Info *server,
 			   struct cifs_server_iface *iface);
 bool is_ses_using_iface(struct cifs_ses *ses, struct cifs_server_iface *iface);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index f28067696a2c..f2698090b39a 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2674,7 +2674,19 @@ int cifs_setup_cifs_sb(struct smb3_fs_context *ctx,
 	cifs_dbg(FYI, "file mode: %04ho  dir mode: %04ho\n",
 		 cifs_sb->ctx->file_mode, cifs_sb->ctx->dir_mode);
 
-	cifs_sb->local_nls = ctx->local_nls;
+	/* this is needed for ASCII cp to Unicode converts */
+	if (ctx->iocharset == NULL) {
+		/* load_nls_default cannot return null */
+		cifs_sb->local_nls = load_nls_default();
+	} else {
+		cifs_sb->local_nls = load_nls(ctx->iocharset);
+		if (cifs_sb->local_nls == NULL) {
+			cifs_dbg(VFS, "CIFS mount error: iocharset %s not found\n",
+				 ctx->iocharset);
+			return -ELIBACC;
+		}
+	}
+	ctx->local_nls = cifs_sb->local_nls;
 
 	if (ctx->nodfs)
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_DFS;
@@ -3145,19 +3157,6 @@ cifs_setup_volume_info(struct smb3_fs_context *ctx)
 		return -EINVAL;
 	}
 
-	/* this is needed for ASCII cp to Unicode converts */
-	if (ctx->iocharset == NULL) {
-		/* load_nls_default cannot return null */
-		ctx->local_nls = load_nls_default();
-	} else {
-		ctx->local_nls = load_nls(ctx->iocharset);
-		if (ctx->local_nls == NULL) {
-			cifs_dbg(VFS, "CIFS mount error: iocharset %s not found\n",
-				 ctx->iocharset);
-			return -ELIBACC;
-		}
-	}
-
 	return rc;
 }
 
@@ -3478,7 +3477,7 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
 
 out:
 	free_xid(xid);
-	cifs_try_adding_channels(ses);
+	cifs_try_adding_channels(cifs_sb, ses);
 	return mount_setup_tlink(cifs_sb, ses, tcon);
 
 error:
diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
index 542fa75b74aa..00bb11939837 100644
--- a/fs/cifs/fs_context.c
+++ b/fs/cifs/fs_context.c
@@ -302,7 +302,6 @@ smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx
 	memcpy(new_ctx, ctx, sizeof(*ctx));
 	new_ctx->prepath = NULL;
 	new_ctx->mount_options = NULL;
-	new_ctx->local_nls = NULL;
 	new_ctx->nodename = NULL;
 	new_ctx->username = NULL;
 	new_ctx->password = NULL;
@@ -1339,9 +1338,6 @@ smb3_cleanup_fs_context_contents(struct smb3_fs_context *ctx)
 	ctx->iocharset = NULL;
 	kfree(ctx->prepath);
 	ctx->prepath = NULL;
-
-	unload_nls(ctx->local_nls);
-	ctx->local_nls = NULL;
 }
 
 void
diff --git a/fs/cifs/fs_context.h b/fs/cifs/fs_context.h
index 62f5a8d98df6..c2aadf3ad091 100644
--- a/fs/cifs/fs_context.h
+++ b/fs/cifs/fs_context.h
@@ -236,7 +236,7 @@ struct smb3_fs_context {
 	char *prepath;
 	struct sockaddr_storage dstaddr; /* destination address */
 	struct sockaddr_storage srcaddr; /* allow binding to a local IP */
-	struct nls_table *local_nls;
+	struct nls_table *local_nls; /* This is a copy of the pointer in cifs_sb */
 	unsigned int echo_interval; /* echo interval in secs */
 	__u64 snapshot_time; /* needed for timewarp tokens */
 	__u32 handle_timeout; /* persistent and durable handle timeout in ms */
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c
index b0e4bf2cd473..98feccdb1599 100644
--- a/fs/cifs/sess.c
+++ b/fs/cifs/sess.c
@@ -34,6 +34,10 @@
 #include "smb2proto.h"
 #include "fs_context.h"
 
+static int
+cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
+		     struct cifs_server_iface *iface);
+
 bool
 is_server_using_iface(struct TCP_Server_Info *server,
 		      struct cifs_server_iface *iface)
@@ -71,7 +75,7 @@ bool is_ses_using_iface(struct cifs_ses *ses, struct cifs_server_iface *iface)
 }
 
 /* returns number of channels added */
-int cifs_try_adding_channels(struct cifs_ses *ses)
+int cifs_try_adding_channels(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses)
 {
 	int old_chan_count = ses->chan_count;
 	int left = ses->chan_max - ses->chan_count;
@@ -134,7 +138,7 @@ int cifs_try_adding_channels(struct cifs_ses *ses)
 			continue;
 		}
 
-		rc = cifs_ses_add_channel(ses, iface);
+		rc = cifs_ses_add_channel(cifs_sb, ses, iface);
 		if (rc) {
 			cifs_dbg(FYI, "failed to open extra channel on iface#%d rc=%d\n",
 				 i, rc);
@@ -167,8 +171,9 @@ cifs_ses_find_chan(struct cifs_ses *ses, struct TCP_Server_Info *server)
 	return NULL;
 }
 
-int
-cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface)
+static int
+cifs_ses_add_channel(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
+		     struct cifs_server_iface *iface)
 {
 	struct cifs_chan *chan;
 	struct smb3_fs_context ctx = {NULL};
@@ -229,13 +234,8 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface)
 	/*
 	 * This will be used for encoding/decoding user/domain/pw
 	 * during sess setup auth.
-	 *
-	 * XXX: We use the default for simplicity but the proper way
-	 * would be to use the one that ses used, which is not
-	 * stored. This might break when dealing with non-ascii
-	 * strings.
 	 */
-	ctx.local_nls = load_nls_default();
+	ctx.local_nls = cifs_sb->local_nls;
 
 	/* Use RDMA if possible */
 	ctx.rdma = iface->rdma_capable;
@@ -275,7 +275,7 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface)
 	if (rc)
 		goto out;
 
-	rc = cifs_setup_session(xid, ses, ctx.local_nls);
+	rc = cifs_setup_session(xid, ses, cifs_sb->local_nls);
 	if (rc)
 		goto out;
 
@@ -298,7 +298,6 @@ cifs_ses_add_channel(struct cifs_ses *ses, struct cifs_server_iface *iface)
 
 	if (rc && chan->server)
 		cifs_put_tcp_session(chan->server, 0);
-	unload_nls(ctx.local_nls);
 
 	return rc;
 }
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 16/21] cifs: don't create a temp nls in cifs_setup_ipc
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
                   ` (13 preceding siblings ...)
  2020-12-07 23:36 ` [PATCH 15/21] cifs: simplify handling of cifs_sb/ctx->local_nls Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 17/21] cifs: uncomplicate printing the iocharset parameter Ronnie Sahlberg
                   ` (4 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

just use the one that is already available in ctx

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/connect.c | 7 +------
 1 file changed, 1 insertion(+), 6 deletions(-)

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index f2698090b39a..22b5f3544947 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -1493,7 +1493,6 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx)
 {
 	int rc = 0, xid;
 	struct cifs_tcon *tcon;
-	struct nls_table *nls_codepage;
 	char unc[SERVER_NAME_LENGTH + sizeof("//x/IPC$")] = {0};
 	bool seal = false;
 	struct TCP_Server_Info *server = ses->server;
@@ -1518,14 +1517,11 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx)
 
 	scnprintf(unc, sizeof(unc), "\\\\%s\\IPC$", server->hostname);
 
-	/* cannot fail */
-	nls_codepage = load_nls_default();
-
 	xid = get_xid();
 	tcon->ses = ses;
 	tcon->ipc = true;
 	tcon->seal = seal;
-	rc = server->ops->tree_connect(xid, ses, unc, tcon, nls_codepage);
+	rc = server->ops->tree_connect(xid, ses, unc, tcon, ctx->local_nls);
 	free_xid(xid);
 
 	if (rc) {
@@ -1538,7 +1534,6 @@ cifs_setup_ipc(struct cifs_ses *ses, struct smb3_fs_context *ctx)
 
 	ses->tcon_ipc = tcon;
 out:
-	unload_nls(nls_codepage);
 	return rc;
 }
 
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 17/21] cifs: uncomplicate printing the iocharset parameter
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
                   ` (14 preceding siblings ...)
  2020-12-07 23:36 ` [PATCH 16/21] cifs: don't create a temp nls in cifs_setup_ipc Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 18/21] cifs: do not allow changing posix_paths during remount Ronnie Sahlberg
                   ` (3 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

There is no need to load the default nls to check if the iocharset argument
was specified or not since we have it in cifs_sb->ctx

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/cifsfs.c | 17 ++---------------
 1 file changed, 2 insertions(+), 15 deletions(-)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 13d7f4a3c836..57c61a2bcf73 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -459,18 +459,6 @@ cifs_show_cache_flavor(struct seq_file *s, struct cifs_sb_info *cifs_sb)
 		seq_puts(s, "loose");
 }
 
-static void
-cifs_show_nls(struct seq_file *s, struct nls_table *cur)
-{
-	struct nls_table *def;
-
-	/* Display iocharset= option if it's not default charset */
-	def = load_nls_default();
-	if (def != cur)
-		seq_printf(s, ",iocharset=%s", cur->charset);
-	unload_nls(def);
-}
-
 /*
  * cifs_show_options() is for displaying mount options in /proc/mounts.
  * Not all settable options are displayed but most of the important
@@ -534,9 +522,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
 		seq_printf(s, ",file_mode=0%ho,dir_mode=0%ho",
 					   cifs_sb->ctx->file_mode,
 					   cifs_sb->ctx->dir_mode);
-
-	cifs_show_nls(s, cifs_sb->local_nls);
-
+	if (cifs_sb->ctx->iocharset)
+		seq_printf(s, ",iocharset=%s", cifs_sb->ctx->iocharset);
 	if (tcon->seal)
 		seq_puts(s, ",seal");
 	else if (tcon->ses->server->ignore_signature)
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 18/21] cifs: do not allow changing posix_paths during remount
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
                   ` (15 preceding siblings ...)
  2020-12-07 23:36 ` [PATCH 17/21] cifs: uncomplicate printing the iocharset parameter Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 19/21] cifs: remove ctx argument from cifs_setup_cifs_sb Ronnie Sahlberg
                   ` (2 subsequent siblings)
  19 siblings, 0 replies; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/fs_context.c | 4 ++++
 1 file changed, 4 insertions(+)

diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
index 00bb11939837..ee9c1fb666c7 100644
--- a/fs/cifs/fs_context.c
+++ b/fs/cifs/fs_context.c
@@ -624,6 +624,10 @@ static void smb3_fs_context_free(struct fs_context *fc)
 static int smb3_verify_reconfigure_ctx(struct smb3_fs_context *new_ctx,
 				       struct smb3_fs_context *old_ctx)
 {
+	if (new_ctx->posix_paths != old_ctx->posix_paths) {
+		cifs_dbg(VFS, "can not change posixpaths during remount\n");
+		return -EINVAL;
+	}
 	if (new_ctx->sectype != old_ctx->sectype) {
 		cifs_dbg(VFS, "can not change sec during remount\n");
 		return -EINVAL;
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 19/21] cifs: remove ctx argument from cifs_setup_cifs_sb
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
                   ` (16 preceding siblings ...)
  2020-12-07 23:36 ` [PATCH 18/21] cifs: do not allow changing posix_paths during remount Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 20/21] cifs: move update of flags into a separate function Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 21/21] cifs: update mnt_cifs_flags during reconfigure Ronnie Sahlberg
  19 siblings, 0 replies; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/cifsfs.c    | 2 +-
 fs/cifs/cifsproto.h | 3 +--
 fs/cifs/connect.c   | 7 ++++---
 3 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index 57c61a2bcf73..e98233a16974 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -802,7 +802,7 @@ cifs_smb3_do_mount(struct file_system_type *fs_type,
 		goto out;
 	}
 
-	rc = cifs_setup_cifs_sb(cifs_sb->ctx, cifs_sb);
+	rc = cifs_setup_cifs_sb(cifs_sb);
 	if (rc) {
 		root = ERR_PTR(rc);
 		goto out;
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 2b5401e1ce20..8e3db6d7112e 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -234,8 +234,7 @@ extern int cifs_read_page_from_socket(struct TCP_Server_Info *server,
 					struct page *page,
 					unsigned int page_offset,
 					unsigned int to_read);
-extern int cifs_setup_cifs_sb(struct smb3_fs_context *ctx,
-			       struct cifs_sb_info *cifs_sb);
+extern int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb);
 extern int cifs_match_super(struct super_block *, void *);
 extern int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx);
 extern void cifs_umount(struct cifs_sb_info *);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 22b5f3544947..3775f049e3ba 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2658,16 +2658,17 @@ void reset_cifs_unix_caps(unsigned int xid, struct cifs_tcon *tcon,
 	}
 }
 
-int cifs_setup_cifs_sb(struct smb3_fs_context *ctx,
-			struct cifs_sb_info *cifs_sb)
+int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb)
 {
+	struct smb3_fs_context *ctx = cifs_sb->ctx;
+
 	INIT_DELAYED_WORK(&cifs_sb->prune_tlinks, cifs_prune_tlinks);
 
 	spin_lock_init(&cifs_sb->tlink_tree_lock);
 	cifs_sb->tlink_tree = RB_ROOT;
 
 	cifs_dbg(FYI, "file mode: %04ho  dir mode: %04ho\n",
-		 cifs_sb->ctx->file_mode, cifs_sb->ctx->dir_mode);
+		 ctx->file_mode, ctx->dir_mode);
 
 	/* this is needed for ASCII cp to Unicode converts */
 	if (ctx->iocharset == NULL) {
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 20/21] cifs: move update of flags into a separate function
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
                   ` (17 preceding siblings ...)
  2020-12-07 23:36 ` [PATCH 19/21] cifs: remove ctx argument from cifs_setup_cifs_sb Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  2020-12-07 23:36 ` [PATCH 21/21] cifs: update mnt_cifs_flags during reconfigure Ronnie Sahlberg
  19 siblings, 0 replies; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

This funciton will set/clear flags that can be changed during mount or remount

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/connect.c    |  74 +-----------------------
 fs/cifs/fs_context.c | 155 +++++++++++++++++++++++++++++++++++++++++++++++++++
 fs/cifs/fs_context.h |   1 +
 3 files changed, 159 insertions(+), 71 deletions(-)

diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 3775f049e3ba..d5798bb8028a 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2684,61 +2684,10 @@ int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb)
 	}
 	ctx->local_nls = cifs_sb->local_nls;
 
-	if (ctx->nodfs)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_DFS;
-	if (ctx->noperm)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
-	if (ctx->setuids)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
-	if (ctx->setuidfromacl)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UID_FROM_ACL;
-	if (ctx->server_ino)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
-	if (ctx->remap)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SFM_CHR;
-	if (ctx->sfu_remap)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
-	if (ctx->no_xattr)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
-	if (ctx->sfu_emul)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
-	if (ctx->nobrl)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
-	if (ctx->nohandlecache)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_HANDLE_CACHE;
-	if (ctx->nostrictsync)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
-	if (ctx->mand_lock)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
-	if (ctx->rwpidforward)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
-	if (ctx->mode_ace)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MODE_FROM_SID;
-	if (ctx->cifs_acl)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
-	if (ctx->backupuid_specified) {
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID;
-	}
-	if (ctx->backupgid_specified) {
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID;
-	}
-	if (ctx->override_uid)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
-	if (ctx->override_gid)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
-	if (ctx->dynperm)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
-	if (ctx->fsc)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
-	if (ctx->multiuser)
-		cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER |
-					    CIFS_MOUNT_NO_PERM);
-	if (ctx->strict_io)
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO;
-	if (ctx->direct_io) {
+	smb3_update_mnt_flags(cifs_sb);
+
+	if (ctx->direct_io)
 		cifs_dbg(FYI, "mounting share using direct i/o\n");
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
-	}
 	if (ctx->cache_ro) {
 		cifs_dbg(VFS, "mounting share with read only caching. Ensure that the share will not be modified while in use.\n");
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RO_CACHE;
@@ -2747,23 +2696,6 @@ int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb)
 		cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_RO_CACHE |
 					    CIFS_MOUNT_RW_CACHE);
 	}
-	if (ctx->mfsymlinks) {
-		if (ctx->sfu_emul) {
-			/*
-			 * Our SFU ("Services for Unix" emulation does not allow
-			 * creating symlinks but does allow reading existing SFU
-			 * symlinks (it does allow both creating and reading SFU
-			 * style mknod and FIFOs though). When "mfsymlinks" and
-			 * "sfu" are both enabled at the same time, it allows
-			 * reading both types of symlinks, but will only create
-			 * them with mfsymlinks format. This allows better
-			 * Apple compatibility (probably better for Samba too)
-			 * while still recognizing old Windows style symlinks.
-			 */
-			cifs_dbg(VFS, "mount options mfsymlinks and sfu both enabled\n");
-		}
-		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
-	}
 
 	if ((ctx->cifs_acl) && (ctx->dynperm))
 		cifs_dbg(VFS, "mount option dynperm ignored if cifsacl mount option supported\n");
diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
index ee9c1fb666c7..bf5a25b930d5 100644
--- a/fs/cifs/fs_context.c
+++ b/fs/cifs/fs_context.c
@@ -1352,3 +1352,158 @@ smb3_cleanup_fs_context(struct smb3_fs_context *ctx)
 	smb3_cleanup_fs_context_contents(ctx);
 	kfree(ctx);
 }
+
+void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb)
+{
+	struct smb3_fs_context *ctx = cifs_sb->ctx;
+
+	if (ctx->nodfs)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_DFS;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_DFS;
+
+	if (ctx->noperm)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_PERM;
+
+	if (ctx->setuids)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SET_UID;
+
+	if (ctx->setuidfromacl)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UID_FROM_ACL;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_UID_FROM_ACL;
+
+	if (ctx->server_ino)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_SERVER_INUM;
+
+	if (ctx->remap)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SFM_CHR;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MAP_SFM_CHR;
+
+	if (ctx->sfu_remap)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MAP_SPECIAL_CHR;
+
+	if (ctx->no_xattr)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_XATTR;
+
+	if (ctx->sfu_emul)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_UNX_EMUL;
+
+	if (ctx->nobrl)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_BRL;
+
+	if (ctx->nohandlecache)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_HANDLE_CACHE;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NO_HANDLE_CACHE;
+
+	if (ctx->nostrictsync)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NOSSYNC;
+
+	if (ctx->mand_lock)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_NOPOSIXBRL;
+
+	if (ctx->rwpidforward)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_RWPIDFORWARD;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_RWPIDFORWARD;
+
+	if (ctx->mode_ace)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MODE_FROM_SID;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MODE_FROM_SID;
+
+	if (ctx->cifs_acl)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_CIFS_ACL;
+
+	if (ctx->backupuid_specified)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_CIFS_BACKUPUID;
+
+	if (ctx->backupgid_specified)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_CIFS_BACKUPGID;
+
+	if (ctx->override_uid)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_OVERR_UID;
+
+	if (ctx->override_gid)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_OVERR_GID;
+
+	if (ctx->dynperm)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_DYNPERM;
+
+	if (ctx->fsc)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_FSCACHE;
+
+	if (ctx->multiuser)
+		cifs_sb->mnt_cifs_flags |= (CIFS_MOUNT_MULTIUSER |
+					    CIFS_MOUNT_NO_PERM);
+	else
+		cifs_sb->mnt_cifs_flags &= ~(CIFS_MOUNT_MULTIUSER |
+					     CIFS_MOUNT_NO_PERM);
+
+	if (ctx->strict_io)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_STRICT_IO;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_STRICT_IO;
+
+	if (ctx->direct_io)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_DIRECT_IO;
+
+	if (ctx->mfsymlinks)
+		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
+	else
+		cifs_sb->mnt_cifs_flags &= ~CIFS_MOUNT_MF_SYMLINKS;
+	if (ctx->mfsymlinks) {
+		if (ctx->sfu_emul) {
+			/*
+			 * Our SFU ("Services for Unix" emulation does not allow
+			 * creating symlinks but does allow reading existing SFU
+			 * symlinks (it does allow both creating and reading SFU
+			 * style mknod and FIFOs though). When "mfsymlinks" and
+			 * "sfu" are both enabled at the same time, it allows
+			 * reading both types of symlinks, but will only create
+			 * them with mfsymlinks format. This allows better
+			 * Apple compatibility (probably better for Samba too)
+			 * while still recognizing old Windows style symlinks.
+			 */
+			cifs_dbg(VFS, "mount options mfsymlinks and sfu both enabled\n");
+		}
+	}
+
+	return;
+}
diff --git a/fs/cifs/fs_context.h b/fs/cifs/fs_context.h
index c2aadf3ad091..efc7ac2783fa 100644
--- a/fs/cifs/fs_context.h
+++ b/fs/cifs/fs_context.h
@@ -265,5 +265,6 @@ static inline struct smb3_fs_context *smb3_fc2context(const struct fs_context *f
 }
 
 extern int smb3_fs_context_dup(struct smb3_fs_context *new_ctx, struct smb3_fs_context *ctx);
+extern void smb3_update_mnt_flags(struct cifs_sb_info *cifs_sb);
 
 #endif
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* [PATCH 21/21] cifs: update mnt_cifs_flags during reconfigure
       [not found] <20201207233646.29823-1-lsahlber@redhat.com>
                   ` (18 preceding siblings ...)
  2020-12-07 23:36 ` [PATCH 20/21] cifs: move update of flags into a separate function Ronnie Sahlberg
@ 2020-12-07 23:36 ` Ronnie Sahlberg
  19 siblings, 0 replies; 25+ messages in thread
From: Ronnie Sahlberg @ 2020-12-07 23:36 UTC (permalink / raw)
  To: linux-cifs; +Cc: Steve French

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
---
 fs/cifs/fs_context.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
index bf5a25b930d5..cc750bb55223 100644
--- a/fs/cifs/fs_context.c
+++ b/fs/cifs/fs_context.c
@@ -704,6 +704,7 @@ static int smb3_reconfigure(struct fs_context *fc)
 
 	smb3_cleanup_fs_context_contents(cifs_sb->ctx);
 	rc = smb3_fs_context_dup(cifs_sb->ctx, ctx);
+	smb3_update_mnt_flags(cifs_sb);
 
 	return rc;
 }
-- 
2.13.6


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH 14/21] cifs: we do not allow changing username/password/unc/... during remount
  2020-12-07 23:36 ` [PATCH 14/21] cifs: we do not allow changing username/password/unc/... during remount Ronnie Sahlberg
@ 2020-12-08  5:06   ` Steve French
  2020-12-08 18:42     ` Pavel Shilovsky
  0 siblings, 1 reply; 25+ messages in thread
From: Steve French @ 2020-12-08  5:06 UTC (permalink / raw)
  To: Ronnie Sahlberg; +Cc: linux-cifs

Minor nits pointed out by checkpatch:

0015-cifs-we-do-not-allow-changing-username-password-unc-.patch
---------------------------------------------------------------
WARNING: Missing commit description - Add an appropriate one

WARNING: kfree(NULL) is safe and this check is probably not required
#76: FILE: fs/cifs/fs_context.c:673:
+ if (ctx->field) { \
+ kfree(ctx->field);

On Mon, Dec 7, 2020 at 5:37 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
>  fs/cifs/cifsfs.c     |  2 +-
>  fs/cifs/fs_context.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++---
>  fs/cifs/fs_context.h |  2 +-
>  3 files changed, 54 insertions(+), 5 deletions(-)
>
> diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> index 80117e9d35f9..13d7f4a3c836 100644
> --- a/fs/cifs/cifsfs.c
> +++ b/fs/cifs/cifsfs.c
> @@ -490,7 +490,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
>
>         if (tcon->no_lease)
>                 seq_puts(s, ",nolease");
> -       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)
> +       if (cifs_sb->ctx->multiuser)
>                 seq_puts(s, ",multiuser");
>         else if (tcon->ses->user_name)
>                 seq_show_option(s, "username", tcon->ses->user_name);
> diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
> index edfdea129fcc..542fa75b74aa 100644
> --- a/fs/cifs/fs_context.c
> +++ b/fs/cifs/fs_context.c
> @@ -629,10 +629,53 @@ static int smb3_verify_reconfigure_ctx(struct smb3_fs_context *new_ctx,
>                 cifs_dbg(VFS, "can not change sec during remount\n");
>                 return -EINVAL;
>         }
> +       if (new_ctx->multiuser != old_ctx->multiuser) {
> +               cifs_dbg(VFS, "can not change multiuser during remount\n");
> +               return -EINVAL;
> +       }
> +       if (new_ctx->UNC &&
> +           (!old_ctx->UNC || strcmp(new_ctx->UNC, old_ctx->UNC))) {
> +               cifs_dbg(VFS, "can not change UNC during remount\n");
> +               return -EINVAL;
> +       }
> +       if (new_ctx->username &&
> +           (!old_ctx->username || strcmp(new_ctx->username, old_ctx->username))) {
> +               cifs_dbg(VFS, "can not change username during remount\n");
> +               return -EINVAL;
> +       }
> +       if (new_ctx->password &&
> +           (!old_ctx->password || strcmp(new_ctx->password, old_ctx->password))) {
> +               cifs_dbg(VFS, "can not change password during remount\n");
> +               return -EINVAL;
> +       }
> +       if (new_ctx->domainname &&
> +           (!old_ctx->domainname || strcmp(new_ctx->domainname, old_ctx->domainname))) {
> +               cifs_dbg(VFS, "can not change domainname during remount\n");
> +               return -EINVAL;
> +       }
> +       if (new_ctx->nodename &&
> +           (!old_ctx->nodename || strcmp(new_ctx->nodename, old_ctx->nodename))) {
> +               cifs_dbg(VFS, "can not change nodename during remount\n");
> +               return -EINVAL;
> +       }
> +       if (new_ctx->iocharset &&
> +           (!old_ctx->iocharset || strcmp(new_ctx->iocharset, old_ctx->iocharset))) {
> +               cifs_dbg(VFS, "can not change iocharset during remount\n");
> +               return -EINVAL;
> +       }
>
>         return 0;
>  }
>
> +#define STEAL_STRING(cifs_sb, ctx, field)                              \
> +do {                                                                   \
> +       if (ctx->field) {                                               \
> +               kfree(ctx->field);                                      \
> +               ctx->field = cifs_sb->ctx->field;                       \
> +               cifs_sb->ctx->field = NULL;                             \
> +       }                                                               \
> +} while (0)
> +
>  static int smb3_reconfigure(struct fs_context *fc)
>  {
>         struct smb3_fs_context *ctx = smb3_fc2context(fc);
> @@ -645,10 +688,16 @@ static int smb3_reconfigure(struct fs_context *fc)
>                 return rc;
>
>         /*
> -        * Steal the UNC from the old and to be destroyed context.
> +        * We can not change UNC/username/password/domainname/nodename/iocharset
> +        * during reconnect so ignore what we have in the new context and
> +        * just use what we already have in cifs_sb->ctx.
>          */
> -       ctx->UNC = cifs_sb->ctx->UNC;
> -       cifs_sb->ctx->UNC = NULL;
> +       STEAL_STRING(cifs_sb, ctx, UNC);
> +       STEAL_STRING(cifs_sb, ctx, username);
> +       STEAL_STRING(cifs_sb, ctx, password);
> +       STEAL_STRING(cifs_sb, ctx, domainname);
> +       STEAL_STRING(cifs_sb, ctx, nodename);
> +       STEAL_STRING(cifs_sb, ctx, iocharset);
>
>         smb3_cleanup_fs_context_contents(cifs_sb->ctx);
>         rc = smb3_fs_context_dup(cifs_sb->ctx, ctx);
> diff --git a/fs/cifs/fs_context.h b/fs/cifs/fs_context.h
> index aa1d952fd5ce..62f5a8d98df6 100644
> --- a/fs/cifs/fs_context.h
> +++ b/fs/cifs/fs_context.h
> @@ -148,7 +148,6 @@ struct smb3_fs_context {
>         bool uid_specified;
>         bool gid_specified;
>         bool sloppy;
> -       char *nodename;
>         bool got_ip;
>         bool got_version;
>         bool got_rsize;
> @@ -160,6 +159,7 @@ struct smb3_fs_context {
>         char *password;
>         char *domainname;
>         char *UNC;
> +       char *nodename;
>         char *iocharset;  /* local code page for mapping to and from Unicode */
>         char source_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* clnt nb name */
>         char target_rfc1001_name[RFC1001_NAME_LEN_WITH_NULL]; /* srvr nb name */
> --
> 2.13.6
>


-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 14/21] cifs: we do not allow changing username/password/unc/... during remount
  2020-12-08  5:06   ` Steve French
@ 2020-12-08 18:42     ` Pavel Shilovsky
  2020-12-08 21:38       ` ronnie sahlberg
  0 siblings, 1 reply; 25+ messages in thread
From: Pavel Shilovsky @ 2020-12-08 18:42 UTC (permalink / raw)
  To: Steve French; +Cc: Ronnie Sahlberg, linux-cifs

пн, 7 дек. 2020 г. в 21:07, Steve French <smfrench@gmail.com>:
>
> Minor nits pointed out by checkpatch:
>
> 0015-cifs-we-do-not-allow-changing-username-password-unc-.patch
> ---------------------------------------------------------------
> WARNING: Missing commit description - Add an appropriate one
>
> WARNING: kfree(NULL) is safe and this check is probably not required
> #76: FILE: fs/cifs/fs_context.c:673:
> + if (ctx->field) { \
> + kfree(ctx->field);
>
> On Mon, Dec 7, 2020 at 5:37 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
> >
> > Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> > ---
> >  fs/cifs/cifsfs.c     |  2 +-
> >  fs/cifs/fs_context.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++---
> >  fs/cifs/fs_context.h |  2 +-
> >  3 files changed, 54 insertions(+), 5 deletions(-)
> >
> > diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> > index 80117e9d35f9..13d7f4a3c836 100644
> > --- a/fs/cifs/cifsfs.c
> > +++ b/fs/cifs/cifsfs.c
> > @@ -490,7 +490,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
> >
> >         if (tcon->no_lease)
> >                 seq_puts(s, ",nolease");
> > -       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)
> > +       if (cifs_sb->ctx->multiuser)
> >                 seq_puts(s, ",multiuser");
> >         else if (tcon->ses->user_name)
> >                 seq_show_option(s, "username", tcon->ses->user_name);
> > diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
> > index edfdea129fcc..542fa75b74aa 100644
> > --- a/fs/cifs/fs_context.c
> > +++ b/fs/cifs/fs_context.c
> > @@ -629,10 +629,53 @@ static int smb3_verify_reconfigure_ctx(struct smb3_fs_context *new_ctx,
> >                 cifs_dbg(VFS, "can not change sec during remount\n");
> >                 return -EINVAL;
> >         }
> > +       if (new_ctx->multiuser != old_ctx->multiuser) {
> > +               cifs_dbg(VFS, "can not change multiuser during remount\n");
> > +               return -EINVAL;
> > +       }
> > +       if (new_ctx->UNC &&
> > +           (!old_ctx->UNC || strcmp(new_ctx->UNC, old_ctx->UNC))) {
> > +               cifs_dbg(VFS, "can not change UNC during remount\n");
> > +               return -EINVAL;
> > +       }
> > +       if (new_ctx->username &&
> > +           (!old_ctx->username || strcmp(new_ctx->username, old_ctx->username))) {
> > +               cifs_dbg(VFS, "can not change username during remount\n");
> > +               return -EINVAL;
> > +       }
> > +       if (new_ctx->password &&
> > +           (!old_ctx->password || strcmp(new_ctx->password, old_ctx->password))) {
> > +               cifs_dbg(VFS, "can not change password during remount\n");
> > +               return -EINVAL;
> > +       }
> > +       if (new_ctx->domainname &&
> > +           (!old_ctx->domainname || strcmp(new_ctx->domainname, old_ctx->domainname))) {
> > +               cifs_dbg(VFS, "can not change domainname during remount\n");
> > +               return -EINVAL;
> > +       }
> > +       if (new_ctx->nodename &&
> > +           (!old_ctx->nodename || strcmp(new_ctx->nodename, old_ctx->nodename))) {
> > +               cifs_dbg(VFS, "can not change nodename during remount\n");
> > +               return -EINVAL;
> > +       }
> > +       if (new_ctx->iocharset &&
> > +           (!old_ctx->iocharset || strcmp(new_ctx->iocharset, old_ctx->iocharset))) {
> > +               cifs_dbg(VFS, "can not change iocharset during remount\n");
> > +               return -EINVAL;
> > +       }
> >
> >         return 0;
> >  }
> >
> > +#define STEAL_STRING(cifs_sb, ctx, field)                              \
> > +do {                                                                   \
> > +       if (ctx->field) {                                               \
> > +               kfree(ctx->field);                                      \
> > +               ctx->field = cifs_sb->ctx->field;                       \
> > +               cifs_sb->ctx->field = NULL;                             \
> > +       }                                                               \
> > +} while (0)

If ctx->field is NULL we won't assign new value from
cifs_sb->ctx->field and the procedure will become no-op. Is this an
intent?

--
Best regards,
Pavel Shilovsky

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 14/21] cifs: we do not allow changing username/password/unc/... during remount
  2020-12-08 18:42     ` Pavel Shilovsky
@ 2020-12-08 21:38       ` ronnie sahlberg
  0 siblings, 0 replies; 25+ messages in thread
From: ronnie sahlberg @ 2020-12-08 21:38 UTC (permalink / raw)
  To: Pavel Shilovsky; +Cc: Steve French, Ronnie Sahlberg, linux-cifs

On Wed, Dec 9, 2020 at 7:08 AM Pavel Shilovsky <piastryyy@gmail.com> wrote:
>
> пн, 7 дек. 2020 г. в 21:07, Steve French <smfrench@gmail.com>:
> >
> > Minor nits pointed out by checkpatch:
> >
> > 0015-cifs-we-do-not-allow-changing-username-password-unc-.patch
> > ---------------------------------------------------------------
> > WARNING: Missing commit description - Add an appropriate one
> >
> > WARNING: kfree(NULL) is safe and this check is probably not required
> > #76: FILE: fs/cifs/fs_context.c:673:
> > + if (ctx->field) { \
> > + kfree(ctx->field);
> >
> > On Mon, Dec 7, 2020 at 5:37 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
> > >
> > > Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> > > ---
> > >  fs/cifs/cifsfs.c     |  2 +-
> > >  fs/cifs/fs_context.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++---
> > >  fs/cifs/fs_context.h |  2 +-
> > >  3 files changed, 54 insertions(+), 5 deletions(-)
> > >
> > > diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> > > index 80117e9d35f9..13d7f4a3c836 100644
> > > --- a/fs/cifs/cifsfs.c
> > > +++ b/fs/cifs/cifsfs.c
> > > @@ -490,7 +490,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
> > >
> > >         if (tcon->no_lease)
> > >                 seq_puts(s, ",nolease");
> > > -       if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER)
> > > +       if (cifs_sb->ctx->multiuser)
> > >                 seq_puts(s, ",multiuser");
> > >         else if (tcon->ses->user_name)
> > >                 seq_show_option(s, "username", tcon->ses->user_name);
> > > diff --git a/fs/cifs/fs_context.c b/fs/cifs/fs_context.c
> > > index edfdea129fcc..542fa75b74aa 100644
> > > --- a/fs/cifs/fs_context.c
> > > +++ b/fs/cifs/fs_context.c
> > > @@ -629,10 +629,53 @@ static int smb3_verify_reconfigure_ctx(struct smb3_fs_context *new_ctx,
> > >                 cifs_dbg(VFS, "can not change sec during remount\n");
> > >                 return -EINVAL;
> > >         }
> > > +       if (new_ctx->multiuser != old_ctx->multiuser) {
> > > +               cifs_dbg(VFS, "can not change multiuser during remount\n");
> > > +               return -EINVAL;
> > > +       }
> > > +       if (new_ctx->UNC &&
> > > +           (!old_ctx->UNC || strcmp(new_ctx->UNC, old_ctx->UNC))) {
> > > +               cifs_dbg(VFS, "can not change UNC during remount\n");
> > > +               return -EINVAL;
> > > +       }
> > > +       if (new_ctx->username &&
> > > +           (!old_ctx->username || strcmp(new_ctx->username, old_ctx->username))) {
> > > +               cifs_dbg(VFS, "can not change username during remount\n");
> > > +               return -EINVAL;
> > > +       }
> > > +       if (new_ctx->password &&
> > > +           (!old_ctx->password || strcmp(new_ctx->password, old_ctx->password))) {
> > > +               cifs_dbg(VFS, "can not change password during remount\n");
> > > +               return -EINVAL;
> > > +       }
> > > +       if (new_ctx->domainname &&
> > > +           (!old_ctx->domainname || strcmp(new_ctx->domainname, old_ctx->domainname))) {
> > > +               cifs_dbg(VFS, "can not change domainname during remount\n");
> > > +               return -EINVAL;
> > > +       }
> > > +       if (new_ctx->nodename &&
> > > +           (!old_ctx->nodename || strcmp(new_ctx->nodename, old_ctx->nodename))) {
> > > +               cifs_dbg(VFS, "can not change nodename during remount\n");
> > > +               return -EINVAL;
> > > +       }
> > > +       if (new_ctx->iocharset &&
> > > +           (!old_ctx->iocharset || strcmp(new_ctx->iocharset, old_ctx->iocharset))) {
> > > +               cifs_dbg(VFS, "can not change iocharset during remount\n");
> > > +               return -EINVAL;
> > > +       }
> > >
> > >         return 0;
> > >  }
> > >
> > > +#define STEAL_STRING(cifs_sb, ctx, field)                              \
> > > +do {                                                                   \
> > > +       if (ctx->field) {                                               \
> > > +               kfree(ctx->field);                                      \
> > > +               ctx->field = cifs_sb->ctx->field;                       \
> > > +               cifs_sb->ctx->field = NULL;                             \
> > > +       }                                                               \
> > > +} while (0)
>
> If ctx->field is NULL we won't assign new value from
> cifs_sb->ctx->field and the procedure will become no-op. Is this an
> intent?

No, that is a bug. I will fix that.

Thanks.

>
> --
> Best regards,
> Pavel Shilovsky

^ permalink raw reply	[flat|nested] 25+ messages in thread

* Re: [PATCH 09/21] cifs: remove [gu]id/backup[gu]id/file_mode/dir_mode from cifs_sb
  2020-12-07 23:36 ` [PATCH 09/21] cifs: remove [gu]id/backup[gu]id/file_mode/dir_mode from cifs_sb Ronnie Sahlberg
@ 2020-12-12 19:42   ` Steve French
  0 siblings, 0 replies; 25+ messages in thread
From: Steve French @ 2020-12-12 19:42 UTC (permalink / raw)
  To: Ronnie Sahlberg; +Cc: linux-cifs

[-- Attachment #1: Type: text/plain, Size: 15647 bytes --]

rebased patch on current for-next and tentatively merged into for-next


On Mon, Dec 7, 2020 at 5:38 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
>
> We can already access these from cifs_sb->ctx so we no longer need
> a local copy in cifs_sb.
>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
>  fs/cifs/cifs_fs_sb.h |  6 ------
>  fs/cifs/cifsacl.c    |  7 ++++---
>  fs/cifs/cifsfs.c     | 12 ++++++------
>  fs/cifs/connect.c    | 15 +++++----------
>  fs/cifs/file.c       |  5 +++--
>  fs/cifs/inode.c      | 29 +++++++++++++++--------------
>  fs/cifs/misc.c       |  5 +++--
>  fs/cifs/readdir.c    |  9 +++++----
>  8 files changed, 41 insertions(+), 47 deletions(-)
>
> diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
> index 8ee37c80880a..3f4f1487f714 100644
> --- a/fs/cifs/cifs_fs_sb.h
> +++ b/fs/cifs/cifs_fs_sb.h
> @@ -67,12 +67,6 @@ struct cifs_sb_info {
>         unsigned int wsize;
>         unsigned long actimeo; /* attribute cache timeout (jiffies) */
>         atomic_t active;
> -       kuid_t  mnt_uid;
> -       kgid_t  mnt_gid;
> -       kuid_t  mnt_backupuid;
> -       kgid_t  mnt_backupgid;
> -       umode_t mnt_file_mode;
> -       umode_t mnt_dir_mode;
>         unsigned int mnt_cifs_flags;
>         struct delayed_work prune_tlinks;
>         struct rcu_head rcu;
> diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
> index 23b21e943652..d4e33bba4713 100644
> --- a/fs/cifs/cifsacl.c
> +++ b/fs/cifs/cifsacl.c
> @@ -32,6 +32,7 @@
>  #include "cifsacl.h"
>  #include "cifsproto.h"
>  #include "cifs_debug.h"
> +#include "fs_context.h"
>
>  /* security id for everyone/world system group */
>  static const struct cifs_sid sid_everyone = {
> @@ -346,8 +347,8 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
>         struct key *sidkey;
>         char *sidstr;
>         const struct cred *saved_cred;
> -       kuid_t fuid = cifs_sb->mnt_uid;
> -       kgid_t fgid = cifs_sb->mnt_gid;
> +       kuid_t fuid = cifs_sb->ctx->linux_uid;
> +       kgid_t fgid = cifs_sb->ctx->linux_gid;
>
>         /*
>          * If we have too many subauthorities, then something is really wrong.
> @@ -448,7 +449,7 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
>
>         /*
>          * Note that we return 0 here unconditionally. If the mapping
> -        * fails then we just fall back to using the mnt_uid/mnt_gid.
> +        * fails then we just fall back to using the ctx->linux_uid/linux_gid.
>          */
>  got_valid_id:
>         rc = 0;
> diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> index 4f27f77d3053..4ea8c3c3bce1 100644
> --- a/fs/cifs/cifsfs.c
> +++ b/fs/cifs/cifsfs.c
> @@ -515,14 +515,14 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
>         }
>
>         seq_printf(s, ",uid=%u",
> -                  from_kuid_munged(&init_user_ns, cifs_sb->mnt_uid));
> +                  from_kuid_munged(&init_user_ns, cifs_sb->ctx->linux_uid));
>         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
>                 seq_puts(s, ",forceuid");
>         else
>                 seq_puts(s, ",noforceuid");
>
>         seq_printf(s, ",gid=%u",
> -                  from_kgid_munged(&init_user_ns, cifs_sb->mnt_gid));
> +                  from_kgid_munged(&init_user_ns, cifs_sb->ctx->linux_gid));
>         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
>                 seq_puts(s, ",forcegid");
>         else
> @@ -532,8 +532,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
>
>         if (!tcon->unix_ext)
>                 seq_printf(s, ",file_mode=0%ho,dir_mode=0%ho",
> -                                          cifs_sb->mnt_file_mode,
> -                                          cifs_sb->mnt_dir_mode);
> +                                          cifs_sb->ctx->file_mode,
> +                                          cifs_sb->ctx->dir_mode);
>
>         cifs_show_nls(s, cifs_sb->local_nls);
>
> @@ -606,11 +606,11 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
>         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID)
>                 seq_printf(s, ",backupuid=%u",
>                            from_kuid_munged(&init_user_ns,
> -                                           cifs_sb->mnt_backupuid));
> +                                           cifs_sb->ctx->backupuid));
>         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID)
>                 seq_printf(s, ",backupgid=%u",
>                            from_kgid_munged(&init_user_ns,
> -                                           cifs_sb->mnt_backupgid));
> +                                           cifs_sb->ctx->backupgid));
>
>         seq_printf(s, ",rsize=%u", cifs_sb->rsize);
>         seq_printf(s, ",wsize=%u", cifs_sb->wsize);
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index 7fc27fb49789..96c5b66d4b44 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -2225,11 +2225,12 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
>         if (new->rsize && new->rsize < old->rsize)
>                 return 0;
>
> -       if (!uid_eq(old->mnt_uid, new->mnt_uid) || !gid_eq(old->mnt_gid, new->mnt_gid))
> +       if (!uid_eq(old->ctx->linux_uid, new->ctx->linux_uid) ||
> +           !gid_eq(old->ctx->linux_gid, new->ctx->linux_gid))
>                 return 0;
>
> -       if (old->mnt_file_mode != new->mnt_file_mode ||
> -           old->mnt_dir_mode != new->mnt_dir_mode)
> +       if (old->ctx->file_mode != new->ctx->file_mode ||
> +           old->ctx->dir_mode != new->ctx->dir_mode)
>                 return 0;
>
>         if (strcmp(old->local_nls->charset, new->local_nls->charset))
> @@ -2678,12 +2679,8 @@ int cifs_setup_cifs_sb(struct smb3_fs_context *ctx,
>         cifs_sb->rsize = ctx->rsize;
>         cifs_sb->wsize = ctx->wsize;
>
> -       cifs_sb->mnt_uid = ctx->linux_uid;
> -       cifs_sb->mnt_gid = ctx->linux_gid;
> -       cifs_sb->mnt_file_mode = ctx->file_mode;
> -       cifs_sb->mnt_dir_mode = ctx->dir_mode;
>         cifs_dbg(FYI, "file mode: %04ho  dir mode: %04ho\n",
> -                cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
> +                cifs_sb->ctx->file_mode, cifs_sb->ctx->dir_mode);
>
>         cifs_sb->actimeo = ctx->actimeo;
>         cifs_sb->local_nls = ctx->local_nls;
> @@ -2722,11 +2719,9 @@ int cifs_setup_cifs_sb(struct smb3_fs_context *ctx,
>                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
>         if (ctx->backupuid_specified) {
>                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID;
> -               cifs_sb->mnt_backupuid = ctx->backupuid;
>         }
>         if (ctx->backupgid_specified) {
>                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID;
> -               cifs_sb->mnt_backupgid = ctx->backupgid;
>         }
>         if (ctx->override_uid)
>                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
> diff --git a/fs/cifs/file.c b/fs/cifs/file.c
> index be46fab4c96d..3ee510d3dab8 100644
> --- a/fs/cifs/file.c
> +++ b/fs/cifs/file.c
> @@ -44,6 +44,7 @@
>  #include "cifs_fs_sb.h"
>  #include "fscache.h"
>  #include "smbdirect.h"
> +#include "fs_context.h"
>
>  static inline int cifs_convert_flags(unsigned int flags)
>  {
> @@ -566,7 +567,7 @@ int cifs_open(struct inode *inode, struct file *file)
>                                 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
>                 /* can not refresh inode info since size could be stale */
>                 rc = cifs_posix_open(full_path, &inode, inode->i_sb,
> -                               cifs_sb->mnt_file_mode /* ignored */,
> +                               cifs_sb->ctx->file_mode /* ignored */,
>                                 file->f_flags, &oplock, &fid.netfid, xid);
>                 if (rc == 0) {
>                         cifs_dbg(FYI, "posix open succeeded\n");
> @@ -735,7 +736,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
>                                                 ~(O_CREAT | O_EXCL | O_TRUNC);
>
>                 rc = cifs_posix_open(full_path, NULL, inode->i_sb,
> -                                    cifs_sb->mnt_file_mode /* ignored */,
> +                                    cifs_sb->ctx->file_mode /* ignored */,
>                                      oflags, &oplock, &cfile->fid.netfid, xid);
>                 if (rc == 0) {
>                         cifs_dbg(FYI, "posix reopen succeeded\n");
> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
> index daec31be8571..e8a7110db2a6 100644
> --- a/fs/cifs/inode.c
> +++ b/fs/cifs/inode.c
> @@ -37,6 +37,7 @@
>  #include "cifs_fs_sb.h"
>  #include "cifs_unicode.h"
>  #include "fscache.h"
> +#include "fs_context.h"
>
>
>  static void cifs_set_ops(struct inode *inode)
> @@ -294,7 +295,7 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
>                 break;
>         }
>
> -       fattr->cf_uid = cifs_sb->mnt_uid;
> +       fattr->cf_uid = cifs_sb->ctx->linux_uid;
>         if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) {
>                 u64 id = le64_to_cpu(info->Uid);
>                 if (id < ((uid_t)-1)) {
> @@ -304,7 +305,7 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
>                 }
>         }
>
> -       fattr->cf_gid = cifs_sb->mnt_gid;
> +       fattr->cf_gid = cifs_sb->ctx->linux_gid;
>         if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) {
>                 u64 id = le64_to_cpu(info->Gid);
>                 if (id < ((gid_t)-1)) {
> @@ -333,8 +334,8 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
>
>         memset(fattr, 0, sizeof(*fattr));
>         fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
> -       fattr->cf_uid = cifs_sb->mnt_uid;
> -       fattr->cf_gid = cifs_sb->mnt_gid;
> +       fattr->cf_uid = cifs_sb->ctx->linux_uid;
> +       fattr->cf_gid = cifs_sb->ctx->linux_gid;
>         ktime_get_coarse_real_ts64(&fattr->cf_mtime);
>         fattr->cf_atime = fattr->cf_ctime = fattr->cf_mtime;
>         fattr->cf_nlink = 2;
> @@ -644,8 +645,8 @@ smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct smb311_posix_qinfo *
>         }
>         /* else if reparse point ... TODO: add support for FIFO and blk dev; special file types */
>
> -       fattr->cf_uid = cifs_sb->mnt_uid; /* TODO: map uid and gid from SID */
> -       fattr->cf_gid = cifs_sb->mnt_gid;
> +       fattr->cf_uid = cifs_sb->ctx->linux_uid; /* TODO: map uid and gid from SID */
> +       fattr->cf_gid = cifs_sb->ctx->linux_gid;
>
>         cifs_dbg(FYI, "POSIX query info: mode 0x%x uniqueid 0x%llx nlink %d\n",
>                 fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink);
> @@ -689,7 +690,7 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
>                 fattr->cf_mode = S_IFLNK;
>                 fattr->cf_dtype = DT_LNK;
>         } else if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
> -               fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
> +               fattr->cf_mode = S_IFDIR | cifs_sb->ctx->dir_mode;
>                 fattr->cf_dtype = DT_DIR;
>                 /*
>                  * Server can return wrong NumberOfLinks value for directories
> @@ -698,7 +699,7 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
>                 if (!tcon->unix_ext)
>                         fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK;
>         } else {
> -               fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
> +               fattr->cf_mode = S_IFREG | cifs_sb->ctx->file_mode;
>                 fattr->cf_dtype = DT_REG;
>
>                 /* clear write bits if ATTR_READONLY is set */
> @@ -717,8 +718,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
>                 }
>         }
>
> -       fattr->cf_uid = cifs_sb->mnt_uid;
> -       fattr->cf_gid = cifs_sb->mnt_gid;
> +       fattr->cf_uid = cifs_sb->ctx->linux_uid;
> +       fattr->cf_gid = cifs_sb->ctx->linux_gid;
>  }
>
>  static int
> @@ -1358,8 +1359,8 @@ struct inode *cifs_root_iget(struct super_block *sb)
>                 set_nlink(inode, 2);
>                 inode->i_op = &cifs_ipc_inode_ops;
>                 inode->i_fop = &simple_dir_operations;
> -               inode->i_uid = cifs_sb->mnt_uid;
> -               inode->i_gid = cifs_sb->mnt_gid;
> +               inode->i_uid = cifs_sb->ctx->linux_uid;
> +               inode->i_gid = cifs_sb->ctx->linux_gid;
>                 spin_unlock(&inode->i_lock);
>         } else if (rc) {
>                 iget_failed(inode);
> @@ -2834,10 +2835,10 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
>                                 attrs->ia_mode &= ~(S_IALLUGO);
>                                 if (S_ISDIR(inode->i_mode))
>                                         attrs->ia_mode |=
> -                                               cifs_sb->mnt_dir_mode;
> +                                               cifs_sb->ctx->dir_mode;
>                                 else
>                                         attrs->ia_mode |=
> -                                               cifs_sb->mnt_file_mode;
> +                                               cifs_sb->ctx->file_mode;
>                         }
>                 } else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
>                         /* ignore mode change - ATTR_READONLY hasn't changed */
> diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
> index 1c14cf01dbef..82e176720ca6 100644
> --- a/fs/cifs/misc.c
> +++ b/fs/cifs/misc.c
> @@ -35,6 +35,7 @@
>  #ifdef CONFIG_CIFS_DFS_UPCALL
>  #include "dns_resolve.h"
>  #endif
> +#include "fs_context.h"
>
>  extern mempool_t *cifs_sm_req_poolp;
>  extern mempool_t *cifs_req_poolp;
> @@ -632,11 +633,11 @@ bool
>  backup_cred(struct cifs_sb_info *cifs_sb)
>  {
>         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) {
> -               if (uid_eq(cifs_sb->mnt_backupuid, current_fsuid()))
> +               if (uid_eq(cifs_sb->ctx->backupuid, current_fsuid()))
>                         return true;
>         }
>         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) {
> -               if (in_group_p(cifs_sb->mnt_backupgid))
> +               if (in_group_p(cifs_sb->ctx->backupgid))
>                         return true;
>         }
>
> diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
> index 5abf1ea21abe..70676843e169 100644
> --- a/fs/cifs/readdir.c
> +++ b/fs/cifs/readdir.c
> @@ -33,6 +33,7 @@
>  #include "cifs_fs_sb.h"
>  #include "cifsfs.h"
>  #include "smb2proto.h"
> +#include "fs_context.h"
>
>  /*
>   * To be safe - for UCS to UTF-8 with strings loaded with the rare long
> @@ -165,14 +166,14 @@ static bool reparse_file_needs_reval(const struct cifs_fattr *fattr)
>  static void
>  cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
>  {
> -       fattr->cf_uid = cifs_sb->mnt_uid;
> -       fattr->cf_gid = cifs_sb->mnt_gid;
> +       fattr->cf_uid = cifs_sb->ctx->linux_uid;
> +       fattr->cf_gid = cifs_sb->ctx->linux_gid;
>
>         if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
> -               fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
> +               fattr->cf_mode = S_IFDIR | cifs_sb->ctx->dir_mode;
>                 fattr->cf_dtype = DT_DIR;
>         } else {
> -               fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
> +               fattr->cf_mode = S_IFREG | cifs_sb->ctx->file_mode;
>                 fattr->cf_dtype = DT_REG;
>         }
>
> --
> 2.13.6
>


-- 
Thanks,

Steve

[-- Attachment #2: 0001-cifs-remove-gu-id-backup-gu-id-file_mode-dir_mode-fr.patch --]
[-- Type: text/x-patch, Size: 15082 bytes --]

From 4afde6c74023ba38d18c9982421306e7f2d4921a Mon Sep 17 00:00:00 2001
From: Ronnie Sahlberg <lsahlber@redhat.com>
Date: Sat, 12 Dec 2020 13:40:50 -0600
Subject: [PATCH] cifs: remove [gu]id/backup[gu]id/file_mode/dir_mode from
 cifs_sb

We can already access these from cifs_sb->ctx so we no longer need
a local copy in cifs_sb.

Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
Signed-off-by: Steve French <stfrench@microsoft.com>
---
 fs/cifs/cifs_fs_sb.h |  6 ------
 fs/cifs/cifsacl.c    |  7 ++++---
 fs/cifs/cifsfs.c     | 12 ++++++------
 fs/cifs/connect.c    | 15 +++++----------
 fs/cifs/file.c       |  5 +++--
 fs/cifs/inode.c      | 39 ++++++++++++++++++++-------------------
 fs/cifs/misc.c       |  5 +++--
 fs/cifs/readdir.c    | 19 ++++++++++---------
 8 files changed, 51 insertions(+), 57 deletions(-)

diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
index 8ee37c80880a..3f4f1487f714 100644
--- a/fs/cifs/cifs_fs_sb.h
+++ b/fs/cifs/cifs_fs_sb.h
@@ -67,12 +67,6 @@ struct cifs_sb_info {
 	unsigned int wsize;
 	unsigned long actimeo; /* attribute cache timeout (jiffies) */
 	atomic_t active;
-	kuid_t	mnt_uid;
-	kgid_t	mnt_gid;
-	kuid_t	mnt_backupuid;
-	kgid_t	mnt_backupgid;
-	umode_t	mnt_file_mode;
-	umode_t	mnt_dir_mode;
 	unsigned int mnt_cifs_flags;
 	struct delayed_work prune_tlinks;
 	struct rcu_head rcu;
diff --git a/fs/cifs/cifsacl.c b/fs/cifs/cifsacl.c
index c3954bfcb666..2f21f89871cc 100644
--- a/fs/cifs/cifsacl.c
+++ b/fs/cifs/cifsacl.c
@@ -32,6 +32,7 @@
 #include "cifsacl.h"
 #include "cifsproto.h"
 #include "cifs_debug.h"
+#include "fs_context.h"
 
 /* security id for everyone/world system group */
 static const struct cifs_sid sid_everyone = {
@@ -346,8 +347,8 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
 	struct key *sidkey;
 	char *sidstr;
 	const struct cred *saved_cred;
-	kuid_t fuid = cifs_sb->mnt_uid;
-	kgid_t fgid = cifs_sb->mnt_gid;
+	kuid_t fuid = cifs_sb->ctx->linux_uid;
+	kgid_t fgid = cifs_sb->ctx->linux_gid;
 
 	/*
 	 * If we have too many subauthorities, then something is really wrong.
@@ -448,7 +449,7 @@ sid_to_id(struct cifs_sb_info *cifs_sb, struct cifs_sid *psid,
 
 	/*
 	 * Note that we return 0 here unconditionally. If the mapping
-	 * fails then we just fall back to using the mnt_uid/mnt_gid.
+	 * fails then we just fall back to using the ctx->linux_uid/linux_gid.
 	 */
 got_valid_id:
 	rc = 0;
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index f810b25dfeb8..3af22c09d8de 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -518,14 +518,14 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
 	}
 
 	seq_printf(s, ",uid=%u",
-		   from_kuid_munged(&init_user_ns, cifs_sb->mnt_uid));
+		   from_kuid_munged(&init_user_ns, cifs_sb->ctx->linux_uid));
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)
 		seq_puts(s, ",forceuid");
 	else
 		seq_puts(s, ",noforceuid");
 
 	seq_printf(s, ",gid=%u",
-		   from_kgid_munged(&init_user_ns, cifs_sb->mnt_gid));
+		   from_kgid_munged(&init_user_ns, cifs_sb->ctx->linux_gid));
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)
 		seq_puts(s, ",forcegid");
 	else
@@ -535,8 +535,8 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
 
 	if (!tcon->unix_ext)
 		seq_printf(s, ",file_mode=0%ho,dir_mode=0%ho",
-					   cifs_sb->mnt_file_mode,
-					   cifs_sb->mnt_dir_mode);
+					   cifs_sb->ctx->file_mode,
+					   cifs_sb->ctx->dir_mode);
 
 	cifs_show_nls(s, cifs_sb->local_nls);
 
@@ -609,11 +609,11 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID)
 		seq_printf(s, ",backupuid=%u",
 			   from_kuid_munged(&init_user_ns,
-					    cifs_sb->mnt_backupuid));
+					    cifs_sb->ctx->backupuid));
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID)
 		seq_printf(s, ",backupgid=%u",
 			   from_kgid_munged(&init_user_ns,
-					    cifs_sb->mnt_backupgid));
+					    cifs_sb->ctx->backupgid));
 
 	seq_printf(s, ",rsize=%u", cifs_sb->rsize);
 	seq_printf(s, ",wsize=%u", cifs_sb->wsize);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 156c18bf40d2..f6aa37aa3bf0 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2240,11 +2240,12 @@ compare_mount_options(struct super_block *sb, struct cifs_mnt_data *mnt_data)
 	if (new->rsize && new->rsize < old->rsize)
 		return 0;
 
-	if (!uid_eq(old->mnt_uid, new->mnt_uid) || !gid_eq(old->mnt_gid, new->mnt_gid))
+	if (!uid_eq(old->ctx->linux_uid, new->ctx->linux_uid) ||
+	    !gid_eq(old->ctx->linux_gid, new->ctx->linux_gid))
 		return 0;
 
-	if (old->mnt_file_mode != new->mnt_file_mode ||
-	    old->mnt_dir_mode != new->mnt_dir_mode)
+	if (old->ctx->file_mode != new->ctx->file_mode ||
+	    old->ctx->dir_mode != new->ctx->dir_mode)
 		return 0;
 
 	if (strcmp(old->local_nls->charset, new->local_nls->charset))
@@ -2707,12 +2708,8 @@ int cifs_setup_cifs_sb(struct smb3_fs_context *ctx,
 	cifs_sb->rsize = ctx->rsize;
 	cifs_sb->wsize = ctx->wsize;
 
-	cifs_sb->mnt_uid = ctx->linux_uid;
-	cifs_sb->mnt_gid = ctx->linux_gid;
-	cifs_sb->mnt_file_mode = ctx->file_mode;
-	cifs_sb->mnt_dir_mode = ctx->dir_mode;
 	cifs_dbg(FYI, "file mode: %04ho  dir mode: %04ho\n",
-		 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
+		 cifs_sb->ctx->file_mode, cifs_sb->ctx->dir_mode);
 
 	cifs_sb->actimeo = ctx->actimeo;
 	cifs_sb->local_nls = ctx->local_nls;
@@ -2751,11 +2748,9 @@ int cifs_setup_cifs_sb(struct smb3_fs_context *ctx,
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
 	if (ctx->backupuid_specified) {
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPUID;
-		cifs_sb->mnt_backupuid = ctx->backupuid;
 	}
 	if (ctx->backupgid_specified) {
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_BACKUPGID;
-		cifs_sb->mnt_backupgid = ctx->backupgid;
 	}
 	if (ctx->override_uid)
 		cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 29176a56229f..583074546e6f 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -44,6 +44,7 @@
 #include "cifs_fs_sb.h"
 #include "fscache.h"
 #include "smbdirect.h"
+#include "fs_context.h"
 
 static inline int cifs_convert_flags(unsigned int flags)
 {
@@ -571,7 +572,7 @@ int cifs_open(struct inode *inode, struct file *file)
 				le64_to_cpu(tcon->fsUnixInfo.Capability))) {
 		/* can not refresh inode info since size could be stale */
 		rc = cifs_posix_open(full_path, &inode, inode->i_sb,
-				cifs_sb->mnt_file_mode /* ignored */,
+				cifs_sb->ctx->file_mode /* ignored */,
 				file->f_flags, &oplock, &fid.netfid, xid);
 		if (rc == 0) {
 			cifs_dbg(FYI, "posix open succeeded\n");
@@ -740,7 +741,7 @@ cifs_reopen_file(struct cifsFileInfo *cfile, bool can_flush)
 						~(O_CREAT | O_EXCL | O_TRUNC);
 
 		rc = cifs_posix_open(full_path, NULL, inode->i_sb,
-				     cifs_sb->mnt_file_mode /* ignored */,
+				     cifs_sb->ctx->file_mode /* ignored */,
 				     oflags, &oplock, &cfile->fid.netfid, xid);
 		if (rc == 0) {
 			cifs_dbg(FYI, "posix reopen succeeded\n");
diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
index eb3c88671508..bbdce32e978f 100644
--- a/fs/cifs/inode.c
+++ b/fs/cifs/inode.c
@@ -37,6 +37,7 @@
 #include "cifs_fs_sb.h"
 #include "cifs_unicode.h"
 #include "fscache.h"
+#include "fs_context.h"
 
 
 static void cifs_set_ops(struct inode *inode)
@@ -294,7 +295,7 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
 		break;
 	}
 
-	fattr->cf_uid = cifs_sb->mnt_uid;
+	fattr->cf_uid = cifs_sb->ctx->linux_uid;
 	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_UID)) {
 		u64 id = le64_to_cpu(info->Uid);
 		if (id < ((uid_t)-1)) {
@@ -304,7 +305,7 @@ cifs_unix_basic_to_fattr(struct cifs_fattr *fattr, FILE_UNIX_BASIC_INFO *info,
 		}
 	}
 	
-	fattr->cf_gid = cifs_sb->mnt_gid;
+	fattr->cf_gid = cifs_sb->ctx->linux_gid;
 	if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_OVERR_GID)) {
 		u64 id = le64_to_cpu(info->Gid);
 		if (id < ((gid_t)-1)) {
@@ -333,8 +334,8 @@ cifs_create_dfs_fattr(struct cifs_fattr *fattr, struct super_block *sb)
 
 	memset(fattr, 0, sizeof(*fattr));
 	fattr->cf_mode = S_IFDIR | S_IXUGO | S_IRWXU;
-	fattr->cf_uid = cifs_sb->mnt_uid;
-	fattr->cf_gid = cifs_sb->mnt_gid;
+	fattr->cf_uid = cifs_sb->ctx->linux_uid;
+	fattr->cf_gid = cifs_sb->ctx->linux_gid;
 	ktime_get_coarse_real_ts64(&fattr->cf_mtime);
 	fattr->cf_atime = fattr->cf_ctime = fattr->cf_mtime;
 	fattr->cf_nlink = 2;
@@ -644,8 +645,8 @@ smb311_posix_info_to_fattr(struct cifs_fattr *fattr, struct smb311_posix_qinfo *
 	}
 	/* else if reparse point ... TODO: add support for FIFO and blk dev; special file types */
 
-	fattr->cf_uid = cifs_sb->mnt_uid; /* TODO: map uid and gid from SID */
-	fattr->cf_gid = cifs_sb->mnt_gid;
+	fattr->cf_uid = cifs_sb->ctx->linux_uid; /* TODO: map uid and gid from SID */
+	fattr->cf_gid = cifs_sb->ctx->linux_gid;
 
 	cifs_dbg(FYI, "POSIX query info: mode 0x%x uniqueid 0x%llx nlink %d\n",
 		fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink);
@@ -685,25 +686,25 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
 
 	fattr->cf_nlink = le32_to_cpu(info->NumberOfLinks);
 	if (reparse_tag == IO_REPARSE_TAG_LX_SYMLINK) {
-		fattr->cf_mode |= S_IFLNK | cifs_sb->mnt_file_mode;
+		fattr->cf_mode |= S_IFLNK | cifs_sb->ctx->file_mode;
 		fattr->cf_dtype = DT_LNK;
 	} else if (reparse_tag == IO_REPARSE_TAG_LX_FIFO) {
-		fattr->cf_mode |= S_IFIFO | cifs_sb->mnt_file_mode;
+		fattr->cf_mode |= S_IFIFO | cifs_sb->ctx->file_mode;
 		fattr->cf_dtype = DT_FIFO;
 	} else if (reparse_tag == IO_REPARSE_TAG_AF_UNIX) {
-		fattr->cf_mode |= S_IFSOCK | cifs_sb->mnt_file_mode;
+		fattr->cf_mode |= S_IFSOCK | cifs_sb->ctx->file_mode;
 		fattr->cf_dtype = DT_SOCK;
 	} else if (reparse_tag == IO_REPARSE_TAG_LX_CHR) {
-		fattr->cf_mode |= S_IFCHR | cifs_sb->mnt_file_mode;
+		fattr->cf_mode |= S_IFCHR | cifs_sb->ctx->file_mode;
 		fattr->cf_dtype = DT_CHR;
 	} else if (reparse_tag == IO_REPARSE_TAG_LX_BLK) {
-		fattr->cf_mode |= S_IFBLK | cifs_sb->mnt_file_mode;
+		fattr->cf_mode |= S_IFBLK | cifs_sb->ctx->file_mode;
 		fattr->cf_dtype = DT_BLK;
 	} else if (symlink) { /* TODO add more reparse tag checks */
 		fattr->cf_mode = S_IFLNK;
 		fattr->cf_dtype = DT_LNK;
 	} else if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
-		fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
+		fattr->cf_mode = S_IFDIR | cifs_sb->ctx->dir_mode;
 		fattr->cf_dtype = DT_DIR;
 		/*
 		 * Server can return wrong NumberOfLinks value for directories
@@ -712,7 +713,7 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
 		if (!tcon->unix_ext)
 			fattr->cf_flags |= CIFS_FATTR_UNKNOWN_NLINK;
 	} else {
-		fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
+		fattr->cf_mode = S_IFREG | cifs_sb->ctx->file_mode;
 		fattr->cf_dtype = DT_REG;
 
 		/* clear write bits if ATTR_READONLY is set */
@@ -731,8 +732,8 @@ cifs_all_info_to_fattr(struct cifs_fattr *fattr, FILE_ALL_INFO *info,
 		}
 	}
 
-	fattr->cf_uid = cifs_sb->mnt_uid;
-	fattr->cf_gid = cifs_sb->mnt_gid;
+	fattr->cf_uid = cifs_sb->ctx->linux_uid;
+	fattr->cf_gid = cifs_sb->ctx->linux_gid;
 }
 
 static int
@@ -1391,8 +1392,8 @@ struct inode *cifs_root_iget(struct super_block *sb)
 		set_nlink(inode, 2);
 		inode->i_op = &cifs_ipc_inode_ops;
 		inode->i_fop = &simple_dir_operations;
-		inode->i_uid = cifs_sb->mnt_uid;
-		inode->i_gid = cifs_sb->mnt_gid;
+		inode->i_uid = cifs_sb->ctx->linux_uid;
+		inode->i_gid = cifs_sb->ctx->linux_gid;
 		spin_unlock(&inode->i_lock);
 	} else if (rc) {
 		iget_failed(inode);
@@ -2877,10 +2878,10 @@ cifs_setattr_nounix(struct dentry *direntry, struct iattr *attrs)
 				attrs->ia_mode &= ~(S_IALLUGO);
 				if (S_ISDIR(inode->i_mode))
 					attrs->ia_mode |=
-						cifs_sb->mnt_dir_mode;
+						cifs_sb->ctx->dir_mode;
 				else
 					attrs->ia_mode |=
-						cifs_sb->mnt_file_mode;
+						cifs_sb->ctx->file_mode;
 			}
 		} else if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_DYNPERM)) {
 			/* ignore mode change - ATTR_READONLY hasn't changed */
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 1c14cf01dbef..82e176720ca6 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -35,6 +35,7 @@
 #ifdef CONFIG_CIFS_DFS_UPCALL
 #include "dns_resolve.h"
 #endif
+#include "fs_context.h"
 
 extern mempool_t *cifs_sm_req_poolp;
 extern mempool_t *cifs_req_poolp;
@@ -632,11 +633,11 @@ bool
 backup_cred(struct cifs_sb_info *cifs_sb)
 {
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPUID) {
-		if (uid_eq(cifs_sb->mnt_backupuid, current_fsuid()))
+		if (uid_eq(cifs_sb->ctx->backupuid, current_fsuid()))
 			return true;
 	}
 	if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_CIFS_BACKUPGID) {
-		if (in_group_p(cifs_sb->mnt_backupgid))
+		if (in_group_p(cifs_sb->ctx->backupgid))
 			return true;
 	}
 
diff --git a/fs/cifs/readdir.c b/fs/cifs/readdir.c
index 799be3a5d25e..80bf4c6f4c7b 100644
--- a/fs/cifs/readdir.c
+++ b/fs/cifs/readdir.c
@@ -33,6 +33,7 @@
 #include "cifs_fs_sb.h"
 #include "cifsfs.h"
 #include "smb2proto.h"
+#include "fs_context.h"
 
 /*
  * To be safe - for UCS to UTF-8 with strings loaded with the rare long
@@ -165,8 +166,8 @@ static bool reparse_file_needs_reval(const struct cifs_fattr *fattr)
 static void
 cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
 {
-	fattr->cf_uid = cifs_sb->mnt_uid;
-	fattr->cf_gid = cifs_sb->mnt_gid;
+	fattr->cf_uid = cifs_sb->ctx->linux_uid;
+	fattr->cf_gid = cifs_sb->ctx->linux_gid;
 
 	/*
 	 * The IO_REPARSE_TAG_LX_ tags originally were used by WSL but they
@@ -177,25 +178,25 @@ cifs_fill_common_info(struct cifs_fattr *fattr, struct cifs_sb_info *cifs_sb)
 	 * reasonably map some of them to directories vs. files vs. symlinks
 	 */
 	if (fattr->cf_cifsattrs & ATTR_DIRECTORY) {
-		fattr->cf_mode = S_IFDIR | cifs_sb->mnt_dir_mode;
+		fattr->cf_mode = S_IFDIR | cifs_sb->ctx->dir_mode;
 		fattr->cf_dtype = DT_DIR;
 	} else if (fattr->cf_cifstag == IO_REPARSE_TAG_LX_SYMLINK) {
-		fattr->cf_mode |= S_IFLNK | cifs_sb->mnt_file_mode;
+		fattr->cf_mode |= S_IFLNK | cifs_sb->ctx->file_mode;
 		fattr->cf_dtype = DT_LNK;
 	} else if (fattr->cf_cifstag == IO_REPARSE_TAG_LX_FIFO) {
-		fattr->cf_mode |= S_IFIFO | cifs_sb->mnt_file_mode;
+		fattr->cf_mode |= S_IFIFO | cifs_sb->ctx->file_mode;
 		fattr->cf_dtype = DT_FIFO;
 	} else if (fattr->cf_cifstag == IO_REPARSE_TAG_AF_UNIX) {
-		fattr->cf_mode |= S_IFSOCK | cifs_sb->mnt_file_mode;
+		fattr->cf_mode |= S_IFSOCK | cifs_sb->ctx->file_mode;
 		fattr->cf_dtype = DT_SOCK;
 	} else if (fattr->cf_cifstag == IO_REPARSE_TAG_LX_CHR) {
-		fattr->cf_mode |= S_IFCHR | cifs_sb->mnt_file_mode;
+		fattr->cf_mode |= S_IFCHR | cifs_sb->ctx->file_mode;
 		fattr->cf_dtype = DT_CHR;
 	} else if (fattr->cf_cifstag == IO_REPARSE_TAG_LX_BLK) {
-		fattr->cf_mode |= S_IFBLK | cifs_sb->mnt_file_mode;
+		fattr->cf_mode |= S_IFBLK | cifs_sb->ctx->file_mode;
 		fattr->cf_dtype = DT_BLK;
 	} else { /* TODO: should we mark some other reparse points (like DFSR) as directories? */
-		fattr->cf_mode = S_IFREG | cifs_sb->mnt_file_mode;
+		fattr->cf_mode = S_IFREG | cifs_sb->ctx->file_mode;
 		fattr->cf_dtype = DT_REG;
 	}
 
-- 
2.27.0


^ permalink raw reply related	[flat|nested] 25+ messages in thread

* Re: [PATCH 10/21] cifs: remove actimeo from cifs_sb
  2020-12-07 23:36 ` [PATCH 10/21] cifs: remove actimeo " Ronnie Sahlberg
@ 2020-12-12 19:44   ` Steve French
  0 siblings, 0 replies; 25+ messages in thread
From: Steve French @ 2020-12-12 19:44 UTC (permalink / raw)
  To: Ronnie Sahlberg; +Cc: linux-cifs

tentatively merged into cifs-2.6.gif for-next

On Mon, Dec 7, 2020 at 5:37 PM Ronnie Sahlberg <lsahlber@redhat.com> wrote:
>
> Signed-off-by: Ronnie Sahlberg <lsahlber@redhat.com>
> ---
>  fs/cifs/cifs_fs_sb.h | 1 -
>  fs/cifs/cifsfs.c     | 2 +-
>  fs/cifs/connect.c    | 3 +--
>  fs/cifs/inode.c      | 4 ++--
>  4 files changed, 4 insertions(+), 6 deletions(-)
>
> diff --git a/fs/cifs/cifs_fs_sb.h b/fs/cifs/cifs_fs_sb.h
> index 3f4f1487f714..69d26313d350 100644
> --- a/fs/cifs/cifs_fs_sb.h
> +++ b/fs/cifs/cifs_fs_sb.h
> @@ -65,7 +65,6 @@ struct cifs_sb_info {
>         unsigned int bsize;
>         unsigned int rsize;
>         unsigned int wsize;
> -       unsigned long actimeo; /* attribute cache timeout (jiffies) */
>         atomic_t active;
>         unsigned int mnt_cifs_flags;
>         struct delayed_work prune_tlinks;
> diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
> index 4ea8c3c3bce1..e432de7c6ca1 100644
> --- a/fs/cifs/cifsfs.c
> +++ b/fs/cifs/cifsfs.c
> @@ -629,7 +629,7 @@ cifs_show_options(struct seq_file *s, struct dentry *root)
>         if (tcon->handle_timeout)
>                 seq_printf(s, ",handletimeout=%u", tcon->handle_timeout);
>         /* convert actimeo and display it in seconds */
> -       seq_printf(s, ",actimeo=%lu", cifs_sb->actimeo / HZ);
> +       seq_printf(s, ",actimeo=%lu", cifs_sb->ctx->actimeo / HZ);
>
>         if (tcon->ses->chan_max > 1)
>                 seq_printf(s, ",multichannel,max_channels=%zu",
> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
> index 96c5b66d4b44..47e2fe8c19a2 100644
> --- a/fs/cifs/connect.c
> +++ b/fs/cifs/connect.c
> @@ -2236,7 +2236,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->actimeo != new->actimeo)
> +       if (old->ctx->actimeo != new->ctx->actimeo)
>                 return 0;
>
>         return 1;
> @@ -2682,7 +2682,6 @@ int cifs_setup_cifs_sb(struct smb3_fs_context *ctx,
>         cifs_dbg(FYI, "file mode: %04ho  dir mode: %04ho\n",
>                  cifs_sb->ctx->file_mode, cifs_sb->ctx->dir_mode);
>
> -       cifs_sb->actimeo = ctx->actimeo;
>         cifs_sb->local_nls = ctx->local_nls;
>
>         if (ctx->nodfs)
> diff --git a/fs/cifs/inode.c b/fs/cifs/inode.c
> index e8a7110db2a6..fb07e0828958 100644
> --- a/fs/cifs/inode.c
> +++ b/fs/cifs/inode.c
> @@ -2165,11 +2165,11 @@ cifs_inode_needs_reval(struct inode *inode)
>         if (!lookupCacheEnabled)
>                 return true;
>
> -       if (!cifs_sb->actimeo)
> +       if (!cifs_sb->ctx->actimeo)
>                 return true;
>
>         if (!time_in_range(jiffies, cifs_i->time,
> -                               cifs_i->time + cifs_sb->actimeo))
> +                               cifs_i->time + cifs_sb->ctx->actimeo))
>                 return true;
>
>         /* hardlinked files w/ noserverino get "special" treatment */
> --
> 2.13.6
>


-- 
Thanks,

Steve

^ permalink raw reply	[flat|nested] 25+ messages in thread

end of thread, other threads:[~2020-12-12 19:45 UTC | newest]

Thread overview: 25+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20201207233646.29823-1-lsahlber@redhat.com>
2020-12-07 23:36 ` [PATCH 02/21] cifs: rename dup_vol to smb3_fs_context_dup and move it into fs_context.c Ronnie Sahlberg
2020-12-07 23:36 ` [PATCH 03/21] cifs: move the enum for cifs parameters into fs_context.h Ronnie Sahlberg
2020-12-07 23:36 ` [PATCH 04/21] cifs: move cifs_parse_devname to fs_context.c Ronnie Sahlberg
2020-12-07 23:36 ` [PATCH 05/21] cifs: switch to new mount api Ronnie Sahlberg
2020-12-07 23:36 ` [PATCH 06/21] cifs: remove the devname argument to cifs_compose_mount_options Ronnie Sahlberg
2020-12-07 23:36 ` [PATCH 07/21] cifs: add an smb3_fs_context to cifs_sb Ronnie Sahlberg
2020-12-07 23:36 ` [PATCH 08/21] cifs: get rid of cifs_sb->mountdata Ronnie Sahlberg
2020-12-07 23:36 ` [PATCH 09/21] cifs: remove [gu]id/backup[gu]id/file_mode/dir_mode from cifs_sb Ronnie Sahlberg
2020-12-12 19:42   ` Steve French
2020-12-07 23:36 ` [PATCH 10/21] cifs: remove actimeo " Ronnie Sahlberg
2020-12-12 19:44   ` Steve French
2020-12-07 23:36 ` [PATCH 11/21] cifs: move cifs_cleanup_volume_info[_content] to fs_context.c Ronnie Sahlberg
2020-12-07 23:36 ` [PATCH 12/21] cifs: move [brw]size from cifs_sb to cifs_sb->ctx Ronnie Sahlberg
2020-12-07 23:36 ` [PATCH 13/21] cifs: add initial reconfigure support Ronnie Sahlberg
2020-12-07 23:36 ` [PATCH 14/21] cifs: we do not allow changing username/password/unc/... during remount Ronnie Sahlberg
2020-12-08  5:06   ` Steve French
2020-12-08 18:42     ` Pavel Shilovsky
2020-12-08 21:38       ` ronnie sahlberg
2020-12-07 23:36 ` [PATCH 15/21] cifs: simplify handling of cifs_sb/ctx->local_nls Ronnie Sahlberg
2020-12-07 23:36 ` [PATCH 16/21] cifs: don't create a temp nls in cifs_setup_ipc Ronnie Sahlberg
2020-12-07 23:36 ` [PATCH 17/21] cifs: uncomplicate printing the iocharset parameter Ronnie Sahlberg
2020-12-07 23:36 ` [PATCH 18/21] cifs: do not allow changing posix_paths during remount Ronnie Sahlberg
2020-12-07 23:36 ` [PATCH 19/21] cifs: remove ctx argument from cifs_setup_cifs_sb Ronnie Sahlberg
2020-12-07 23:36 ` [PATCH 20/21] cifs: move update of flags into a separate function Ronnie Sahlberg
2020-12-07 23:36 ` [PATCH 21/21] cifs: update mnt_cifs_flags during reconfigure Ronnie Sahlberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).