Blob Blame History Raw
From: Paulo Alcantara <pc@cjr.nz>
Date: Tue, 11 Oct 2022 18:16:07 -0300
Subject: [PATCH] cifs: split out ses and tcon retrieval from mount_get_conns()
Git-commit: a73a26d97eca082fe13c964e5541543c1e78dc55
References: bsc#1193629
Patch-mainline: v6.2-rc1

Introduce and export two helpers for getting session and tcon during
mount(2).  Those will be used by dfs when retrieving sessions and
tcons separately while chasing referrals.  Besides, export
cifs_mount_ctx structure as it will be used by dfs code as well.

No functional changes.

Signed-off-by: Paulo Alcantara (SUSE) <pc@cjr.nz>
Signed-off-by: Steve French <stfrench@microsoft.com>
Acked-by: Paulo Alcantara <palcantara@suse.de>
---
 fs/cifs/cifsglob.h  |   14 +++++++
 fs/cifs/cifsproto.h |    2 +
 fs/cifs/connect.c   |  101 +++++++++++++++++++++++++++++++---------------------
 3 files changed, 78 insertions(+), 39 deletions(-)

--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -1765,6 +1765,20 @@ struct file_list {
 	struct cifsFileInfo *cfile;
 };
 
+struct cifs_mount_ctx {
+	struct cifs_sb_info *cifs_sb;
+	struct smb3_fs_context *fs_ctx;
+	unsigned int xid;
+	struct TCP_Server_Info *server;
+	struct cifs_ses *ses;
+	struct cifs_tcon *tcon;
+#ifdef CONFIG_CIFS_DFS_UPCALL
+	struct cifs_ses *root_ses;
+	uuid_t mount_id;
+	char *origin_fullpath, *leaf_fullpath;
+#endif
+};
+
 static inline void free_dfs_info_param(struct dfs_info3_param *param)
 {
 	if (param) {
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -238,6 +238,8 @@ extern int cifs_read_page_from_socket(st
 					unsigned int page_offset,
 					unsigned int to_read);
 extern int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb);
+int cifs_mount_get_session(struct cifs_mount_ctx *mnt_ctx);
+int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx);
 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 *);
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -62,20 +62,6 @@ extern bool disable_legacy_dialects;
 /* Drop the connection to not overload the server */
 #define NUM_STATUS_IO_TIMEOUT   5
 
-struct mount_ctx {
-	struct cifs_sb_info *cifs_sb;
-	struct smb3_fs_context *fs_ctx;
-	unsigned int xid;
-	struct TCP_Server_Info *server;
-	struct cifs_ses *ses;
-	struct cifs_tcon *tcon;
-#ifdef CONFIG_CIFS_DFS_UPCALL
-	struct cifs_ses *root_ses;
-	uuid_t mount_id;
-	char *origin_fullpath, *leaf_fullpath;
-#endif
-};
-
 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);
@@ -3191,7 +3177,7 @@ int cifs_setup_cifs_sb(struct cifs_sb_in
 }
 
 /* Release all succeed connections */
