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>
This commit is contained in:
parent
395664439c
commit
374402a2a1
|
@ -615,7 +615,7 @@ cifs_get_root(struct smb_vol *vol, struct super_block *sb)
|
|||
return dget(sb->s_root);
|
||||
|
||||
full_path = cifs_build_path_to_root(vol, cifs_sb,
|
||||
cifs_sb_master_tcon(cifs_sb));
|
||||
cifs_sb_master_tcon(cifs_sb), 0);
|
||||
if (full_path == NULL)
|
||||
return ERR_PTR(-ENOMEM);
|
||||
|
||||
|
|
|
@ -63,7 +63,8 @@ extern void exit_cifs_spnego(void);
|
|||
extern char *build_path_from_dentry(struct dentry *);
|
||||
extern char *cifs_build_path_to_root(struct smb_vol *vol,
|
||||
struct cifs_sb_info *cifs_sb,
|
||||
struct cifs_tcon *tcon);
|
||||
struct cifs_tcon *tcon,
|
||||
int add_treename);
|
||||
extern char *build_wildcard_path_from_dentry(struct dentry *direntry);
|
||||
extern char *cifs_compose_mount_options(const char *sb_mountdata,
|
||||
const char *fullpath, const struct dfs_info3_param *ref,
|
||||
|
|
|
@ -3765,7 +3765,8 @@ remote_path_check:
|
|||
/*
|
||||
* cifs_build_path_to_root works only when we have a valid tcon
|
||||
*/
|
||||
full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon);
|
||||
full_path = cifs_build_path_to_root(volume_info, cifs_sb, tcon,
|
||||
tcon->Flags & SMB_SHARE_IS_IN_DFS);
|
||||
if (full_path == NULL) {
|
||||
rc = -ENOMEM;
|
||||
goto mount_fail_check;
|
||||
|
|
|
@ -47,7 +47,7 @@ renew_parental_timestamps(struct dentry *direntry)
|
|||
|
||||
char *
|
||||
cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
|
||||
struct cifs_tcon *tcon)
|
||||
struct cifs_tcon *tcon, int add_treename)
|
||||
{
|
||||
int pplen = vol->prepath ? strlen(vol->prepath) + 1 : 0;
|
||||
int dfsplen;
|
||||
|
@ -59,7 +59,7 @@ cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
|
|||
return full_path;
|
||||
}
|
||||
|
||||
if (tcon->Flags & SMB_SHARE_IS_IN_DFS)
|
||||
if (add_treename)
|
||||
dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
|
||||
else
|
||||
dfsplen = 0;
|
||||
|
|
Loading…
Reference in New Issue