Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Paulo Alcantara and committed by
Steve French
a73a26d9 6d740164

+79 -40
+14
fs/cifs/cifsglob.h
··· 1760 1760 struct cifsFileInfo *cfile; 1761 1761 }; 1762 1762 1763 + struct cifs_mount_ctx { 1764 + struct cifs_sb_info *cifs_sb; 1765 + struct smb3_fs_context *fs_ctx; 1766 + unsigned int xid; 1767 + struct TCP_Server_Info *server; 1768 + struct cifs_ses *ses; 1769 + struct cifs_tcon *tcon; 1770 + #ifdef CONFIG_CIFS_DFS_UPCALL 1771 + struct cifs_ses *root_ses; 1772 + uuid_t mount_id; 1773 + char *origin_fullpath, *leaf_fullpath; 1774 + #endif 1775 + }; 1776 + 1763 1777 static inline void free_dfs_info_param(struct dfs_info3_param *param) 1764 1778 { 1765 1779 if (param) {
+2
fs/cifs/cifsproto.h
··· 242 242 unsigned int page_offset, 243 243 unsigned int to_read); 244 244 extern int cifs_setup_cifs_sb(struct cifs_sb_info *cifs_sb); 245 + int cifs_mount_get_session(struct cifs_mount_ctx *mnt_ctx); 246 + int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx); 245 247 extern int cifs_match_super(struct super_block *, void *); 246 248 extern int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx); 247 249 extern void cifs_umount(struct cifs_sb_info *);
+63 -40
fs/cifs/connect.c
··· 62 62 /* Drop the connection to not overload the server */ 63 63 #define NUM_STATUS_IO_TIMEOUT 5 64 64 65 - struct mount_ctx { 66 - struct cifs_sb_info *cifs_sb; 67 - struct smb3_fs_context *fs_ctx; 68 - unsigned int xid; 69 - struct TCP_Server_Info *server; 70 - struct cifs_ses *ses; 71 - struct cifs_tcon *tcon; 72 - #ifdef CONFIG_CIFS_DFS_UPCALL 73 - struct cifs_ses *root_ses; 74 - uuid_t mount_id; 75 - char *origin_fullpath, *leaf_fullpath; 76 - #endif 77 - }; 78 - 79 65 static int ip_connect(struct TCP_Server_Info *server); 80 66 static int generic_ip_connect(struct TCP_Server_Info *server); 81 67 static void tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink); ··· 3177 3191 } 3178 3192 3179 3193 /* Release all succeed connections */ 3180 - static inline void mount_put_conns(struct mount_ctx *mnt_ctx) 3194 + static inline void mount_put_conns(struct cifs_mount_ctx *mnt_ctx) 3181 3195 { 3182 3196 int rc = 0; 3183 3197 ··· 3191 3205 free_xid(mnt_ctx->xid); 3192 3206 } 3193 3207 3194 - /* Get connections for tcp, ses and tcon */ 3195 - static int mount_get_conns(struct mount_ctx *mnt_ctx) 3208 + int cifs_mount_get_session(struct cifs_mount_ctx *mnt_ctx) 3196 3209 { 3197 - int rc = 0; 3198 3210 struct TCP_Server_Info *server = NULL; 3211 + struct smb3_fs_context *ctx; 3199 3212 struct cifs_ses *ses = NULL; 3200 - struct cifs_tcon *tcon = NULL; 3201 - struct smb3_fs_context *ctx = mnt_ctx->fs_ctx; 3202 - struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb; 3203 3213 unsigned int xid; 3214 + int rc = 0; 3204 3215 3205 3216 xid = get_xid(); 3217 + 3218 + if (WARN_ON_ONCE(!mnt_ctx || !mnt_ctx->fs_ctx)) { 3219 + rc = -EINVAL; 3220 + goto out; 3221 + } 3222 + ctx = mnt_ctx->fs_ctx; 3206 3223 3207 3224 /* get a reference to a tcp session */ 3208 3225 server = cifs_get_tcp_session(ctx, NULL); ··· 3227 3238 SMB2_GLOBAL_CAP_PERSISTENT_HANDLES))) { 3228 3239 cifs_server_dbg(VFS, "persistent handles not supported by server\n"); 3229 3240 rc = -EOPNOTSUPP; 3230 - goto out; 3231 3241 } 3232 3242 3243 + out: 3244 + mnt_ctx->xid = xid; 3245 + mnt_ctx->server = server; 3246 + mnt_ctx->ses = ses; 3247 + mnt_ctx->tcon = NULL; 3248 + 3249 + return rc; 3250 + } 3251 + 3252 + int cifs_mount_get_tcon(struct cifs_mount_ctx *mnt_ctx) 3253 + { 3254 + struct TCP_Server_Info *server; 3255 + struct cifs_sb_info *cifs_sb; 3256 + struct smb3_fs_context *ctx; 3257 + struct cifs_tcon *tcon = NULL; 3258 + int rc = 0; 3259 + 3260 + if (WARN_ON_ONCE(!mnt_ctx || !mnt_ctx->server || !mnt_ctx->ses || !mnt_ctx->fs_ctx || 3261 + !mnt_ctx->cifs_sb)) { 3262 + rc = -EINVAL; 3263 + goto out; 3264 + } 3265 + server = mnt_ctx->server; 3266 + ctx = mnt_ctx->fs_ctx; 3267 + cifs_sb = mnt_ctx->cifs_sb; 3268 + 3233 3269 /* search for existing tcon to this server share */ 3234 - tcon = cifs_get_tcon(ses, ctx); 3270 + tcon = cifs_get_tcon(mnt_ctx->ses, ctx); 3235 3271 if (IS_ERR(tcon)) { 3236 3272 rc = PTR_ERR(tcon); 3237 3273 tcon = NULL; ··· 3274 3260 * reset of caps checks mount to see if unix extensions disabled 3275 3261 * for just this mount. 3276 3262 */ 3277 - reset_cifs_unix_caps(xid, tcon, cifs_sb, ctx); 3263 + reset_cifs_unix_caps(mnt_ctx->xid, tcon, cifs_sb, ctx); 3278 3264 spin_lock(&tcon->ses->server->srv_lock); 3279 3265 if ((tcon->ses->server->tcpStatus == CifsNeedReconnect) && 3280 3266 (le64_to_cpu(tcon->fsUnixInfo.Capability) & ··· 3290 3276 3291 3277 /* do not care if a following call succeed - informational */ 3292 3278 if (!tcon->pipe && server->ops->qfs_tcon) { 3293 - server->ops->qfs_tcon(xid, tcon, cifs_sb); 3279 + server->ops->qfs_tcon(mnt_ctx->xid, tcon, cifs_sb); 3294 3280 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_RO_CACHE) { 3295 3281 if (tcon->fsDevInfo.DeviceCharacteristics & 3296 3282 cpu_to_le32(FILE_READ_ONLY_DEVICE)) ··· 3323 3309 cifs_fscache_get_super_cookie(tcon); 3324 3310 3325 3311 out: 3326 - mnt_ctx->server = server; 3327 - mnt_ctx->ses = ses; 3328 3312 mnt_ctx->tcon = tcon; 3329 - mnt_ctx->xid = xid; 3330 - 3331 3313 return rc; 3314 + } 3315 + 3316 + /* Get connections for tcp, ses and tcon */ 3317 + static int mount_get_conns(struct cifs_mount_ctx *mnt_ctx) 3318 + { 3319 + int rc; 3320 + 3321 + rc = cifs_mount_get_session(mnt_ctx); 3322 + if (rc) 3323 + return rc; 3324 + 3325 + return cifs_mount_get_tcon(mnt_ctx); 3332 3326 } 3333 3327 3334 3328 static int mount_setup_tlink(struct cifs_sb_info *cifs_sb, struct cifs_ses *ses, ··· 3367 3345 3368 3346 #ifdef CONFIG_CIFS_DFS_UPCALL 3369 3347 /* Get unique dfs connections */ 3370 - static int mount_get_dfs_conns(struct mount_ctx *mnt_ctx) 3348 + static int mount_get_dfs_conns(struct cifs_mount_ctx *mnt_ctx) 3371 3349 { 3372 3350 int rc; 3373 3351 ··· 3470 3448 * 3471 3449 * Return -EREMOTE if it is, otherwise 0 or -errno. 3472 3450 */ 3473 - static int is_path_remote(struct mount_ctx *mnt_ctx) 3451 + static int is_path_remote(struct cifs_mount_ctx *mnt_ctx) 3474 3452 { 3475 3453 int rc; 3476 3454 struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb; ··· 3514 3492 } 3515 3493 3516 3494 #ifdef CONFIG_CIFS_DFS_UPCALL 3517 - static void set_root_ses(struct mount_ctx *mnt_ctx) 3495 + static void set_root_ses(struct cifs_mount_ctx *mnt_ctx) 3518 3496 { 3519 3497 if (mnt_ctx->ses) { 3520 3498 spin_lock(&cifs_tcp_ses_lock); ··· 3525 3503 mnt_ctx->root_ses = mnt_ctx->ses; 3526 3504 } 3527 3505 3528 - static int is_dfs_mount(struct mount_ctx *mnt_ctx, bool *isdfs, struct dfs_cache_tgt_list *root_tl) 3506 + static int is_dfs_mount(struct cifs_mount_ctx *mnt_ctx, bool *isdfs, 3507 + struct dfs_cache_tgt_list *root_tl) 3529 3508 { 3530 3509 int rc; 3531 3510 struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb; ··· 3557 3534 return 0; 3558 3535 } 3559 3536 3560 - static int connect_dfs_target(struct mount_ctx *mnt_ctx, const char *full_path, 3537 + static int connect_dfs_target(struct cifs_mount_ctx *mnt_ctx, const char *full_path, 3561 3538 const char *ref_path, struct dfs_cache_tgt_iterator *tit) 3562 3539 { 3563 3540 int rc; ··· 3591 3568 return rc; 3592 3569 } 3593 3570 3594 - static int connect_dfs_root(struct mount_ctx *mnt_ctx, struct dfs_cache_tgt_list *root_tl) 3571 + static int connect_dfs_root(struct cifs_mount_ctx *mnt_ctx, struct dfs_cache_tgt_list *root_tl) 3595 3572 { 3596 3573 int rc; 3597 3574 char *full_path; ··· 3636 3613 return rc; 3637 3614 } 3638 3615 3639 - static int __follow_dfs_link(struct mount_ctx *mnt_ctx) 3616 + static int __follow_dfs_link(struct cifs_mount_ctx *mnt_ctx) 3640 3617 { 3641 3618 int rc; 3642 3619 struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb; ··· 3685 3662 return rc; 3686 3663 } 3687 3664 3688 - static int follow_dfs_link(struct mount_ctx *mnt_ctx) 3665 + static int follow_dfs_link(struct cifs_mount_ctx *mnt_ctx) 3689 3666 { 3690 3667 int rc; 3691 3668 struct cifs_sb_info *cifs_sb = mnt_ctx->cifs_sb; ··· 3718 3695 } 3719 3696 3720 3697 /* Set up DFS referral paths for failover */ 3721 - static void setup_server_referral_paths(struct mount_ctx *mnt_ctx) 3698 + static void setup_server_referral_paths(struct cifs_mount_ctx *mnt_ctx) 3722 3699 { 3723 3700 struct TCP_Server_Info *server = mnt_ctx->server; 3724 3701 ··· 3733 3710 int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx) 3734 3711 { 3735 3712 int rc; 3736 - struct mount_ctx mnt_ctx = { .cifs_sb = cifs_sb, .fs_ctx = ctx, }; 3713 + struct cifs_mount_ctx mnt_ctx = { .cifs_sb = cifs_sb, .fs_ctx = ctx, }; 3737 3714 struct dfs_cache_tgt_list tl = DFS_CACHE_TGT_LIST_INIT(tl); 3738 3715 bool isdfs; 3739 3716 ··· 3793 3770 int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb3_fs_context *ctx) 3794 3771 { 3795 3772 int rc = 0; 3796 - struct mount_ctx mnt_ctx = { .cifs_sb = cifs_sb, .fs_ctx = ctx, }; 3773 + struct cifs_mount_ctx mnt_ctx = { .cifs_sb = cifs_sb, .fs_ctx = ctx, }; 3797 3774 3798 3775 rc = mount_get_conns(&mnt_ctx); 3799 3776 if (rc)