@@ -321,49 +321,6 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx)
321321 return rc ;
322322}
323323
324- /* Update dfs referral path of superblock */
325- static int update_server_fullpath (struct TCP_Server_Info * server , struct cifs_sb_info * cifs_sb ,
326- const char * target )
327- {
328- int rc = 0 ;
329- size_t len = strlen (target );
330- char * refpath , * npath ;
331-
332- if (unlikely (len < 2 || * target != '\\' ))
333- return - EINVAL ;
334-
335- if (target [1 ] == '\\' ) {
336- len += 1 ;
337- refpath = kmalloc (len , GFP_KERNEL );
338- if (!refpath )
339- return - ENOMEM ;
340-
341- scnprintf (refpath , len , "%s" , target );
342- } else {
343- len += sizeof ("\\" );
344- refpath = kmalloc (len , GFP_KERNEL );
345- if (!refpath )
346- return - ENOMEM ;
347-
348- scnprintf (refpath , len , "\\%s" , target );
349- }
350-
351- npath = dfs_cache_canonical_path (refpath , cifs_sb -> local_nls , cifs_remap (cifs_sb ));
352- kfree (refpath );
353-
354- if (IS_ERR (npath )) {
355- rc = PTR_ERR (npath );
356- } else {
357- mutex_lock (& server -> refpath_lock );
358- spin_lock (& server -> srv_lock );
359- kfree (server -> leaf_fullpath );
360- server -> leaf_fullpath = npath ;
361- spin_unlock (& server -> srv_lock );
362- mutex_unlock (& server -> refpath_lock );
363- }
364- return rc ;
365- }
366-
367324static int target_share_matches_server (struct TCP_Server_Info * server , char * share ,
368325 bool * target_match )
369326{
@@ -388,77 +345,22 @@ static int target_share_matches_server(struct TCP_Server_Info *server, char *sha
388345 return rc ;
389346}
390347
391- static void __tree_connect_ipc (const unsigned int xid , char * tree ,
392- struct cifs_sb_info * cifs_sb ,
393- struct cifs_ses * ses )
394- {
395- struct TCP_Server_Info * server = ses -> server ;
396- struct cifs_tcon * tcon = ses -> tcon_ipc ;
397- int rc ;
398-
399- spin_lock (& ses -> ses_lock );
400- spin_lock (& ses -> chan_lock );
401- if (cifs_chan_needs_reconnect (ses , server ) ||
402- ses -> ses_status != SES_GOOD ) {
403- spin_unlock (& ses -> chan_lock );
404- spin_unlock (& ses -> ses_lock );
405- cifs_server_dbg (FYI , "%s: skipping ipc reconnect due to disconnected ses\n" ,
406- __func__ );
407- return ;
408- }
409- spin_unlock (& ses -> chan_lock );
410- spin_unlock (& ses -> ses_lock );
411-
412- cifs_server_lock (server );
413- scnprintf (tree , MAX_TREE_SIZE , "\\\\%s\\IPC$" , server -> hostname );
414- cifs_server_unlock (server );
415-
416- rc = server -> ops -> tree_connect (xid , ses , tree , tcon ,
417- cifs_sb -> local_nls );
418- cifs_server_dbg (FYI , "%s: tree_reconnect %s: %d\n" , __func__ , tree , rc );
419- spin_lock (& tcon -> tc_lock );
420- if (rc ) {
421- tcon -> status = TID_NEED_TCON ;
422- } else {
423- tcon -> status = TID_GOOD ;
424- tcon -> need_reconnect = false;
425- }
426- spin_unlock (& tcon -> tc_lock );
427- }
428-
429- static void tree_connect_ipc (const unsigned int xid , char * tree ,
430- struct cifs_sb_info * cifs_sb ,
431- struct cifs_tcon * tcon )
432- {
433- struct cifs_ses * ses = tcon -> ses ;
434-
435- __tree_connect_ipc (xid , tree , cifs_sb , ses );
436- __tree_connect_ipc (xid , tree , cifs_sb , CIFS_DFS_ROOT_SES (ses ));
437- }
438-
439- static int __tree_connect_dfs_target (const unsigned int xid , struct cifs_tcon * tcon ,
440- struct cifs_sb_info * cifs_sb , char * tree , bool islink ,
441- struct dfs_cache_tgt_list * tl )
348+ static int tree_connect_dfs_target (const unsigned int xid ,
349+ struct cifs_tcon * tcon ,
350+ struct cifs_sb_info * cifs_sb ,
351+ char * tree , bool islink ,
352+ struct dfs_cache_tgt_list * tl )
442353{
443- int rc ;
354+ const struct smb_version_operations * ops = tcon -> ses -> server -> ops ;
444355 struct TCP_Server_Info * server = tcon -> ses -> server ;
445- const struct smb_version_operations * ops = server -> ops ;
446- struct cifs_ses * root_ses = CIFS_DFS_ROOT_SES (tcon -> ses );
447- char * share = NULL , * prefix = NULL ;
448356 struct dfs_cache_tgt_iterator * tit ;
357+ char * share = NULL , * prefix = NULL ;
449358 bool target_match ;
450-
451- tit = dfs_cache_get_tgt_iterator (tl );
452- if (!tit ) {
453- rc = - ENOENT ;
454- goto out ;
455- }
359+ int rc = - ENOENT ;
456360
457361 /* Try to tree connect to all dfs targets */
458- for (; tit ; tit = dfs_cache_get_next_tgt (tl , tit )) {
459- const char * target = dfs_cache_get_tgt_name (tit );
460- DFS_CACHE_TGT_LIST (ntl );
461-
362+ for (tit = dfs_cache_get_tgt_iterator (tl );
363+ tit ; tit = dfs_cache_get_next_tgt (tl , tit )) {
462364 kfree (share );
463365 kfree (prefix );
464366 share = prefix = NULL ;
@@ -479,69 +381,16 @@ static int __tree_connect_dfs_target(const unsigned int xid, struct cifs_tcon *t
479381 }
480382
481383 dfs_cache_noreq_update_tgthint (server -> leaf_fullpath + 1 , tit );
482- tree_connect_ipc (xid , tree , cifs_sb , tcon );
483-
484384 scnprintf (tree , MAX_TREE_SIZE , "\\%s" , share );
485- if (!islink ) {
486- rc = ops -> tree_connect (xid , tcon -> ses , tree , tcon , cifs_sb -> local_nls );
487- break ;
488- }
489-
490- /*
491- * If no dfs referrals were returned from link target, then just do a TREE_CONNECT
492- * to it. Otherwise, cache the dfs referral and then mark current tcp ses for
493- * reconnect so either the demultiplex thread or the echo worker will reconnect to
494- * newly resolved target.
495- */
496- if (dfs_cache_find (xid , root_ses , cifs_sb -> local_nls , cifs_remap (cifs_sb ), target ,
497- NULL , & ntl )) {
498- rc = ops -> tree_connect (xid , tcon -> ses , tree , tcon , cifs_sb -> local_nls );
499- if (rc )
500- continue ;
501-
385+ rc = ops -> tree_connect (xid , tcon -> ses , tree ,
386+ tcon , tcon -> ses -> local_nls );
387+ if (islink && !rc && cifs_sb )
502388 rc = cifs_update_super_prepath (cifs_sb , prefix );
503- } else {
504- /* Target is another dfs share */
505- rc = update_server_fullpath (server , cifs_sb , target );
506- dfs_cache_free_tgts (tl );
507-
508- if (!rc ) {
509- rc = - EREMOTE ;
510- list_replace_init (& ntl .tl_list , & tl -> tl_list );
511- } else
512- dfs_cache_free_tgts (& ntl );
513- }
514389 break ;
515390 }
516391
517- out :
518392 kfree (share );
519393 kfree (prefix );
520-
521- return rc ;
522- }
523-
524- static int tree_connect_dfs_target (const unsigned int xid , struct cifs_tcon * tcon ,
525- struct cifs_sb_info * cifs_sb , char * tree , bool islink ,
526- struct dfs_cache_tgt_list * tl )
527- {
528- int rc ;
529- int num_links = 0 ;
530- struct TCP_Server_Info * server = tcon -> ses -> server ;
531- char * old_fullpath = server -> leaf_fullpath ;
532-
533- do {
534- rc = __tree_connect_dfs_target (xid , tcon , cifs_sb , tree , islink , tl );
535- if (!rc || rc != - EREMOTE )
536- break ;
537- } while (rc = - ELOOP , ++ num_links < MAX_NESTED_LINKS );
538- /*
539- * If we couldn't tree connect to any targets from last referral path, then
540- * retry it from newly resolved dfs referral.
541- */
542- if (rc && server -> leaf_fullpath != old_fullpath )
543- cifs_signal_cifsd_for_reconnect (server , true);
544-
545394 dfs_cache_free_tgts (tl );
546395 return rc ;
547396}
@@ -597,14 +446,11 @@ int cifs_tree_connect(const unsigned int xid, struct cifs_tcon *tcon)
597446 if (!IS_ERR (sb ))
598447 cifs_sb = CIFS_SB (sb );
599448
600- /*
601- * Tree connect to last share in @tcon->tree_name whether dfs super or
602- * cached dfs referral was not found.
603- */
604- if (!cifs_sb || !server -> leaf_fullpath ||
449+ /* Tree connect to last share in @tcon->tree_name if no DFS referral */
450+ if (!server -> leaf_fullpath ||
605451 dfs_cache_noreq_find (server -> leaf_fullpath + 1 , & ref , & tl )) {
606- rc = ops -> tree_connect (xid , tcon -> ses , tcon -> tree_name , tcon ,
607- cifs_sb ? cifs_sb -> local_nls : nlsc );
452+ rc = ops -> tree_connect (xid , tcon -> ses , tcon -> tree_name ,
453+ tcon , tcon -> ses -> local_nls );
608454 goto out ;
609455 }
610456
0 commit comments