@@ -529,9 +529,7 @@ static int reconnect_dfs_server(struct TCP_Server_Info *server)
529
529
mod_delayed_work (cifsiod_wq , & server -> reconnect , 0 );
530
530
} while (server -> tcpStatus == CifsNeedReconnect );
531
531
532
- if (target_hint )
533
- dfs_cache_noreq_update_tgthint (refpath , target_hint );
534
-
532
+ dfs_cache_noreq_update_tgthint (refpath , target_hint );
535
533
dfs_cache_free_tgts (& tl );
536
534
537
535
/* Need to set up echo worker again once connection has been established */
@@ -4079,265 +4077,7 @@ cifs_prune_tlinks(struct work_struct *work)
4079
4077
TLINK_IDLE_EXPIRE );
4080
4078
}
4081
4079
4082
- #ifdef CONFIG_CIFS_DFS_UPCALL
4083
- /* Update dfs referral path of superblock */
4084
- static int update_server_fullpath (struct TCP_Server_Info * server , struct cifs_sb_info * cifs_sb ,
4085
- const char * target )
4086
- {
4087
- int rc = 0 ;
4088
- size_t len = strlen (target );
4089
- char * refpath , * npath ;
4090
-
4091
- if (unlikely (len < 2 || * target != '\\' ))
4092
- return - EINVAL ;
4093
-
4094
- if (target [1 ] == '\\' ) {
4095
- len += 1 ;
4096
- refpath = kmalloc (len , GFP_KERNEL );
4097
- if (!refpath )
4098
- return - ENOMEM ;
4099
-
4100
- scnprintf (refpath , len , "%s" , target );
4101
- } else {
4102
- len += sizeof ("\\" );
4103
- refpath = kmalloc (len , GFP_KERNEL );
4104
- if (!refpath )
4105
- return - ENOMEM ;
4106
-
4107
- scnprintf (refpath , len , "\\%s" , target );
4108
- }
4109
-
4110
- npath = dfs_cache_canonical_path (refpath , cifs_sb -> local_nls , cifs_remap (cifs_sb ));
4111
- kfree (refpath );
4112
-
4113
- if (IS_ERR (npath )) {
4114
- rc = PTR_ERR (npath );
4115
- } else {
4116
- mutex_lock (& server -> refpath_lock );
4117
- kfree (server -> leaf_fullpath );
4118
- server -> leaf_fullpath = npath ;
4119
- mutex_unlock (& server -> refpath_lock );
4120
- server -> current_fullpath = server -> leaf_fullpath ;
4121
- }
4122
- return rc ;
4123
- }
4124
-
4125
- static int target_share_matches_server (struct TCP_Server_Info * server , const char * tcp_host ,
4126
- size_t tcp_host_len , char * share , bool * target_match )
4127
- {
4128
- int rc = 0 ;
4129
- const char * dfs_host ;
4130
- size_t dfs_host_len ;
4131
-
4132
- * target_match = true;
4133
- extract_unc_hostname (share , & dfs_host , & dfs_host_len );
4134
-
4135
- /* Check if hostnames or addresses match */
4136
- if (dfs_host_len != tcp_host_len || strncasecmp (dfs_host , tcp_host , dfs_host_len ) != 0 ) {
4137
- cifs_dbg (FYI , "%s: %.*s doesn't match %.*s\n" , __func__ , (int )dfs_host_len ,
4138
- dfs_host , (int )tcp_host_len , tcp_host );
4139
- rc = match_target_ip (server , dfs_host , dfs_host_len , target_match );
4140
- if (rc )
4141
- cifs_dbg (VFS , "%s: failed to match target ip: %d\n" , __func__ , rc );
4142
- }
4143
- return rc ;
4144
- }
4145
-
4146
- static int __tree_connect_dfs_target (const unsigned int xid , struct cifs_tcon * tcon ,
4147
- struct cifs_sb_info * cifs_sb , char * tree , bool islink ,
4148
- struct dfs_cache_tgt_list * tl )
4149
- {
4150
- int rc ;
4151
- struct TCP_Server_Info * server = tcon -> ses -> server ;
4152
- const struct smb_version_operations * ops = server -> ops ;
4153
- struct cifs_ses * root_ses = CIFS_DFS_ROOT_SES (tcon -> ses );
4154
- struct cifs_tcon * ipc = root_ses -> tcon_ipc ;
4155
- char * share = NULL , * prefix = NULL ;
4156
- const char * tcp_host ;
4157
- size_t tcp_host_len ;
4158
- struct dfs_cache_tgt_iterator * tit ;
4159
- bool target_match ;
4160
-
4161
- extract_unc_hostname (server -> hostname , & tcp_host , & tcp_host_len );
4162
-
4163
- tit = dfs_cache_get_tgt_iterator (tl );
4164
- if (!tit ) {
4165
- rc = - ENOENT ;
4166
- goto out ;
4167
- }
4168
-
4169
- /* Try to tree connect to all dfs targets */
4170
- for (; tit ; tit = dfs_cache_get_next_tgt (tl , tit )) {
4171
- const char * target = dfs_cache_get_tgt_name (tit );
4172
- struct dfs_cache_tgt_list ntl = DFS_CACHE_TGT_LIST_INIT (ntl );
4173
-
4174
- kfree (share );
4175
- kfree (prefix );
4176
- share = prefix = NULL ;
4177
-
4178
- /* Check if share matches with tcp ses */
4179
- rc = dfs_cache_get_tgt_share (server -> current_fullpath + 1 , tit , & share , & prefix );
4180
- if (rc ) {
4181
- cifs_dbg (VFS , "%s: failed to parse target share: %d\n" , __func__ , rc );
4182
- break ;
4183
- }
4184
-
4185
- rc = target_share_matches_server (server , tcp_host , tcp_host_len , share ,
4186
- & target_match );
4187
- if (rc )
4188
- break ;
4189
- if (!target_match ) {
4190
- rc = - EHOSTUNREACH ;
4191
- continue ;
4192
- }
4193
-
4194
- if (ipc -> need_reconnect ) {
4195
- scnprintf (tree , MAX_TREE_SIZE , "\\\\%s\\IPC$" , server -> hostname );
4196
- rc = ops -> tree_connect (xid , ipc -> ses , tree , ipc , cifs_sb -> local_nls );
4197
- if (rc )
4198
- break ;
4199
- }
4200
-
4201
- scnprintf (tree , MAX_TREE_SIZE , "\\%s" , share );
4202
- if (!islink ) {
4203
- rc = ops -> tree_connect (xid , tcon -> ses , tree , tcon , cifs_sb -> local_nls );
4204
- break ;
4205
- }
4206
- /*
4207
- * If no dfs referrals were returned from link target, then just do a TREE_CONNECT
4208
- * to it. Otherwise, cache the dfs referral and then mark current tcp ses for
4209
- * reconnect so either the demultiplex thread or the echo worker will reconnect to
4210
- * newly resolved target.
4211
- */
4212
- if (dfs_cache_find (xid , root_ses , cifs_sb -> local_nls , cifs_remap (cifs_sb ), target ,
4213
- NULL , & ntl )) {
4214
- rc = ops -> tree_connect (xid , tcon -> ses , tree , tcon , cifs_sb -> local_nls );
4215
- if (rc )
4216
- continue ;
4217
- rc = dfs_cache_noreq_update_tgthint (server -> current_fullpath + 1 , tit );
4218
- if (!rc )
4219
- rc = cifs_update_super_prepath (cifs_sb , prefix );
4220
- } else {
4221
- /* Target is another dfs share */
4222
- rc = update_server_fullpath (server , cifs_sb , target );
4223
- dfs_cache_free_tgts (tl );
4224
-
4225
- if (!rc ) {
4226
- rc = - EREMOTE ;
4227
- list_replace_init (& ntl .tl_list , & tl -> tl_list );
4228
- } else
4229
- dfs_cache_free_tgts (& ntl );
4230
- }
4231
- break ;
4232
- }
4233
-
4234
- out :
4235
- kfree (share );
4236
- kfree (prefix );
4237
-
4238
- return rc ;
4239
- }
4240
-
4241
- static int tree_connect_dfs_target (const unsigned int xid , struct cifs_tcon * tcon ,
4242
- struct cifs_sb_info * cifs_sb , char * tree , bool islink ,
4243
- struct dfs_cache_tgt_list * tl )
4244
- {
4245
- int rc ;
4246
- int num_links = 0 ;
4247
- struct TCP_Server_Info * server = tcon -> ses -> server ;
4248
-
4249
- do {
4250
- rc = __tree_connect_dfs_target (xid , tcon , cifs_sb , tree , islink , tl );
4251
- if (!rc || rc != - EREMOTE )
4252
- break ;
4253
- } while (rc = - ELOOP , ++ num_links < MAX_NESTED_LINKS );
4254
- /*
4255
- * If we couldn't tree connect to any targets from last referral path, then retry from
4256
- * original referral path.
4257
- */
4258
- if (rc && server -> current_fullpath != server -> origin_fullpath ) {
4259
- server -> current_fullpath = server -> origin_fullpath ;
4260
- cifs_signal_cifsd_for_reconnect (server , true);
4261
- }
4262
-
4263
- dfs_cache_free_tgts (tl );
4264
- return rc ;
4265
- }
4266
-
4267
- int cifs_tree_connect (const unsigned int xid , struct cifs_tcon * tcon , const struct nls_table * nlsc )
4268
- {
4269
- int rc ;
4270
- struct TCP_Server_Info * server = tcon -> ses -> server ;
4271
- const struct smb_version_operations * ops = server -> ops ;
4272
- struct super_block * sb = NULL ;
4273
- struct cifs_sb_info * cifs_sb ;
4274
- struct dfs_cache_tgt_list tl = DFS_CACHE_TGT_LIST_INIT (tl );
4275
- char * tree ;
4276
- struct dfs_info3_param ref = {0 };
4277
-
4278
- /* only send once per connect */
4279
- spin_lock (& tcon -> tc_lock );
4280
- if (tcon -> ses -> ses_status != SES_GOOD ||
4281
- (tcon -> status != TID_NEW &&
4282
- tcon -> status != TID_NEED_TCON )) {
4283
- spin_unlock (& tcon -> tc_lock );
4284
- return 0 ;
4285
- }
4286
- tcon -> status = TID_IN_TCON ;
4287
- spin_unlock (& tcon -> tc_lock );
4288
-
4289
- tree = kzalloc (MAX_TREE_SIZE , GFP_KERNEL );
4290
- if (!tree ) {
4291
- rc = - ENOMEM ;
4292
- goto out ;
4293
- }
4294
-
4295
- if (tcon -> ipc ) {
4296
- scnprintf (tree , MAX_TREE_SIZE , "\\\\%s\\IPC$" , server -> hostname );
4297
- rc = ops -> tree_connect (xid , tcon -> ses , tree , tcon , nlsc );
4298
- goto out ;
4299
- }
4300
-
4301
- sb = cifs_get_tcp_super (server );
4302
- if (IS_ERR (sb )) {
4303
- rc = PTR_ERR (sb );
4304
- cifs_dbg (VFS , "%s: could not find superblock: %d\n" , __func__ , rc );
4305
- goto out ;
4306
- }
4307
-
4308
- cifs_sb = CIFS_SB (sb );
4309
-
4310
- /* If it is not dfs or there was no cached dfs referral, then reconnect to same share */
4311
- if (!server -> current_fullpath ||
4312
- dfs_cache_noreq_find (server -> current_fullpath + 1 , & ref , & tl )) {
4313
- rc = ops -> tree_connect (xid , tcon -> ses , tcon -> tree_name , tcon , cifs_sb -> local_nls );
4314
- goto out ;
4315
- }
4316
-
4317
- rc = tree_connect_dfs_target (xid , tcon , cifs_sb , tree , ref .server_type == DFS_TYPE_LINK ,
4318
- & tl );
4319
- free_dfs_info_param (& ref );
4320
-
4321
- out :
4322
- kfree (tree );
4323
- cifs_put_tcp_super (sb );
4324
-
4325
- if (rc ) {
4326
- spin_lock (& tcon -> tc_lock );
4327
- if (tcon -> status == TID_IN_TCON )
4328
- tcon -> status = TID_NEED_TCON ;
4329
- spin_unlock (& tcon -> tc_lock );
4330
- } else {
4331
- spin_lock (& tcon -> tc_lock );
4332
- if (tcon -> status == TID_IN_TCON )
4333
- tcon -> status = TID_GOOD ;
4334
- spin_unlock (& tcon -> tc_lock );
4335
- tcon -> need_reconnect = false;
4336
- }
4337
-
4338
- return rc ;
4339
- }
4340
- #else
4080
+ #ifndef CONFIG_CIFS_DFS_UPCALL
4341
4081
int cifs_tree_connect (const unsigned int xid , struct cifs_tcon * tcon , const struct nls_table * nlsc )
4342
4082
{
4343
4083
int rc ;
0 commit comments