aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/connect.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/cifs/connect.c')
-rw-r--r--fs/cifs/connect.c24
1 files changed, 11 insertions, 13 deletions
diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c
index 20c60ddaa5a1..3e20831119a9 100644
--- a/fs/cifs/connect.c
+++ b/fs/cifs/connect.c
@@ -2788,9 +2788,9 @@ build_unc_path_to_root(const struct smb_vol *volume_info,
2788/* 2788/*
2789 * Perform a dfs referral query for a share and (optionally) prefix 2789 * Perform a dfs referral query for a share and (optionally) prefix
2790 * 2790 *
2791 * If a referral is found, mount_data will be set to point at a newly 2791 * If a referral is found, cifs_sb->mountdata will be (re-)allocated
2792 * allocated string containing updated options for the submount. 2792 * to a string containing updated options for the submount. Otherwise it
2793 * Otherwise it will be left untouched. 2793 * will be left untouched.
2794 * 2794 *
2795 * Returns the rc from get_dfs_path to the caller, which can be used to 2795 * Returns the rc from get_dfs_path to the caller, which can be used to
2796 * determine whether there were referrals. 2796 * determine whether there were referrals.
@@ -2798,7 +2798,7 @@ build_unc_path_to_root(const struct smb_vol *volume_info,
2798static int 2798static int
2799expand_dfs_referral(int xid, struct cifsSesInfo *pSesInfo, 2799expand_dfs_referral(int xid, struct cifsSesInfo *pSesInfo,
2800 struct smb_vol *volume_info, struct cifs_sb_info *cifs_sb, 2800 struct smb_vol *volume_info, struct cifs_sb_info *cifs_sb,
2801 char **mount_data, int check_prefix) 2801 int check_prefix)
2802{ 2802{
2803 int rc; 2803 int rc;
2804 unsigned int num_referrals = 0; 2804 unsigned int num_referrals = 0;
@@ -2826,11 +2826,14 @@ expand_dfs_referral(int xid, struct cifsSesInfo *pSesInfo,
2826 free_dfs_info_array(referrals, num_referrals); 2826 free_dfs_info_array(referrals, num_referrals);
2827 kfree(fake_devname); 2827 kfree(fake_devname);
2828 2828
2829 if (cifs_sb->mountdata != NULL)
2830 kfree(cifs_sb->mountdata);
2831
2829 if (IS_ERR(mdata)) { 2832 if (IS_ERR(mdata)) {
2830 rc = PTR_ERR(mdata); 2833 rc = PTR_ERR(mdata);
2831 mdata = NULL; 2834 mdata = NULL;
2832 } 2835 }
2833 *mount_data = mdata; 2836 cifs_sb->mountdata = mdata;
2834 } 2837 }
2835 kfree(full_path); 2838 kfree(full_path);
2836 return rc; 2839 return rc;
@@ -2853,6 +2856,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2853#ifdef CONFIG_CIFS_DFS_UPCALL 2856#ifdef CONFIG_CIFS_DFS_UPCALL
2854 int referral_walks_count = 0; 2857 int referral_walks_count = 0;
2855try_mount_again: 2858try_mount_again:
2859 mount_data = cifs_sb->mountdata;
2856 2860
2857 /* cleanup activities if we're chasing a referral */ 2861 /* cleanup activities if we're chasing a referral */
2858 if (referral_walks_count) { 2862 if (referral_walks_count) {
@@ -2986,7 +2990,7 @@ remote_path_check:
2986 */ 2990 */
2987 if (referral_walks_count == 0) { 2991 if (referral_walks_count == 0) {
2988 int refrc = expand_dfs_referral(xid, pSesInfo, volume_info, 2992 int refrc = expand_dfs_referral(xid, pSesInfo, volume_info,
2989 cifs_sb, &mount_data, false); 2993 cifs_sb, false);
2990 if (!refrc) { 2994 if (!refrc) {
2991 referral_walks_count++; 2995 referral_walks_count++;
2992 goto try_mount_again; 2996 goto try_mount_again;
@@ -3028,17 +3032,13 @@ remote_path_check:
3028 convert_delimiter(cifs_sb->prepath, 3032 convert_delimiter(cifs_sb->prepath,
3029 CIFS_DIR_SEP(cifs_sb)); 3033 CIFS_DIR_SEP(cifs_sb));
3030 3034
3031 if (mount_data != mount_data_global)
3032 kfree(mount_data);
3033
3034 rc = expand_dfs_referral(xid, pSesInfo, volume_info, cifs_sb, 3035 rc = expand_dfs_referral(xid, pSesInfo, volume_info, cifs_sb,
3035 &mount_data, true); 3036 true);
3036 3037
3037 if (!rc) { 3038 if (!rc) {
3038 referral_walks_count++; 3039 referral_walks_count++;
3039 goto try_mount_again; 3040 goto try_mount_again;
3040 } 3041 }
3041 mount_data = NULL;
3042 goto mount_fail_check; 3042 goto mount_fail_check;
3043#else /* No DFS support, return error on mount */ 3043#else /* No DFS support, return error on mount */
3044 rc = -EOPNOTSUPP; 3044 rc = -EOPNOTSUPP;
@@ -3072,8 +3072,6 @@ remote_path_check:
3072mount_fail_check: 3072mount_fail_check:
3073 /* on error free sesinfo and tcon struct if needed */ 3073 /* on error free sesinfo and tcon struct if needed */
3074 if (rc) { 3074 if (rc) {
3075 if (mount_data != mount_data_global)
3076 kfree(mount_data);
3077 /* If find_unc succeeded then rc == 0 so we can not end */ 3075 /* If find_unc succeeded then rc == 0 so we can not end */
3078 /* up accidentally freeing someone elses tcon struct */ 3076 /* up accidentally freeing someone elses tcon struct */
3079 if (tcon) 3077 if (tcon)