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>
This commit is contained in:
Paulo Alcantara 2022-10-11 18:16:07 -03:00 committed by Steve French
parent 6d740164d8
commit a73a26d97e
3 changed files with 79 additions and 40 deletions

View File

@ -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) {

View File

@ -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 *);

View File

@ -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;
goto out;
}
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)