Skip to content

Commit 5bb30a4

Browse files
Paulo Alcantara (SUSE)smfrench
authored andcommitted
cifs: Fix retrieval of DFS referrals in cifs_mount()
Make sure that DFS referrals are sent to newly resolved root targets as in a multi tier DFS setup. Signed-off-by: Paulo Alcantara (SUSE) <[email protected]> Link: https://lkml.kernel.org/r/[email protected] Cc: [email protected] Tested-by: Matthew Ruffell <[email protected]> Signed-off-by: Steve French <[email protected]>
1 parent 84a1f5b commit 5bb30a4

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

fs/cifs/connect.c

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4786,6 +4786,17 @@ static int is_path_remote(struct cifs_sb_info *cifs_sb, struct smb_vol *vol,
47864786
}
47874787

47884788
#ifdef CONFIG_CIFS_DFS_UPCALL
4789+
static inline void set_root_tcon(struct cifs_sb_info *cifs_sb,
4790+
struct cifs_tcon *tcon,
4791+
struct cifs_tcon **root)
4792+
{
4793+
spin_lock(&cifs_tcp_ses_lock);
4794+
tcon->tc_count++;
4795+
tcon->remap = cifs_remap(cifs_sb);
4796+
spin_unlock(&cifs_tcp_ses_lock);
4797+
*root = tcon;
4798+
}
4799+
47894800
int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol)
47904801
{
47914802
int rc = 0;
@@ -4887,18 +4898,10 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol)
48874898
/* Cache out resolved root server */
48884899
(void)dfs_cache_find(xid, ses, cifs_sb->local_nls, cifs_remap(cifs_sb),
48894900
root_path + 1, NULL, NULL);
4890-
/*
4891-
* Save root tcon for additional DFS requests to update or create a new
4892-
* DFS cache entry, or even perform DFS failover.
4893-
*/
4894-
spin_lock(&cifs_tcp_ses_lock);
4895-
tcon->tc_count++;
4896-
tcon->dfs_path = root_path;
4901+
kfree(root_path);
48974902
root_path = NULL;
4898-
tcon->remap = cifs_remap(cifs_sb);
4899-
spin_unlock(&cifs_tcp_ses_lock);
49004903

4901-
root_tcon = tcon;
4904+
set_root_tcon(cifs_sb, tcon, &root_tcon);
49024905

49034906
for (count = 1; ;) {
49044907
if (!rc && tcon) {
@@ -4935,6 +4938,15 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol)
49354938
mount_put_conns(cifs_sb, xid, server, ses, tcon);
49364939
rc = mount_get_conns(vol, cifs_sb, &xid, &server, &ses,
49374940
&tcon);
4941+
/*
4942+
* Ensure that DFS referrals go through new root server.
4943+
*/
4944+
if (!rc && tcon &&
4945+
(tcon->share_flags & (SHI1005_FLAGS_DFS |
4946+
SHI1005_FLAGS_DFS_ROOT))) {
4947+
cifs_put_tcon(root_tcon);
4948+
set_root_tcon(cifs_sb, tcon, &root_tcon);
4949+
}
49384950
}
49394951
if (rc) {
49404952
if (rc == -EACCES || rc == -EOPNOTSUPP)

0 commit comments

Comments
 (0)