CIFS: add build_path_from_dentry_optional_prefix()

this function does the same thing as add build_path_from_dentry() but
takes a boolean parameter to decide whether or not to prefix the path
with the tree name.

we cannot rely on tcon->Flags & SMB_SHARE_IS_IN_DFS for SMB2 as smb2
code never sets tcon->Flags but it sets tcon->share_flags and it seems
the SMB_SHARE_IS_IN_DFS has different semantics in SMB2: the prefix
shouldn't be added everytime it was in SMB1.

Signed-off-by: Aurelien Aptel <aaptel@suse.com>
Acked-by: Pavel Shilovsky <pshilov@microsoft.com>
Signed-off-by: Steve French <smfrench@gmail.com>
This commit is contained in:
Aurelien Aptel 2017-02-13 16:14:17 +01:00 committed by Steve French
parent 4ecce920e1
commit 268a635d41
3 changed files with 17 additions and 2 deletions

View File

@ -303,7 +303,9 @@ static struct vfsmount *cifs_dfs_do_automount(struct dentry *mntpt)
* gives us the latter, so we must adjust the result. * gives us the latter, so we must adjust the result.
*/ */
mnt = ERR_PTR(-ENOMEM); mnt = ERR_PTR(-ENOMEM);
full_path = build_path_from_dentry(mntpt);
/* always use tree name prefix */
full_path = build_path_from_dentry_optional_prefix(mntpt, true);
if (full_path == NULL) if (full_path == NULL)
goto cdda_exit; goto cdda_exit;

View File

@ -61,6 +61,8 @@ extern void exit_cifs_idmap(void);
extern int init_cifs_spnego(void); extern int init_cifs_spnego(void);
extern void exit_cifs_spnego(void); extern void exit_cifs_spnego(void);
extern char *build_path_from_dentry(struct dentry *); extern char *build_path_from_dentry(struct dentry *);
extern char *build_path_from_dentry_optional_prefix(struct dentry *direntry,
bool prefix);
extern char *cifs_build_path_to_root(struct smb_vol *vol, extern char *cifs_build_path_to_root(struct smb_vol *vol,
struct cifs_sb_info *cifs_sb, struct cifs_sb_info *cifs_sb,
struct cifs_tcon *tcon, struct cifs_tcon *tcon,

View File

@ -80,6 +80,17 @@ cifs_build_path_to_root(struct smb_vol *vol, struct cifs_sb_info *cifs_sb,
/* Note: caller must free return buffer */ /* Note: caller must free return buffer */
char * char *
build_path_from_dentry(struct dentry *direntry) build_path_from_dentry(struct dentry *direntry)
{
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
bool prefix = tcon->Flags & SMB_SHARE_IS_IN_DFS;
return build_path_from_dentry_optional_prefix(direntry,
prefix);
}
char *
build_path_from_dentry_optional_prefix(struct dentry *direntry, bool prefix)
{ {
struct dentry *temp; struct dentry *temp;
int namelen; int namelen;
@ -92,7 +103,7 @@ build_path_from_dentry(struct dentry *direntry)
unsigned seq; unsigned seq;
dirsep = CIFS_DIR_SEP(cifs_sb); dirsep = CIFS_DIR_SEP(cifs_sb);
if (tcon->Flags & SMB_SHARE_IS_IN_DFS) if (prefix)
dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1); dfsplen = strnlen(tcon->treeName, MAX_TREE_SIZE + 1);
else else
dfsplen = 0; dfsplen = 0;