@@ -69,7 +69,7 @@ static int get_session(struct cifs_mount_ctx *mnt_ctx, const char *full_path)
6969 * Get an active reference of @ses so that next call to cifs_put_tcon() won't
7070 * release it as any new DFS referrals must go through its IPC tcon.
7171 */
72- static void add_root_smb_session (struct cifs_mount_ctx * mnt_ctx )
72+ static void set_root_smb_session (struct cifs_mount_ctx * mnt_ctx )
7373{
7474 struct smb3_fs_context * ctx = mnt_ctx -> fs_ctx ;
7575 struct cifs_ses * ses = mnt_ctx -> ses ;
@@ -95,7 +95,7 @@ static inline int parse_dfs_target(struct smb3_fs_context *ctx,
9595 return rc ;
9696}
9797
98- static int set_ref_paths (struct cifs_mount_ctx * mnt_ctx ,
98+ static int setup_dfs_ref (struct cifs_mount_ctx * mnt_ctx ,
9999 struct dfs_info3_param * tgt ,
100100 struct dfs_ref_walk * rw )
101101{
@@ -120,6 +120,7 @@ static int set_ref_paths(struct cifs_mount_ctx *mnt_ctx,
120120 }
121121 ref_walk_path (rw ) = ref_path ;
122122 ref_walk_fpath (rw ) = full_path ;
123+ ref_walk_ses (rw ) = ctx -> dfs_root_ses ;
123124 return 0 ;
124125}
125126
@@ -128,11 +129,11 @@ static int __dfs_referral_walk(struct cifs_mount_ctx *mnt_ctx,
128129{
129130 struct smb3_fs_context * ctx = mnt_ctx -> fs_ctx ;
130131 struct dfs_info3_param tgt = {};
131- bool is_refsrv ;
132132 int rc = - ENOENT ;
133133
134134again :
135135 do {
136+ ctx -> dfs_root_ses = ref_walk_ses (rw );
136137 if (ref_walk_empty (rw )) {
137138 rc = dfs_get_referral (mnt_ctx , ref_walk_path (rw ) + 1 ,
138139 NULL , ref_walk_tl (rw ));
@@ -158,10 +159,7 @@ static int __dfs_referral_walk(struct cifs_mount_ctx *mnt_ctx,
158159 if (rc )
159160 continue ;
160161
161- is_refsrv = tgt .server_type == DFS_TYPE_ROOT ||
162- DFS_INTERLINK (tgt .flags );
163162 ref_walk_set_tgt_hint (rw );
164-
165163 if (tgt .flags & DFSREF_STORAGE_SERVER ) {
166164 rc = cifs_mount_get_tcon (mnt_ctx );
167165 if (!rc )
@@ -172,12 +170,10 @@ static int __dfs_referral_walk(struct cifs_mount_ctx *mnt_ctx,
172170 continue ;
173171 }
174172
175- if (is_refsrv )
176- add_root_smb_session (mnt_ctx );
177-
173+ set_root_smb_session (mnt_ctx );
178174 rc = ref_walk_advance (rw );
179175 if (!rc ) {
180- rc = set_ref_paths (mnt_ctx , & tgt , rw );
176+ rc = setup_dfs_ref (mnt_ctx , & tgt , rw );
181177 if (!rc ) {
182178 rc = - EREMOTE ;
183179 goto again ;
@@ -193,37 +189,39 @@ static int __dfs_referral_walk(struct cifs_mount_ctx *mnt_ctx,
193189 return rc ;
194190}
195191
196- static int dfs_referral_walk (struct cifs_mount_ctx * mnt_ctx )
192+ static int dfs_referral_walk (struct cifs_mount_ctx * mnt_ctx ,
193+ struct dfs_ref_walk * * rw )
197194{
198- struct dfs_ref_walk * rw ;
199195 int rc ;
200196
201- rw = ref_walk_alloc ();
202- if (IS_ERR (rw ))
203- return PTR_ERR (rw );
197+ * rw = ref_walk_alloc ();
198+ if (IS_ERR (* rw )) {
199+ rc = PTR_ERR (* rw );
200+ * rw = NULL ;
201+ return rc ;
202+ }
204203
205- ref_walk_init (rw );
206- rc = set_ref_paths (mnt_ctx , NULL , rw );
204+ ref_walk_init (* rw );
205+ rc = setup_dfs_ref (mnt_ctx , NULL , * rw );
207206 if (!rc )
208- rc = __dfs_referral_walk (mnt_ctx , rw );
209- ref_walk_free (rw );
207+ rc = __dfs_referral_walk (mnt_ctx , * rw );
210208 return rc ;
211209}
212210
213211static int __dfs_mount_share (struct cifs_mount_ctx * mnt_ctx )
214212{
215213 struct cifs_sb_info * cifs_sb = mnt_ctx -> cifs_sb ;
216214 struct smb3_fs_context * ctx = mnt_ctx -> fs_ctx ;
215+ struct dfs_ref_walk * rw = NULL ;
217216 struct cifs_tcon * tcon ;
218217 char * origin_fullpath ;
219- bool new_tcon = true;
220218 int rc ;
221219
222220 origin_fullpath = dfs_get_path (cifs_sb , ctx -> source );
223221 if (IS_ERR (origin_fullpath ))
224222 return PTR_ERR (origin_fullpath );
225223
226- rc = dfs_referral_walk (mnt_ctx );
224+ rc = dfs_referral_walk (mnt_ctx , & rw );
227225 if (!rc ) {
228226 /*
229227 * Prevent superblock from being created with any missing
@@ -241,21 +239,16 @@ static int __dfs_mount_share(struct cifs_mount_ctx *mnt_ctx)
241239
242240 tcon = mnt_ctx -> tcon ;
243241 spin_lock (& tcon -> tc_lock );
244- if (!tcon -> origin_fullpath ) {
245- tcon -> origin_fullpath = origin_fullpath ;
246- origin_fullpath = NULL ;
247- } else {
248- new_tcon = false;
249- }
242+ tcon -> origin_fullpath = origin_fullpath ;
243+ origin_fullpath = NULL ;
244+ ref_walk_set_tcon (rw , tcon );
250245 spin_unlock (& tcon -> tc_lock );
251-
252- if (new_tcon ) {
253- queue_delayed_work (dfscache_wq , & tcon -> dfs_cache_work ,
254- dfs_cache_get_ttl () * HZ );
255- }
246+ queue_delayed_work (dfscache_wq , & tcon -> dfs_cache_work ,
247+ dfs_cache_get_ttl () * HZ );
256248
257249out :
258250 kfree (origin_fullpath );
251+ ref_walk_free (rw );
259252 return rc ;
260253}
261254
@@ -279,7 +272,7 @@ static int update_fs_context_dstaddr(struct smb3_fs_context *ctx)
279272 return rc ;
280273}
281274
282- int dfs_mount_share (struct cifs_mount_ctx * mnt_ctx , bool * isdfs )
275+ int dfs_mount_share (struct cifs_mount_ctx * mnt_ctx )
283276{
284277 struct smb3_fs_context * ctx = mnt_ctx -> fs_ctx ;
285278 bool nodfs = ctx -> nodfs ;
@@ -289,7 +282,6 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs)
289282 if (rc )
290283 return rc ;
291284
292- * isdfs = false;
293285 rc = get_session (mnt_ctx , NULL );
294286 if (rc )
295287 return rc ;
@@ -317,10 +309,15 @@ int dfs_mount_share(struct cifs_mount_ctx *mnt_ctx, bool *isdfs)
317309 return rc ;
318310 }
319311
320- * isdfs = true;
321- add_root_smb_session (mnt_ctx );
322- rc = __dfs_mount_share (mnt_ctx );
323- dfs_put_root_smb_sessions (mnt_ctx );
312+ if (!ctx -> dfs_conn ) {
313+ ctx -> dfs_conn = true;
314+ cifs_mount_put_conns (mnt_ctx );
315+ rc = get_session (mnt_ctx , NULL );
316+ }
317+ if (!rc ) {
318+ set_root_smb_session (mnt_ctx );
319+ rc = __dfs_mount_share (mnt_ctx );
320+ }
324321 return rc ;
325322}
326323
0 commit comments