summaryrefslogtreecommitdiff
path: root/fs
diff options
context:
space:
mode:
authorPaulo Alcantara <pc@cjr.nz>2022-10-11 18:16:07 -0300
committerSteve French <stfrench@microsoft.com>2022-12-19 08:03:11 -0600
commita73a26d97eca082fe13c964e5541543c1e78dc55 (patch)
tree51efe2befc14dfc395180eaeafa767c1f49664b1 /fs
parent6d740164d8903e6a0e98c30f80fac6af19ce0a21 (diff)
cifs: split out ses and tcon retrieval from mount_get_conns()
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>
Diffstat (limited to 'fs')
-rw-r--r--fs/cifs/cifsglob.h14
-rw-r--r--fs/cifs/cifsproto.h2
-rw-r--r--fs/cifs/connect.c101
3 files changed, 78 insertions, 39 deletions
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index 82f2d3070c26..799e64427fde 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -1760,6 +1760,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) {
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index 4b1f7315ca16..4ae3e8375941 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -242,6 +242,8 @@ extern int cifs_read_page_from_socket(struct TCP_Server_Info *server,
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 *);
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index af386c5f019e..5e465025708d 100644
--- 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_info *cifs_sb)
}
/* 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(struct mount_ctx *mnt_ctx)
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_ctx *mnt_ctx)
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_ctx *mnt_ctx)
* 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_ctx *mnt_ctx)
/* 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_ctx *mnt_ctx)
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_sb_info *cifs_sb, struct cifs_ses *ses,
#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(struct TCP_Server_Info *server,
*
* 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_ctx *mnt_ctx)
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 *mnt_ctx, bool *isdfs, struct dfs_cache
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_ctx *mnt_ctx)
}
/* 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(struct mount_ctx *mnt_ctx)
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)