merged into cifs-2.6.git for-next On Fri, Nov 22, 2019 at 9:31 AM Paulo Alcantara (SUSE) <pc@xxxxxx> wrote: > > 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) <pc@xxxxxx> > Link: https://lkml.kernel.org/r/05aa2995-e85e-0ff4-d003-5bb08bd17a22@xxxxxxxxxxxxx > Cc: stable@xxxxxxxxxxxxxxx > Tested-by: Matthew Ruffell <matthew.ruffell@xxxxxxxxxxxxx> > --- > fs/cifs/connect.c | 32 ++++++++++++++++++++++---------- > 1 file changed, 22 insertions(+), 10 deletions(-) > > diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c > index 668d477cc9c7..86d98d73749d 100644 > --- a/fs/cifs/connect.c > +++ b/fs/cifs/connect.c > @@ -4776,6 +4776,17 @@ static int is_path_remote(struct cifs_sb_info *cifs_sb, struct smb_vol *vol, > } > > #ifdef CONFIG_CIFS_DFS_UPCALL > +static inline void set_root_tcon(struct cifs_sb_info *cifs_sb, > + struct cifs_tcon *tcon, > + struct cifs_tcon **root) > +{ > + spin_lock(&cifs_tcp_ses_lock); > + tcon->tc_count++; > + tcon->remap = cifs_remap(cifs_sb); > + spin_unlock(&cifs_tcp_ses_lock); > + *root = tcon; > +} > + > int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) > { > int rc = 0; > @@ -4877,18 +4888,10 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) > /* Cache out resolved root server */ > (void)dfs_cache_find(xid, ses, cifs_sb->local_nls, cifs_remap(cifs_sb), > root_path + 1, NULL, NULL); > - /* > - * Save root tcon for additional DFS requests to update or create a new > - * DFS cache entry, or even perform DFS failover. > - */ > - spin_lock(&cifs_tcp_ses_lock); > - tcon->tc_count++; > - tcon->dfs_path = root_path; > + kfree(root_path); > root_path = NULL; > - tcon->remap = cifs_remap(cifs_sb); > - spin_unlock(&cifs_tcp_ses_lock); > > - root_tcon = tcon; > + set_root_tcon(cifs_sb, tcon, &root_tcon); > > for (count = 1; ;) { > if (!rc && tcon) { > @@ -4925,6 +4928,15 @@ int cifs_mount(struct cifs_sb_info *cifs_sb, struct smb_vol *vol) > mount_put_conns(cifs_sb, xid, server, ses, tcon); > rc = mount_get_conns(vol, cifs_sb, &xid, &server, &ses, > &tcon); > + /* > + * Ensure that DFS referrals go through new root server. > + */ > + if (!rc && tcon && > + (tcon->share_flags & (SHI1005_FLAGS_DFS | > + SHI1005_FLAGS_DFS_ROOT))) { > + cifs_put_tcon(root_tcon); > + set_root_tcon(cifs_sb, tcon, &root_tcon); > + } > } > if (rc) { > if (rc == -EACCES || rc == -EOPNOTSUPP) > -- > 2.24.0 > -- Thanks, Steve