@@ -811,13 +811,9 @@ cifs_read_iter_from_socket(struct TCP_Server_Info *server, struct iov_iter *iter
811
811
unsigned int to_read )
812
812
{
813
813
struct msghdr smb_msg = { .msg_iter = * iter };
814
- int ret ;
815
814
816
815
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 );
821
817
}
822
818
823
819
static bool
@@ -1530,6 +1526,9 @@ static int match_server(struct TCP_Server_Info *server,
1530
1526
if (server -> nosharesock )
1531
1527
return 0 ;
1532
1528
1529
+ if (!match_super && (ctx -> dfs_conn || server -> dfs_conn ))
1530
+ return 0 ;
1531
+
1533
1532
/* If multidialect negotiation see if existing sessions match one */
1534
1533
if (strcmp (ctx -> vals -> version_string , SMB3ANY_VERSION_STRING ) == 0 ) {
1535
1534
if (server -> vals -> protocol_id < SMB30_PROT_ID )
@@ -1723,6 +1722,7 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
1723
1722
1724
1723
if (ctx -> nosharesock )
1725
1724
tcp_ses -> nosharesock = true;
1725
+ tcp_ses -> dfs_conn = ctx -> dfs_conn ;
1726
1726
1727
1727
tcp_ses -> ops = ctx -> ops ;
1728
1728
tcp_ses -> vals = ctx -> vals ;
@@ -1873,13 +1873,15 @@ cifs_get_tcp_session(struct smb3_fs_context *ctx,
1873
1873
}
1874
1874
1875
1875
/* 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 )
1877
1879
{
1878
1880
if (ctx -> sectype != Unspecified &&
1879
1881
ctx -> sectype != ses -> sectype )
1880
1882
return 0 ;
1881
1883
1882
- if (ctx -> dfs_root_ses != ses -> dfs_root_ses )
1884
+ if (! match_super && ctx -> dfs_root_ses != ses -> dfs_root_ses )
1883
1885
return 0 ;
1884
1886
1885
1887
/*
@@ -1998,7 +2000,7 @@ cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
1998
2000
continue ;
1999
2001
}
2000
2002
spin_lock (& ses -> chan_lock );
2001
- if (match_session (ses , ctx )) {
2003
+ if (match_session (ses , ctx , false )) {
2002
2004
spin_unlock (& ses -> chan_lock );
2003
2005
spin_unlock (& ses -> ses_lock );
2004
2006
ret = ses ;
@@ -2058,8 +2060,7 @@ void __cifs_put_smb_ses(struct cifs_ses *ses)
2058
2060
if (do_logoff ) {
2059
2061
xid = get_xid ();
2060
2062
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" ,
2063
2064
__func__ , rc );
2064
2065
_free_xid (xid );
2065
2066
}
@@ -2382,8 +2383,6 @@ cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb3_fs_context *ctx)
2382
2383
* need to lock before changing something in the session.
2383
2384
*/
2384
2385
spin_lock (& cifs_tcp_ses_lock );
2385
- if (ctx -> dfs_root_ses )
2386
- cifs_smb_ses_inc_refcount (ctx -> dfs_root_ses );
2387
2386
ses -> dfs_root_ses = ctx -> dfs_root_ses ;
2388
2387
list_add (& ses -> smb_ses_list , & server -> smb_ses_list );
2389
2388
spin_unlock (& cifs_tcp_ses_lock );
@@ -2458,6 +2457,7 @@ cifs_put_tcon(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace)
2458
2457
{
2459
2458
unsigned int xid ;
2460
2459
struct cifs_ses * ses ;
2460
+ LIST_HEAD (ses_list );
2461
2461
2462
2462
/*
2463
2463
* 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)
2482
2482
2483
2483
list_del_init (& tcon -> tcon_list );
2484
2484
tcon -> status = TID_EXITING ;
2485
+ #ifdef CONFIG_CIFS_DFS_UPCALL
2486
+ list_replace_init (& tcon -> dfs_ses_list , & ses_list );
2487
+ #endif
2485
2488
spin_unlock (& tcon -> tc_lock );
2486
2489
spin_unlock (& cifs_tcp_ses_lock );
2487
2490
@@ -2509,6 +2512,9 @@ cifs_put_tcon(struct cifs_tcon *tcon, enum smb3_tcon_ref_trace trace)
2509
2512
cifs_fscache_release_super_cookie (tcon );
2510
2513
tconInfoFree (tcon , netfs_trace_tcon_ref_free );
2511
2514
cifs_put_smb_ses (ses );
2515
+ #ifdef CONFIG_CIFS_DFS_UPCALL
2516
+ dfs_put_root_smb_sessions (& ses_list );
2517
+ #endif
2512
2518
}
2513
2519
2514
2520
/**
@@ -2892,7 +2898,7 @@ cifs_match_super(struct super_block *sb, void *data)
2892
2898
spin_lock (& ses -> chan_lock );
2893
2899
spin_lock (& tcon -> tc_lock );
2894
2900
if (!match_server (tcp_srv , ctx , true) ||
2895
- !match_session (ses , ctx ) ||
2901
+ !match_session (ses , ctx , true ) ||
2896
2902
!match_tcon (tcon , ctx ) ||
2897
2903
!match_prepath (sb , tcon , mnt_data )) {
2898
2904
rc = 0 ;
@@ -3623,13 +3629,12 @@ int cifs_is_path_remote(struct cifs_mount_ctx *mnt_ctx)
3623
3629
int cifs_mount (struct cifs_sb_info * cifs_sb , struct smb3_fs_context * ctx )
3624
3630
{
3625
3631
struct cifs_mount_ctx mnt_ctx = { .cifs_sb = cifs_sb , .fs_ctx = ctx , };
3626
- bool isdfs ;
3627
3632
int rc ;
3628
3633
3629
- rc = dfs_mount_share (& mnt_ctx , & isdfs );
3634
+ rc = dfs_mount_share (& mnt_ctx );
3630
3635
if (rc )
3631
3636
goto error ;
3632
- if (!isdfs )
3637
+ if (!ctx -> dfs_conn )
3633
3638
goto out ;
3634
3639
3635
3640
/*
@@ -4034,7 +4039,7 @@ cifs_set_vol_auth(struct smb3_fs_context *ctx, struct cifs_ses *ses)
4034
4039
}
4035
4040
4036
4041
static 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 )
4038
4043
{
4039
4044
int rc ;
4040
4045
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)
4132
4137
return tcon ;
4133
4138
}
4134
4139
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
-
4146
4140
struct cifs_tcon *
4147
4141
cifs_sb_master_tcon (struct cifs_sb_info * cifs_sb )
4148
4142
{
@@ -4212,9 +4206,9 @@ tlink_rb_insert(struct rb_root *root, struct tcon_link *new_tlink)
4212
4206
struct tcon_link *
4213
4207
cifs_sb_tlink (struct cifs_sb_info * cifs_sb )
4214
4208
{
4215
- int ret ;
4216
- kuid_t fsuid = current_fsuid ();
4217
4209
struct tcon_link * tlink , * newtlink ;
4210
+ kuid_t fsuid = current_fsuid ();
4211
+ int err ;
4218
4212
4219
4213
if (!(cifs_sb -> mnt_cifs_flags & CIFS_MOUNT_MULTIUSER ))
4220
4214
return cifs_get_tlink (cifs_sb_master_tlink (cifs_sb ));
@@ -4249,9 +4243,9 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
4249
4243
spin_unlock (& cifs_sb -> tlink_tree_lock );
4250
4244
} else {
4251
4245
wait_for_construction :
4252
- ret = wait_on_bit (& tlink -> tl_flags , TCON_LINK_PENDING ,
4246
+ err = wait_on_bit (& tlink -> tl_flags , TCON_LINK_PENDING ,
4253
4247
TASK_INTERRUPTIBLE );
4254
- if (ret ) {
4248
+ if (err ) {
4255
4249
cifs_put_tlink (tlink );
4256
4250
return ERR_PTR (- ERESTARTSYS );
4257
4251
}
@@ -4262,8 +4256,9 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
4262
4256
4263
4257
/* return error if we tried this already recently */
4264
4258
if (time_before (jiffies , tlink -> tl_time + TLINK_ERROR_EXPIRE )) {
4259
+ err = PTR_ERR (tlink -> tl_tcon );
4265
4260
cifs_put_tlink (tlink );
4266
- return ERR_PTR (- EACCES );
4261
+ return ERR_PTR (err );
4267
4262
}
4268
4263
4269
4264
if (test_and_set_bit (TCON_LINK_PENDING , & tlink -> tl_flags ))
@@ -4275,8 +4270,11 @@ cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
4275
4270
wake_up_bit (& tlink -> tl_flags , TCON_LINK_PENDING );
4276
4271
4277
4272
if (IS_ERR (tlink -> tl_tcon )) {
4273
+ err = PTR_ERR (tlink -> tl_tcon );
4274
+ if (err == - ENOKEY )
4275
+ err = - EACCES ;
4278
4276
cifs_put_tlink (tlink );
4279
- return ERR_PTR (- EACCES );
4277
+ return ERR_PTR (err );
4280
4278
}
4281
4279
4282
4280
return tlink ;
0 commit comments