@@ -2972,17 +2972,20 @@ expand_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
29722972 rc = dfs_cache_find (xid , ses , cifs_sb -> local_nls , cifs_remap (cifs_sb ),
29732973 ref_path , & referral , NULL );
29742974 if (!rc ) {
2975+ char * fake_devname = NULL ;
2976+
29752977 mdata = cifs_compose_mount_options (cifs_sb -> ctx -> mount_options ,
2976- full_path + 1 , & referral );
2978+ full_path + 1 , & referral ,
2979+ & fake_devname );
29772980 free_dfs_info_param (& referral );
29782981
29792982 if (IS_ERR (mdata )) {
29802983 rc = PTR_ERR (mdata );
29812984 mdata = NULL ;
29822985 } else {
2983- smb3_cleanup_fs_context_contents (ctx );
2984- rc = cifs_setup_volume_info (ctx );
2986+ rc = cifs_setup_volume_info (ctx , mdata , fake_devname );
29852987 }
2988+ kfree (fake_devname );
29862989 kfree (cifs_sb -> ctx -> mount_options );
29872990 cifs_sb -> ctx -> mount_options = mdata ;
29882991 }
@@ -3036,6 +3039,7 @@ static int setup_dfs_tgt_conn(const char *path, const char *full_path,
30363039 struct dfs_info3_param ref = {0 };
30373040 char * mdata = NULL ;
30383041 struct smb3_fs_context fake_ctx = {NULL };
3042+ char * fake_devname = NULL ;
30393043
30403044 cifs_dbg (FYI , "%s: dfs path: %s\n" , __func__ , path );
30413045
@@ -3044,16 +3048,18 @@ static int setup_dfs_tgt_conn(const char *path, const char *full_path,
30443048 return rc ;
30453049
30463050 mdata = cifs_compose_mount_options (cifs_sb -> ctx -> mount_options ,
3047- full_path + 1 , & ref );
3051+ full_path + 1 , & ref ,
3052+ & fake_devname );
30483053 free_dfs_info_param (& ref );
30493054
30503055 if (IS_ERR (mdata )) {
30513056 rc = PTR_ERR (mdata );
30523057 mdata = NULL ;
30533058 } else
3054- rc = cifs_setup_volume_info (& fake_ctx );
3059+ rc = cifs_setup_volume_info (& fake_ctx , mdata , fake_devname );
30553060
30563061 kfree (mdata );
3062+ kfree (fake_devname );
30573063
30583064 if (!rc ) {
30593065 /*
@@ -3122,10 +3128,24 @@ static int do_dfs_failover(const char *path, const char *full_path, struct cifs_
31223128 * we should pass a clone of the original context?
31233129 */
31243130int
3125- cifs_setup_volume_info (struct smb3_fs_context * ctx )
3131+ cifs_setup_volume_info (struct smb3_fs_context * ctx , const char * mntopts , const char * devname )
31263132{
31273133 int rc = 0 ;
31283134
3135+ smb3_parse_devname (devname , ctx );
3136+
3137+ if (mntopts ) {
3138+ char * ip ;
3139+
3140+ cifs_dbg (FYI , "%s: mntopts=%s\n" , __func__ , mntopts );
3141+ rc = smb3_parse_opt (mntopts , "ip" , & ip );
3142+ if (!rc && !cifs_convert_address ((struct sockaddr * )& ctx -> dstaddr , ip ,
3143+ strlen (ip ))) {
3144+ cifs_dbg (VFS , "%s: failed to convert ip address\n" , __func__ );
3145+ return - EINVAL ;
3146+ }
3147+ }
3148+
31293149 if (ctx -> nullauth ) {
31303150 cifs_dbg (FYI , "Anonymous login\n" );
31313151 kfree (ctx -> username );
0 commit comments