-static inline void mount_put_conns(struct mount_ctx *mnt_ctx)
+static inline void mount_put_conns(struct cifs_mount_ctx *mnt_ctx)
 {
 	int rc = 0;
 
@@ -3205,19 +3191,22 @@ static inline void mount_put_conns(struc
 	free_xid(mnt_ctx->xid);
 }
 
-/* Get connections for tcp, ses and tcon */
-static int mount_get_conns(struct mount_ctx *mnt_ctx)
+int cifs_mount_get_session(struct cifs_mount_ctx *mnt_ctx)
 {
-	int rc = 0;
 	struct TCP_Server_Info *server = NULL;
+	struct smb3_fs_context *ctx;
 	struct cifs_ses *ses = NULL;
-	struct cifs_tcon *tcon = NULL;
-	struct smb3_fs_context *ctx = mnt_ctx->fs_ctx;
-	struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb;
 	unsigned int xid;
+	int rc = 0;
 
 	xid = get_xid();
 
+	if (WARN_ON_ONCE(!mnt_ctx || !mnt_ctx->fs_ctx)) {
+		rc = -EINVAL;
+		goto out;
+	}
+	ctx = mnt_ctx->fs_ctx;
+
 	/* get a reference to a tcp session */
 	server = cifs_get_tcp_session(ctx, NULL);
 	if (IS_ERR(server)) {
@@ -3238,11 +3227,36 @@ static int mount_get_conns(struct mount_
 					    SMB2_GLOBAL_CAP_PERSISTENT_HANDLES))) {
 		cifs_server_dbg(VFS, "persistent handles not supported by server\n");
 		rc = -EOPNOTSUPP;
+	}
+
+out:
+	mnt_ctx->xid = xid;
+	mnt_ctx->server = server;
+	mnt_ctx->ses = ses;
+	mnt_ctx->tcon = NULL;
+
+	return rc;
+}
+
+int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx)
+{
+	struct TCP_Server_Info *server;
+	struct cifs_sb_info *cifs_sb;
+	struct smb3_fs_context *ctx;
+	struct cifs_tcon *tcon = NULL;
+	int rc = 0;
+
+	if (WARN_ON_ONCE(!mnt_ctx || !mnt_ctx->server || !mnt_ctx->ses || !mnt_ctx->fs_ctx ||
+			 !mnt_ctx->cifs_sb)) {
+		rc = -EINVAL;
 		goto out;
 	}
+	server = mnt_ctx->server;
+	ctx = mnt_ctx->fs_ctx;
+	cifs_sb = mnt_ctx->cifs_sb;
 
 	/* search for existing tcon to this server share */
-	tcon = cifs_get_tcon(ses, ctx);
+	tcon = cifs_get_tcon(mnt_ctx->ses, ctx);
 	if (IS_ERR(tcon)) {
 		rc = PTR_ERR(tcon);
 		tcon = NULL;
@@ -3260,7 +3274,7 @@ static int mount_get_conns(struct mount_
 		 * reset of caps checks mount to see if unix extensions disabled
 		 * for just this mount.
 		 */
-		reset_cifs_unix_caps(xid, tcon, cifs_sb, ctx);
+		reset_cifs_unix_caps(mnt_ctx->xid, tcon, cifs_sb, ctx);
 		spin_lock(&tcon->ses->server->srv_lock);
 		if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) &&
 		    (le64_to_cpu(tcon->fsUnixInfo.Capability) &
@@ -3276,7 +3290,7 @@ static int mount_get_conns(struct mount_
 
 	/* do not care if a following call succeed - informational */
 	if (!tcon->pipe && server->ops->qfs_tcon) {
-		server->ops->qfs_tcon(xid, tcon, cifs_sb);
+		server->ops->qfs_tcon(mnt_ctx->xid, tcon, cifs_sb);
 		if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) {
 			if (tcon->fsDevInfo.DeviceCharacteristics &
 			    cpu_to_le32(FILE_READ_ONLY_DEVICE))
@@ -3309,14 +3323,22 @@ static int mount_get_conns(struct mount_
 		cifs_fscache_get_super_cookie(tcon);
 
 out:
-	mnt_ctx->server = server;
-	mnt_ctx->ses = ses;
 	mnt_ctx->tcon = tcon;
-	mnt_ctx->xid = xid;
-
 	return rc;
 }
 
+/* Get connections for tcp, ses and tcon */
+static int mount_get_conns(struct cifs_mount_ctx *mnt_ctx)
+{
+	int rc;
+
+	rc = cifs_mount_get_session(mnt_ctx);
+	if (rc)
+		return rc;
+
+	return cifs_mount_get_tcon(mnt_ctx);
+}
+
 static int mount_setup_tlink(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses,
 			     struct cifs_tcon *tcon)
 {
@@ -3345,7 +3367,7 @@ static int mount_setup_tlink(struct cifs
 
 #ifdef CONFIG_CIFS_DFS_UPCALL
 /* Get unique dfs connections */
-static int mount_get_dfs_conns(struct mount_ctx *mnt_ctx)
+static int mount_get_dfs_conns(struct cifs_mount_ctx *mnt_ctx)
 {
 	int rc;
 
@@ -3448,7 +3470,7 @@ cifs_are_all_path_components_accessible(
  *
  * Return -EREMOTE if it is, otherwise 0 or -errno.
  */
-static int is_path_remote(struct mount_ctx *mnt_ctx)
+static int is_path_remote(struct cifs_mount_ctx *mnt_ctx)
 {
 	int rc;
 	struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb;
@@ -3492,7 +3514,7 @@ out:
 }
 
 #ifdef CONFIG_CIFS_DFS_UPCALL
-static void set_root_ses(struct mount_ctx *mnt_ctx)
+static void set_root_ses(struct cifs_mount_ctx *mnt_ctx)
 {
 	if (mnt_ctx->ses) {
 		spin_lock(&cifs_tcp_ses_lock);
@@ -3503,7 +3525,8 @@ static void set_root_ses(struct mount_ct
 	mnt_ctx->root_ses = mnt_ctx->ses;
 }
 
-static int is_dfs_mount(struct mount_ctx *mnt_ctx, bool *isdfs, struct dfs_cache_tgt_list *root_tl)
+static int is_dfs_mount(struct cifs_mount_ctx *mnt_ctx, bool *isdfs,
+			struct dfs_cache_tgt_list *root_tl)
 {
 	int rc;
 	struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb;
@@ -3534,7 +3557,7 @@ static int is_dfs_mount(struct mount_ctx
 	return 0;
 }
 
-static int connect_dfs_target(struct mount_ctx *mnt_ctx, const char *full_path,
+static int connect_dfs_target(struct cifs_mount_ctx *mnt_ctx, const char *full_path,
 			      const char *ref_path, struct dfs_cache_tgt_iterator *tit)
 {
 	int rc;
@@ -3568,7 +3591,7 @@ out:
 	return rc;
 }
 
-static int connect_dfs_root(struct mount_ctx *mnt_ctx, struct dfs_cache_tgt_list *root_tl)
+static int connect_dfs_root(struct cifs_mount_ctx *mnt_ctx, struct dfs_cache_tgt_list *root_tl)
 {
 	int rc;
 	char *full_path;
@@ -3613,7 +3636,7 @@ out:
 	return rc;
 }
 
-static int __follow_dfs_link(struct mount_ctx *mnt_ctx)
+static int __follow_dfs_link(struct cifs_mount_ctx *mnt_ctx)
 {
 	int rc;
 	struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb;
@@ -3662,7 +3685,7 @@ out:
 	return rc;
 }
 
-static int follow_dfs_link(struct mount_ctx *mnt_ctx)
+static int follow_dfs_link(struct cifs_mount_ctx *mnt_ctx)
 {
 	int rc;
 	struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb;
@@ -3695,7 +3718,7 @@ static int follow_dfs_link(struct mount_
 }
 
 /* Set up DFS referral paths for failover */
-static void setup_server_referral_paths(struct mount_ctx *mnt_ctx)
+static void setup_server_referral_paths(struct cifs_mount_ctx *mnt_ctx)
 {
 	struct TCP_Server_Info *server = mnt_ctx->server;
 
@@ -3710,7 +3733,7 @@ static void setup_server_referral_paths(
 int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
 {
 	int rc;
-	struct mount_ctx mnt_ctx = { .cifs_sb = cifs_sb, .fs_ctx = ctx, };
+	struct cifs_mount_ctx mnt_ctx = { .cifs_sb = cifs_sb, .fs_ctx = ctx, };
 	struct dfs_cache_tgt_list tl = DFS_CACHE_TGT_LIST_INIT(tl);
 	bool isdfs;
 
@@ -3770,7 +3793,7 @@ error:
 int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx)
 {
 	int rc = 0;
-	struct mount_ctx mnt_ctx = { .cifs_sb = cifs_sb, .fs_ctx = ctx, };
+	struct cifs_mount_ctx mnt_ctx = { .cifs_sb = cifs_sb, .fs_ctx = ctx, };
 
 	rc = mount_get_conns(&mnt_ctx);
 	if (rc)