@@ -811,13 +811,9 @@ cifs_read_iter_from_socket(struct TCP_Server_Info *server, struct iov_iter *iter
811811 unsigned int to_read )
812812{
813813 struct msghdr smb_msg = { .msg_iter = * iter };
814- int ret ;
815814
816815 iov_iter_truncate (& smb_msg .msg_iter , to_read );
817- ret = cifs_readv_from_socket (server , & smb_msg );
818- if (ret > 0 )
819- iov_iter_advance (iter , ret );
820- return ret ;
816+ return cifs_readv_from_socket (server , & smb_msg );
821817}
822818
823819static bool
@@ -1530,6 +1526,9 @@ static int match_server(struct TCP_Server_Info *server,
15301526 if (server -> nosharesock )
15311527 return 0 ;
15321528
1529+ if (!match_super && (ctx -> dfs_conn || server -> dfs_conn ))
1530+ return 0 ;
1531+
15331532 /* If multidialect negotiation see if existing sessions match one */
15341533 if (strcmp (ctx -> vals -> version_string , SMB3ANY_VERSION_STRING ) == 0 ) {
15351534 if (server -> vals -> protocol_id < SMB30_PROT_ID )
@@ -1723,6 +1722,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
17231722
17241723 if (ctx -> nosharesock )
17251724 tcp_ses -> nosharesock = true;
1725+ tcp_ses -> dfs_conn = ctx -> dfs_conn ;
17261726
17271727 tcp_ses -> ops = ctx -> ops ;
17281728 tcp_ses -> vals = ctx -> vals ;
@@ -1873,13 +1873,15 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
18731873}
18741874
18751875/* this function must be called with ses_lock and chan_lock held */
1876- static int match_session (struct cifs_ses * ses , struct smb3_fs_context * ctx )
1876+ static int match_session (struct cifs_ses * ses ,
1877+ struct smb3_fs_context * ctx ,
1878+ bool match_super )
18771879{
18781880 if (ctx -> sectype != Unspecified &&
18791881 ctx -> sectype != ses -> sectype )
18801882 return 0 ;
18811883
1882- if (ctx -> dfs_root_ses != ses -> dfs_root_ses )
1884+ if (! match_super && ctx -> dfs_root_ses != ses -> dfs_root_ses )
18831885 return 0 ;
18841886
18851887 /*
@@ -1998,7 +2000,7 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
19982000 continue ;
19992001 }
20002002 spin_lock (& ses -> chan_lock );
2001- if (match_session (ses , ctx )) {
2003+ if (match_session (ses , ctx , false )) {
20022004 spin_unlock (& ses -> chan_lock );
20032005 spin_unlock (& ses -> ses_lock );
20042006 ret = ses ;
@@ -2058,8 +2060,7 @@ void __cifs_put_smb_ses(struct cifs_ses *ses)
20582060 if (do_logoff ) {
20592061 xid = get_xid ();
20602062 rc = server -> ops -> logoff (xid , ses );
2061- if (rc )
2062- cifs_server_dbg (VFS , "%s: Session Logoff failure rc=%d\n" ,
2063+ cifs_server_dbg (FYI , "%s: Session Logoff: rc=%d\n" ,
20632064 __func__ , rc );
20642065 _free_xid (xid );
20652066 }
@@ -2382,8 +2383,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
23822383 * need to lock before changing something in the session.
23832384 */
23842385 spin_lock (& cifs_tcp_ses_lock );
2385- if (ctx -> dfs_root_ses )
2386- cifs_smb_ses_inc_refcount (ctx -> dfs_root_ses );
23872386 ses -> dfs_root_ses = ctx -> dfs_root_ses ;
23882387 list_add (& ses -> smb_ses_list , & server -> smb_ses_list );
23892388 spin_unlock (& cifs_tcp_ses_lock );
@@ -2458,6 +2457,7 @@ cifs_put_tcon(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace)
24582457{
24592458 unsigned int xid ;
24602459 struct cifs_ses * ses ;
2460+ LIST_HEAD (ses_list );
24612461
24622462 /*
24632463 * IPC tcon share the lifetime of their session and are
@@ -2482,6 +2482,9 @@ cifs_put_tcon(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace)
24822482
24832483 list_del_init (& tcon -> tcon_list );
24842484 tcon -> status = TID_EXITING ;
2485+ #ifdef CONFIG_CIFS_DFS_UPCALL
2486+ list_replace_init (& tcon -> dfs_ses_list , & ses_list );
2487+ #endif
24852488 spin_unlock (& tcon -> tc_lock );
24862489 spin_unlock (& cifs_tcp_ses_lock );
24872490
@@ -2509,6 +2512,9 @@ cifs_put_tcon(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace)
25092512 cifs_fscache_release_super_cookie (tcon );
25102513 tconInfoFree (tcon , netfs_trace_tcon_ref_free );
25112514 cifs_put_smb_ses (ses );
2515+ #ifdef CONFIG_CIFS_DFS_UPCALL
2516+ dfs_put_root_smb_sessions (& ses_list );
2517+ #endif
25122518}
25132519
25142520/**
@@ -2892,7 +2898,7 @@ cifs_match_super(struct super_block *sb, void *data)
28922898 spin_lock (& ses -> chan_lock );
28932899 spin_lock (& tcon -> tc_lock );
28942900 if (!match_server (tcp_srv , ctx , true) ||
2895- !match_session (ses , ctx ) ||
2901+ !match_session (ses , ctx , true ) ||
28962902 !match_tcon (tcon , ctx ) ||
28972903 !match_prepath (sb , tcon , mnt_data )) {
28982904 rc = 0 ;
@@ -3623,13 +3629,12 @@ int cifs_is_path_remote(struct cifs_mount_ctx *mnt_ctx)
36233629int cifs_mount (struct cifs_sb_info * cifs_sb , struct smb3_fs_context * ctx )
36243630{
36253631 struct cifs_mount_ctx mnt_ctx = { .cifs_sb = cifs_sb , .fs_ctx = ctx , };
3626- bool isdfs ;
36273632 int rc ;
36283633
3629- rc = dfs_mount_share (& mnt_ctx , & isdfs );
3634+ rc = dfs_mount_share (& mnt_ctx );
36303635 if (rc )
36313636 goto error ;
3632- if (!isdfs )
3637+ if (!ctx -> dfs_conn )
36333638 goto out ;
36343639
36353640 /*
@@ -4034,7 +4039,7 @@ cifs_set_vol_auth(struct smb3_fs_context *ctx, struct cifs_ses *ses)
40344039}
40354040
40364041static struct cifs_tcon *
4037- __cifs_construct_tcon (struct cifs_sb_info * cifs_sb , kuid_t fsuid )
4042+ cifs_construct_tcon (struct cifs_sb_info * cifs_sb , kuid_t fsuid )
40384043{
40394044 int rc ;
40404045 struct cifs_tcon * master_tcon = cifs_sb_master_tcon (cifs_sb );
@@ -4132,17 +4137,6 @@ __cifs_construct_tcon(struct cifs_sb_info *cifs_sb, kuid_t fsuid)
41324137 return tcon ;
41334138}
41344139
4135- static struct cifs_tcon *
4136- cifs_construct_tcon (struct cifs_sb_info * cifs_sb , kuid_t fsuid )
4137- {
4138- struct cifs_tcon * ret ;
4139-
4140- cifs_mount_lock ();
4141- ret = __cifs_construct_tcon (cifs_sb , fsuid );
4142- cifs_mount_unlock ();
4143- return ret ;
4144- }
4145-
41464140struct cifs_tcon *
41474141cifs_sb_master_tcon (struct cifs_sb_info * cifs_sb )
41484142{
@@ -4212,9 +4206,9 @@ tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink)
42124206struct tcon_link *
42134207cifs_sb_tlink (struct cifs_sb_info * cifs_sb )
42144208{
4215- int ret ;
4216- kuid_t fsuid = current_fsuid ();
42174209 struct tcon_link * tlink , * newtlink ;
4210+ kuid_t fsuid = current_fsuid ();
4211+ int err ;
42184212
42194213 if (!(cifs_sb -> mnt_cifs_flags & CIFS_MOUNT_MULTIUSER ))
42204214 return cifs_get_tlink (cifs_sb_master_tlink (cifs_sb ));
@@ -4249,9 +4243,9 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
42494243 spin_unlock (& cifs_sb -> tlink_tree_lock );
42504244 } else {
42514245wait_for_construction :
4252- ret = wait_on_bit (& tlink -> tl_flags , TCON_LINK_PENDING ,
4246+ err = wait_on_bit (& tlink -> tl_flags , TCON_LINK_PENDING ,
42534247 TASK_INTERRUPTIBLE );
4254- if (ret ) {
4248+ if (err ) {
42554249 cifs_put_tlink (tlink );
42564250 return ERR_PTR (- ERESTARTSYS );
42574251 }
@@ -4262,8 +4256,9 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
42624256
42634257 /* return error if we tried this already recently */
42644258 if (time_before (jiffies , tlink -> tl_time + TLINK_ERROR_EXPIRE )) {
4259+ err = PTR_ERR (tlink -> tl_tcon );
42654260 cifs_put_tlink (tlink );
4266- return ERR_PTR (- EACCES );
4261+ return ERR_PTR (err );
42674262 }
42684263
42694264 if (test_and_set_bit (TCON_LINK_PENDING , & tlink -> tl_flags ))
@@ -4275,8 +4270,11 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
42754270 wake_up_bit (& tlink -> tl_flags , TCON_LINK_PENDING );
42764271
42774272 if (IS_ERR (tlink -> tl_tcon )) {
4273+ err = PTR_ERR (tlink -> tl_tcon );
4274+ if (err == - ENOKEY )
4275+ err = - EACCES ;
42784276 cifs_put_tlink (tlink );
4279- return ERR_PTR (- EACCES );
4277+ return ERR_PTR (err );
42804278 }
42814279
42824280 return tlink ;
0 commit comments