@@ -258,61 +258,23 @@ char *cifs_compose_mount_options(const char *sb_mountdata,
258258 goto compose_mount_options_out ;
259259}
260260
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-
304261/*
305262 * Create a vfsmount that we can automount
306263 */
307- static struct vfsmount * cifs_dfs_do_automount (struct dentry * mntpt )
264+ static struct vfsmount * cifs_dfs_do_automount (struct path * path )
308265{
266+ int rc ;
267+ struct dentry * mntpt = path -> dentry ;
268+ struct fs_context * fc ;
309269 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 ;
311273 char * full_path ;
312274 struct vfsmount * mnt ;
313275
314- cifs_dbg ( FYI , "in %s\n" , __func__ );
315- BUG_ON ( IS_ROOT ( mntpt ) );
276+ if ( IS_ROOT ( mntpt ))
277+ return ERR_PTR ( - ESTALE );
316278
317279 /*
318280 * 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)
321283 * gives us the latter, so we must adjust the result.
322284 */
323285 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 );
328296
329297 page = alloc_dentry_path ();
330298 /* always use tree name prefix */
331299 full_path = build_path_from_dentry_optional_prefix (mntpt , page , true);
332300 if (IS_ERR (full_path )) {
333301 mnt = ERR_CAST (full_path );
334- goto free_full_path ;
302+ goto out ;
335303 }
336304
337- convert_delimiter (full_path , '\\ ' );
305+ convert_delimiter (full_path , '/ ' );
338306 cifs_dbg (FYI , "%s: full_path: %s\n" , __func__ , full_path );
339307
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 );
342323
343- free_full_path :
324+ out :
325+ put_fs_context (fc );
344326 free_dentry_path (page );
345- cdda_exit :
346- cifs_dbg (FYI , "leaving %s\n" , __func__ );
347327 return mnt ;
348328}
349329
@@ -354,9 +334,9 @@ struct vfsmount *cifs_dfs_d_automount(struct path *path)
354334{
355335 struct vfsmount * newmnt ;
356336
357- cifs_dbg (FYI , "in %s \n" , __func__ );
337+ cifs_dbg (FYI , "%s: %pd \n" , __func__ , path -> dentry );
358338
359- newmnt = cifs_dfs_do_automount (path -> dentry );
339+ newmnt = cifs_dfs_do_automount (path );
360340 if (IS_ERR (newmnt )) {
361341 cifs_dbg (FYI , "leaving %s [automount failed]\n" , __func__ );
362342 return newmnt ;
0 commit comments