@@ -120,17 +120,17 @@ cifs_build_devname(char *nodename, const char *prepath)
120
120
121
121
122
122
/**
123
- * cifs_compose_mount_options - creates mount options for refferral
123
+ * cifs_compose_mount_options - creates mount options for referral
124
124
* @sb_mountdata: parent/root DFS mount options (template)
125
125
* @fullpath: full path in UNC format
126
- * @ref: server's referral
126
+ * @ref: optional server's referral
127
127
* @devname: optional pointer for saving device name
128
128
*
129
129
* creates mount options for submount based on template options sb_mountdata
130
130
* and replacing unc,ip,prefixpath options with ones we've got form ref_unc.
131
131
*
132
132
* Returns: pointer to new mount options or ERR_PTR.
133
- * Caller is responcible for freeing retunrned value if it is not error.
133
+ * Caller is responsible for freeing returned value if it is not error.
134
134
*/
135
135
char * cifs_compose_mount_options (const char * sb_mountdata ,
136
136
const char * fullpath ,
@@ -150,18 +150,27 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
150
150
if (sb_mountdata == NULL )
151
151
return ERR_PTR (- EINVAL );
152
152
153
- if (strlen (fullpath ) - ref -> path_consumed ) {
154
- prepath = fullpath + ref -> path_consumed ;
155
- /* skip initial delimiter */
156
- if (* prepath == '/' || * prepath == '\\' )
157
- prepath ++ ;
158
- }
153
+ if (ref ) {
154
+ if (strlen (fullpath ) - ref -> path_consumed ) {
155
+ prepath = fullpath + ref -> path_consumed ;
156
+ /* skip initial delimiter */
157
+ if (* prepath == '/' || * prepath == '\\' )
158
+ prepath ++ ;
159
+ }
159
160
160
- name = cifs_build_devname (ref -> node_name , prepath );
161
- if (IS_ERR (name )) {
162
- rc = PTR_ERR (name );
163
- name = NULL ;
164
- goto compose_mount_options_err ;
161
+ name = cifs_build_devname (ref -> node_name , prepath );
162
+ if (IS_ERR (name )) {
163
+ rc = PTR_ERR (name );
164
+ name = NULL ;
165
+ goto compose_mount_options_err ;
166
+ }
167
+ } else {
168
+ name = cifs_build_devname ((char * )fullpath , NULL );
169
+ if (IS_ERR (name )) {
170
+ rc = PTR_ERR (name );
171
+ name = NULL ;
172
+ goto compose_mount_options_err ;
173
+ }
165
174
}
166
175
167
176
rc = dns_resolve_server_name_to_ip (name , & srvIP );
@@ -225,6 +234,8 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
225
234
226
235
if (devname )
227
236
* devname = name ;
237
+ else
238
+ kfree (name );
228
239
229
240
/*cifs_dbg(FYI, "%s: parent mountdata: %s\n", __func__, sb_mountdata);*/
230
241
/*cifs_dbg(FYI, "%s: submount mountdata: %s\n", __func__, mountdata );*/
@@ -241,23 +252,23 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
241
252
}
242
253
243
254
/**
244
- * cifs_dfs_do_refmount - mounts specified path using provided refferal
255
+ * cifs_dfs_do_mount - mounts specified path using DFS full path
256
+ *
257
+ * Always pass down @fullpath to smb3_do_mount() so we can use the root server
258
+ * to perform failover in case we failed to connect to the first target in the
259
+ * referral.
260
+ *
245
261
* @cifs_sb: parent/root superblock
246
262
* @fullpath: full path in UNC format
247
- * @ref: server's referral
248
263
*/
249
- static struct vfsmount * cifs_dfs_do_refmount (struct dentry * mntpt ,
250
- struct cifs_sb_info * cifs_sb ,
251
- const char * fullpath , const struct dfs_info3_param * ref )
264
+ static struct vfsmount * cifs_dfs_do_mount (struct dentry * mntpt ,
265
+ struct cifs_sb_info * cifs_sb ,
266
+ const char * fullpath )
252
267
{
253
268
struct vfsmount * mnt ;
254
269
char * mountdata ;
255
270
char * devname ;
256
271
257
- /*
258
- * Always pass down the DFS full path to smb3_do_mount() so we
259
- * can use it later for failover.
260
- */
261
272
devname = kstrndup (fullpath , strlen (fullpath ), GFP_KERNEL );
262
273
if (!devname )
263
274
return ERR_PTR (- ENOMEM );
@@ -266,7 +277,7 @@ static struct vfsmount *cifs_dfs_do_refmount(struct dentry *mntpt,
266
277
267
278
/* strip first '\' from fullpath */
268
279
mountdata = cifs_compose_mount_options (cifs_sb -> mountdata ,
269
- fullpath + 1 , ref , NULL );
280
+ fullpath + 1 , NULL , NULL );
270
281
if (IS_ERR (mountdata )) {
271
282
kfree (devname );
272
283
return (struct vfsmount * )mountdata ;
@@ -278,28 +289,16 @@ static struct vfsmount *cifs_dfs_do_refmount(struct dentry *mntpt,
278
289
return mnt ;
279
290
}
280
291
281
- static void dump_referral (const struct dfs_info3_param * ref )
282
- {
283
- cifs_dbg (FYI , "DFS: ref path: %s\n" , ref -> path_name );
284
- cifs_dbg (FYI , "DFS: node path: %s\n" , ref -> node_name );
285
- cifs_dbg (FYI , "DFS: fl: %d, srv_type: %d\n" ,
286
- ref -> flags , ref -> server_type );
287
- cifs_dbg (FYI , "DFS: ref_flags: %d, path_consumed: %d\n" ,
288
- ref -> ref_flag , ref -> path_consumed );
289
- }
290
-
291
292
/*
292
293
* Create a vfsmount that we can automount
293
294
*/
294
295
static struct vfsmount * cifs_dfs_do_automount (struct dentry * mntpt )
295
296
{
296
- struct dfs_info3_param referral = {0 };
297
297
struct cifs_sb_info * cifs_sb ;
298
298
struct cifs_ses * ses ;
299
299
struct cifs_tcon * tcon ;
300
300
char * full_path , * root_path ;
301
301
unsigned int xid ;
302
- int len ;
303
302
int rc ;
304
303
struct vfsmount * mnt ;
305
304
@@ -357,7 +356,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
357
356
if (!rc ) {
358
357
rc = dfs_cache_find (xid , ses , cifs_sb -> local_nls ,
359
358
cifs_remap (cifs_sb ), full_path + 1 ,
360
- & referral , NULL );
359
+ NULL , NULL );
361
360
}
362
361
363
362
free_xid (xid );
@@ -366,26 +365,16 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
366
365
mnt = ERR_PTR (rc );
367
366
goto free_root_path ;
368
367
}
369
-
370
- dump_referral (& referral );
371
-
372
- len = strlen (referral .node_name );
373
- if (len < 2 ) {
374
- cifs_dbg (VFS , "%s: Net Address path too short: %s\n" ,
375
- __func__ , referral .node_name );
376
- mnt = ERR_PTR (- EINVAL );
377
- goto free_dfs_ref ;
378
- }
379
368
/*
380
- * cifs_mount() will retry every available node server in case
381
- * of failures.
369
+ * OK - we were able to get and cache a referral for @full_path.
370
+ *
371
+ * Now, pass it down to cifs_mount() and it will retry every available
372
+ * node server in case of failures - no need to do it here.
382
373
*/
383
- mnt = cifs_dfs_do_refmount (mntpt , cifs_sb , full_path , & referral );
384
- cifs_dbg (FYI , "%s: cifs_dfs_do_refmount :%s , mnt:%p\n" , __func__ ,
385
- referral . node_name , mnt );
374
+ mnt = cifs_dfs_do_mount (mntpt , cifs_sb , full_path );
375
+ cifs_dbg (FYI , "%s: cifs_dfs_do_mount :%s , mnt:%p\n" , __func__ ,
376
+ full_path + 1 , mnt );
386
377
387
- free_dfs_ref :
388
- free_dfs_info_param (& referral );
389
378
free_root_path :
390
379
kfree (root_path );
391
380
free_full_path :
0 commit comments