Skip to content

Commit 7ad54b9

Browse files
Paulo Alcantarasmfrench
authored andcommitted
cifs: use origin fullpath for automounts
Use TCP_Server_Info::origin_fullpath instead of cifs_tcon::tree_name when building source paths for automounts as it will be useful for domain-based DFS referrals where the connections and referrals would get either re-used from the cache or re-created when chasing the dfs link. Signed-off-by: Paulo Alcantara (SUSE) <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 25cf01b commit 7ad54b9

File tree

4 files changed

+53
-10
lines changed

4 files changed

+53
-10
lines changed

fs/cifs/cifs_dfs_ref.c

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,7 @@
2121
#include "cifsfs.h"
2222
#include "dns_resolve.h"
2323
#include "cifs_debug.h"
24-
#include "cifs_unicode.h"
25-
#include "dfs_cache.h"
24+
#include "dfs.h"
2625
#include "fs_context.h"
2726

2827
static LIST_HEAD(cifs_dfs_automount_list);
@@ -119,6 +118,17 @@ cifs_build_devname(char *nodename, const char *prepath)
119118
return dev;
120119
}
121120

121+
static int set_dest_addr(struct smb3_fs_context *ctx, const char *full_path)
122+
{
123+
struct sockaddr *addr = (struct sockaddr *)&ctx->dstaddr;
124+
int rc;
125+
126+
rc = dns_resolve_server_name_to_ip(full_path, addr, NULL);
127+
if (!rc)
128+
cifs_set_port(addr, ctx->port);
129+
return rc;
130+
}
131+
122132
/*
123133
* Create a vfsmount that we can automount
124134
*/
@@ -156,8 +166,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct path *path)
156166
ctx = smb3_fc2context(fc);
157167

158168
page = alloc_dentry_path();
159-
/* always use tree name prefix */
160-
full_path = build_path_from_dentry_optional_prefix(mntpt, page, true);
169+
full_path = dfs_get_automount_devname(mntpt, page);
161170
if (IS_ERR(full_path)) {
162171
mnt = ERR_CAST(full_path);
163172
goto out;
@@ -168,6 +177,7 @@ static struct vfsmount *cifs_dfs_do_automount(struct path *path)
168177

169178
tmp = *cur_ctx;
170179
tmp.source = full_path;
180+
tmp.leaf_fullpath = NULL;
171181
tmp.UNC = tmp.prepath = NULL;
172182

173183
rc = smb3_fs_context_dup(ctx, &tmp);
@@ -176,6 +186,12 @@ static struct vfsmount *cifs_dfs_do_automount(struct path *path)
176186
goto out;
177187
}
178188

189+
rc = set_dest_addr(ctx, full_path);
190+
if (rc) {
191+
mnt = ERR_PTR(rc);
192+
goto out;
193+
}
194+
179195
rc = smb3_parse_devname(full_path, ctx);
180196
if (!rc)
181197
mnt = fc_mount(fc);

fs/cifs/cifsproto.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,9 @@ extern void exit_cifs_idmap(void);
5757
extern int init_cifs_spnego(void);
5858
extern void exit_cifs_spnego(void);
5959
extern const char *build_path_from_dentry(struct dentry *, void *);
60+
char *__build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
61+
const char *tree, int tree_len,
62+
bool prefix);
6063
extern char *build_path_from_dentry_optional_prefix(struct dentry *direntry,
6164
void *page, bool prefix);
6265
static inline void *alloc_dentry_path(void)

fs/cifs/dfs.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,19 @@ static inline int dfs_get_referral(struct cifs_mount_ctx *mnt_ctx, const char *p
2828
cifs_remap(cifs_sb), path, ref, tl);
2929
}
3030

31+
static inline char *dfs_get_automount_devname(struct dentry *dentry, void *page)
32+
{
33+
struct cifs_sb_info *cifs_sb = CIFS_SB(dentry->d_sb);
34+
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
35+
struct TCP_Server_Info *server = tcon->ses->server;
36+
37+
if (unlikely(!server->origin_fullpath))
38+
return ERR_PTR(-EREMOTE);
39+
40+
return __build_path_from_dentry_optional_prefix(dentry, page,
41+
server->origin_fullpath,
42+
strlen(server->origin_fullpath),
43+
true);
44+
}
45+
3146
#endif /* _CIFS_DFS_H */

fs/cifs/dir.c

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -78,22 +78,21 @@ build_path_from_dentry(struct dentry *direntry, void *page)
7878
prefix);
7979
}
8080

81-
char *
82-
build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
83-
bool prefix)
81+
char *__build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
82+
const char *tree, int tree_len,
83+
bool prefix)
8484
{
8585
int dfsplen;
8686
int pplen = 0;
8787
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
88-
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
8988
char dirsep = CIFS_DIR_SEP(cifs_sb);
9089
char *s;
9190

9291
if (unlikely(!page))
9392
return ERR_PTR(-ENOMEM);
9493

9594
if (prefix)
96-
dfsplen = strnlen(tcon->tree_name, MAX_TREE_SIZE + 1);
95+
dfsplen = strnlen(tree, tree_len + 1);
9796
else
9897
dfsplen = 0;
9998

@@ -123,7 +122,7 @@ build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
123122
}
124123
if (dfsplen) {
125124
s -= dfsplen;
126-
memcpy(s, tcon->tree_name, dfsplen);
125+
memcpy(s, tree, dfsplen);
127126
if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
128127
int i;
129128
for (i = 0; i < dfsplen; i++) {
@@ -135,6 +134,16 @@ build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
135134
return s;
136135
}
137136

137+
char *build_path_from_dentry_optional_prefix(struct dentry *direntry, void *page,
138+
bool prefix)
139+
{
140+
struct cifs_sb_info *cifs_sb = CIFS_SB(direntry->d_sb);
141+
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
142+
143+
return __build_path_from_dentry_optional_prefix(direntry, page, tcon->tree_name,
144+
MAX_TREE_SIZE, prefix);
145+
}
146+
138147
/*
139148
* Don't allow path components longer than the server max.
140149
* Don't allow the separator character in a path component.

0 commit comments

Comments
 (0)