Skip to content

Commit 374402a

Browse files
spuiuksmfrench
authored andcommitted
cifs_get_root shouldn't use path with tree name
When a server returns the optional flag SMB_SHARE_IS_IN_DFS in response to a tree connect, cifs_build_path_to_root() will return a pathname which includes the hostname. This causes problems with cifs_get_root() which separates each component and does a lookup for each component of the path which in this case will incorrectly include looking up the hostname component as a path component. We encountered a problem with dfs shares hosted by a Netapp. When connecting to nodes pointed to by the DFS share. The tree connect for these nodes return SMB_SHARE_IS_IN_DFS resulting failures in lookup in cifs_get_root(). RH bz: 1373153 The patch was tested against a Netapp simulator and by a user using an actual Netapp server. Signed-off-by: Sachin Prabhu <sprabhu@redhat.com> Reported-by: Pierguido Lambri <plambri@redhat.com> Reviewed-by: Jeff Layton <jlayton@redhat.com> Signed-off-by: Steve French <smfrench@gmail.com>
1 parent 3956644 commit 374402a

File tree

4 files changed

+7
-5
lines changed

4 files changed

+7
-5
lines changed

fs/cifs/cifsfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -615,7 +615,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
615615
return dget(sb->s_root);
616616

617617
full_path = cifs_build_path_to_root(vol, cifs_sb,
618-
cifs_sb_master_tcon(cifs_sb));
618+
cifs_sb_master_tcon(cifs_sb), 0);
619619
if (full_path == NULL)
620620
return ERR_PTR(-ENOMEM);
621621

fs/cifs/cifsproto.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ extern void exit_cifs_spnego(void);
6363
extern char *build_path_from_dentry(struct dentry *);
6464
extern char *cifs_build_path_to_root(struct smb_vol *vol,
6565
struct cifs_sb_info *cifs_sb,
66-
struct cifs_tcon *tcon);
66+
struct cifs_tcon *tcon,
67+
int add_treename);
6768
extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
6869
extern char *cifs_compose_mount_options(const char *sb_mountdata,
6970
const char *fullpath, const struct dfs_info3_param *ref,

fs/cifs/connect.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3765,7 +3765,8 @@ cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *volume_info)
37653765
/*
37663766
* cifs_build_path_to_root works only when we have a valid tcon
37673767
*/
3768-
full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon);
3768+
full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon,
3769+
tcon->Flags & SMB_SHARE_IS_IN_DFS);
37693770
if (full_path == NULL) {
37703771
rc = -ENOMEM;
37713772
goto mount_fail_check;

fs/cifs/dir.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ renew_parental_timestamps(struct dentry *direntry)
4747

4848
char *
4949
cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
50-
struct cifs_tcon *tcon)
50+
struct cifs_tcon *tcon, int add_treename)
5151
{
5252
int pplen = vol->prepath ? strlen(vol->prepath) + 1 : 0;
5353
int dfsplen;
@@ -59,7 +59,7 @@ cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
5959
return full_path;
6060
}
6161

62-
if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
62+
if (add_treename)
6363
dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
6464
else
6565
dfsplen = 0;

0 commit comments

Comments
 (0)