@@ -258,61 +258,23 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
258
258
goto compose_mount_options_out ;
259
259
}
260
260
261
- /**
262
- * cifs_dfs_do_mount - mounts specified path using DFS full path
263
- *
264
- * Always pass down @fullpath to smb3_do_mount() so we can use the root server
265
- * to perform failover in case we failed to connect to the first target in the
266
- * referral.
267
- *
268
- * @mntpt: directory entry for the path we are trying to automount
269
- * @cifs_sb: parent/root superblock
270
- * @fullpath: full path in UNC format
271
- */
272
- static struct vfsmount * cifs_dfs_do_mount (struct dentry * mntpt ,
273
- struct cifs_sb_info * cifs_sb ,
274
- const char * fullpath )
275
- {
276
- struct vfsmount * mnt ;
277
- char * mountdata ;
278
- char * devname ;
279
-
280
- devname = kstrdup (fullpath , GFP_KERNEL );
281
- if (!devname )
282
- return ERR_PTR (- ENOMEM );
283
-
284
- convert_delimiter (devname , '/' );
285
-
286
- /* TODO: change to call fs_context_for_mount(), fill in context directly, call fc_mount */
287
-
288
- /* See afs_mntpt_do_automount in fs/afs/mntpt.c for an example */
289
-
290
- /* strip first '\' from fullpath */
291
- mountdata = cifs_compose_mount_options (cifs_sb -> ctx -> mount_options ,
292
- fullpath + 1 , NULL , NULL );
293
- if (IS_ERR (mountdata )) {
294
- kfree (devname );
295
- return (struct vfsmount * )mountdata ;
296
- }
297
-
298
- mnt = vfs_submount (mntpt , & cifs_fs_type , devname , mountdata );
299
- kfree (mountdata );
300
- kfree (devname );
301
- return mnt ;
302
- }
303
-
304
261
/*
305
262
* Create a vfsmount that we can automount
306
263
*/
307
- static struct vfsmount * cifs_dfs_do_automount (struct dentry * mntpt )
264
+ static struct vfsmount * cifs_dfs_do_automount (struct path * path )
308
265
{
266
+ int rc ;
267
+ struct dentry * mntpt = path -> dentry ;
268
+ struct fs_context * fc ;
309
269
struct cifs_sb_info * cifs_sb ;
310
- void * page ;
270
+ void * page = NULL ;
271
+ struct smb3_fs_context * ctx , * cur_ctx ;
272
+ struct smb3_fs_context tmp ;
311
273
char * full_path ;
312
274
struct vfsmount * mnt ;
313
275
314
- cifs_dbg ( FYI , "in %s\n" , __func__ );
315
- BUG_ON ( IS_ROOT ( mntpt ) );
276
+ if ( IS_ROOT ( mntpt ))
277
+ return ERR_PTR ( - ESTALE );
316
278
317
279
/*
318
280
* The MSDFS spec states that paths in DFS referral requests and
@@ -321,29 +283,47 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
321
283
* gives us the latter, so we must adjust the result.
322
284
*/
323
285
cifs_sb = CIFS_SB (mntpt -> d_sb );
324
- if (cifs_sb -> mnt_cifs_flags & CIFS_MOUNT_NO_DFS ) {
325
- mnt = ERR_PTR (- EREMOTE );
326
- goto cdda_exit ;
327
- }
286
+ if (cifs_sb -> mnt_cifs_flags & CIFS_MOUNT_NO_DFS )
287
+ return ERR_PTR (- EREMOTE );
288
+
289
+ cur_ctx = cifs_sb -> ctx ;
290
+
291
+ fc = fs_context_for_submount (path -> mnt -> mnt_sb -> s_type , mntpt );
292
+ if (IS_ERR (fc ))
293
+ return ERR_CAST (fc );
294
+
295
+ ctx = smb3_fc2context (fc );
328
296
329
297
page = alloc_dentry_path ();
330
298
/* always use tree name prefix */
331
299
full_path = build_path_from_dentry_optional_prefix (mntpt , page , true);
332
300
if (IS_ERR (full_path )) {
333
301
mnt = ERR_CAST (full_path );
334
- goto free_full_path ;
302
+ goto out ;
335
303
}
336
304
337
- convert_delimiter (full_path , '\\ ' );
305
+ convert_delimiter (full_path , '/ ' );
338
306
cifs_dbg (FYI , "%s: full_path: %s\n" , __func__ , full_path );
339
307
340
- mnt = cifs_dfs_do_mount (mntpt , cifs_sb , full_path );
341
- cifs_dbg (FYI , "%s: cifs_dfs_do_mount:%s , mnt:%p\n" , __func__ , full_path + 1 , mnt );
308
+ tmp = * cur_ctx ;
309
+ tmp .source = full_path ;
310
+ tmp .UNC = tmp .prepath = NULL ;
311
+
312
+ rc = smb3_fs_context_dup (ctx , & tmp );
313
+ if (rc ) {
314
+ mnt = ERR_PTR (rc );
315
+ goto out ;
316
+ }
317
+
318
+ rc = smb3_parse_devname (full_path , ctx );
319
+ if (!rc )
320
+ mnt = fc_mount (fc );
321
+ else
322
+ mnt = ERR_PTR (rc );
342
323
343
- free_full_path :
324
+ out :
325
+ put_fs_context (fc );
344
326
free_dentry_path (page );
345
- cdda_exit :
346
- cifs_dbg (FYI , "leaving %s\n" , __func__ );
347
327
return mnt ;
348
328
}
349
329
@@ -354,9 +334,9 @@ struct vfsmount *cifs_dfs_d_automount(struct path *path)
354
334
{
355
335
struct vfsmount * newmnt ;
356
336
357
- cifs_dbg (FYI , "in %s \n" , __func__ );
337
+ cifs_dbg (FYI , "%s: %pd \n" , __func__ , path -> dentry );
358
338
359
- newmnt = cifs_dfs_do_automount (path -> dentry );
339
+ newmnt = cifs_dfs_do_automount (path );
360
340
if (IS_ERR (newmnt )) {
361
341
cifs_dbg (FYI , "leaving %s [automount failed]\n" , __func__ );
362
342
return newmnt ;
0 commit comments