xref: /linux/fs/smb/client/dfs_cache.c (revision 7db28abbea0f7dc1ec4fdfdc149db5fbd9e4c994)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * DFS referral cache routines
4  *
5  * Copyright (c) 2018-2019 Paulo Alcantara <palcantara@suse.de>
6  */
7 
8 #include <linux/jhash.h>
9 #include <linux/ktime.h>
10 #include <linux/slab.h>
11 #include <linux/proc_fs.h>
12 #include <linux/nls.h>
13 #include <linux/workqueue.h>
14 #include <linux/uuid.h>
15 #include "cifsglob.h"
16 #include "smb2pdu.h"
17 #include "smb2proto.h"
18 #include "cifsproto.h"
19 #include "cifs_debug.h"
20 #include "cifs_unicode.h"
21 #include "smb2glob.h"
22 #include "dns_resolve.h"
23 #include "dfs.h"
24 
25 #include "dfs_cache.h"
26 
27 #define CACHE_HTABLE_SIZE	512
28 #define CACHE_MAX_ENTRIES	1024
29 #define CACHE_MIN_TTL		120 /* 2 minutes */
30 #define CACHE_DEFAULT_TTL	300 /* 5 minutes */
31 
32 struct cache_dfs_tgt {
33 	char *name;
34 	int path_consumed;
35 	struct list_head list;
36 };
37 
38 struct cache_entry {
39 	struct hlist_node hlist;
40 	const char *path;
41 	int hdr_flags; /* RESP_GET_DFS_REFERRAL.ReferralHeaderFlags */
42 	int ttl; /* DFS_REREFERRAL_V3.TimeToLive */
43 	int srvtype; /* DFS_REREFERRAL_V3.ServerType */
44 	int ref_flags; /* DFS_REREFERRAL_V3.ReferralEntryFlags */
45 	struct timespec64 etime;
46 	int path_consumed; /* RESP_GET_DFS_REFERRAL.PathConsumed */
47 	int numtgts;
48 	struct list_head tlist;
49 	struct cache_dfs_tgt *tgthint;
50 };
51 
52 static struct kmem_cache *cache_slab __read_mostly;
53 struct workqueue_struct *dfscache_wq;
54 
55 atomic_t dfs_cache_ttl;
56 
57 static struct nls_table *cache_cp;
58 
59 /*
60  * Number of entries in the cache
61  */
62 static atomic_t cache_count;
63 
64 static struct hlist_head cache_htable[CACHE_HTABLE_SIZE];
65 static DECLARE_RWSEM(htable_rw_lock);
66 
67 /**
68  * dfs_cache_canonical_path - get a canonical DFS path
69  *
70  * @path: DFS path
71  * @cp: codepage
72  * @remap: mapping type
73  *
74  * Return canonical path if success, otherwise error.
75  */
76 char *dfs_cache_canonical_path(const char *path, const struct nls_table *cp, int remap)
77 {
78 	char *tmp;
79 	int plen = 0;
80 	char *npath;
81 
82 	if (!path || strlen(path) < 3 || (*path != '\\' && *path != '/'))
83 		return ERR_PTR(-EINVAL);
84 
85 	if (unlikely(strcmp(cp->charset, cache_cp->charset))) {
86 		tmp = (char *)cifs_strndup_to_utf16(path, strlen(path), &plen, cp, remap);
87 		if (!tmp) {
88 			cifs_dbg(VFS, "%s: failed to convert path to utf16\n", __func__);
89 			return ERR_PTR(-EINVAL);
90 		}
91 
92 		npath = cifs_strndup_from_utf16(tmp, plen, true, cache_cp);
93 		kfree(tmp);
94 
95 		if (!npath) {
96 			cifs_dbg(VFS, "%s: failed to convert path from utf16\n", __func__);
97 			return ERR_PTR(-EINVAL);
98 		}
99 	} else {
100 		npath = kstrdup(path, GFP_KERNEL);
101 		if (!npath)
102 			return ERR_PTR(-ENOMEM);
103 	}
104 	convert_delimiter(npath, '\\');
105 	return npath;
106 }
107 
108 static inline bool cache_entry_expired(const struct cache_entry *ce)
109 {
110 	struct timespec64 ts;
111 
112 	ktime_get_coarse_real_ts64(&ts);
113 	return timespec64_compare(&ts, &ce->etime) >= 0;
114 }
115 
116 static inline void free_tgts(struct cache_entry *ce)
117 {
118 	struct cache_dfs_tgt *t, *n;
119 
120 	list_for_each_entry_safe(t, n, &ce->tlist, list) {
121 		list_del(&t->list);
122 		kfree(t->name);
123 		kfree(t);
124 	}
125 
126 	WRITE_ONCE(ce->tgthint, NULL);
127 }
128 
129 static inline void flush_cache_ent(struct cache_entry *ce)
130 {
131 	cifs_dbg(FYI, "%s: %s\n", __func__, ce->path);
132 	hlist_del_init(&ce->hlist);
133 	kfree(ce->path);
134 	free_tgts(ce);
135 	atomic_dec(&cache_count);
136 	kmem_cache_free(cache_slab, ce);
137 }
138 
139 static void flush_cache_ents(void)
140 {
141 	int i;
142 
143 	for (i = 0; i < CACHE_HTABLE_SIZE; i++) {
144 		struct hlist_head *l = &cache_htable[i];
145 		struct hlist_node *n;
146 		struct cache_entry *ce;
147 
148 		hlist_for_each_entry_safe(ce, n, l, hlist) {
149 			if (!hlist_unhashed(&ce->hlist))
150 				flush_cache_ent(ce);
151 		}
152 	}
153 }
154 
155 /*
156  * dfs cache /proc file
157  */
158 static int dfscache_proc_show(struct seq_file *m, void *v)
159 {
160 	int i;
161 	struct cache_entry *ce;
162 	struct cache_dfs_tgt *t;
163 
164 	seq_puts(m, "DFS cache\n---------\n");
165 
166 	down_read(&htable_rw_lock);
167 	for (i = 0; i < CACHE_HTABLE_SIZE; i++) {
168 		struct hlist_head *l = &cache_htable[i];
169 
170 		hlist_for_each_entry(ce, l, hlist) {
171 			if (hlist_unhashed(&ce->hlist))
172 				continue;
173 
174 			seq_printf(m,
175 				   "cache entry: path=%s,type=%s,ttl=%d,etime=%ld,hdr_flags=0x%x,ref_flags=0x%x,interlink=%s,path_consumed=%d,expired=%s\n",
176 				   ce->path, ce->srvtype == DFS_TYPE_ROOT ? "root" : "link",
177 				   ce->ttl, ce->etime.tv_nsec, ce->hdr_flags, ce->ref_flags,
178 				   str_yes_no(DFS_INTERLINK(ce->hdr_flags)),
179 				   ce->path_consumed, str_yes_no(cache_entry_expired(ce)));
180 
181 			list_for_each_entry(t, &ce->tlist, list) {
182 				seq_printf(m, "  %s%s\n",
183 					   t->name,
184 					   READ_ONCE(ce->tgthint) == t ? " (target hint)" : "");
185 			}
186 		}
187 	}
188 	up_read(&htable_rw_lock);
189 
190 	return 0;
191 }
192 
193 static ssize_t dfscache_proc_write(struct file *file, const char __user *buffer,
194 				   size_t count, loff_t *ppos)
195 {
196 	char c;
197 	int rc;
198 
199 	rc = get_user(c, buffer);
200 	if (rc)
201 		return rc;
202 
203 	if (c != '0')
204 		return -EINVAL;
205 
206 	cifs_dbg(FYI, "clearing dfs cache\n");
207 
208 	down_write(&htable_rw_lock);
209 	flush_cache_ents();
210 	up_write(&htable_rw_lock);
211 
212 	return count;
213 }
214 
215 static int dfscache_proc_open(struct inode *inode, struct file *file)
216 {
217 	return single_open(file, dfscache_proc_show, NULL);
218 }
219 
220 const struct proc_ops dfscache_proc_ops = {
221 	.proc_open	= dfscache_proc_open,
222 	.proc_read	= seq_read,
223 	.proc_lseek	= seq_lseek,
224 	.proc_release	= single_release,
225 	.proc_write	= dfscache_proc_write,
226 };
227 
228 #ifdef CONFIG_CIFS_DEBUG2
229 static inline void dump_tgts(const struct cache_entry *ce)
230 {
231 	struct cache_dfs_tgt *t;
232 
233 	cifs_dbg(FYI, "target list:\n");
234 	list_for_each_entry(t, &ce->tlist, list) {
235 		cifs_dbg(FYI, "  %s%s\n", t->name,
236 			 READ_ONCE(ce->tgthint) == t ? " (target hint)" : "");
237 	}
238 }
239 
240 static inline void dump_ce(const struct cache_entry *ce)
241 {
242 	cifs_dbg(FYI, "cache entry: path=%s,type=%s,ttl=%d,etime=%ld,hdr_flags=0x%x,ref_flags=0x%x,interlink=%s,path_consumed=%d,expired=%s\n",
243 		 ce->path,
244 		 ce->srvtype == DFS_TYPE_ROOT ? "root" : "link", ce->ttl,
245 		 ce->etime.tv_nsec,
246 		 ce->hdr_flags, ce->ref_flags,
247 		 str_yes_no(DFS_INTERLINK(ce->hdr_flags)),
248 		 ce->path_consumed,
249 		 str_yes_no(cache_entry_expired(ce)));
250 	dump_tgts(ce);
251 }
252 
253 static inline void dump_refs(const struct dfs_info3_param *refs, int numrefs)
254 {
255 	int i;
256 
257 	cifs_dbg(FYI, "DFS referrals returned by the server:\n");
258 	for (i = 0; i < numrefs; i++) {
259 		const struct dfs_info3_param *ref = &refs[i];
260 
261 		cifs_dbg(FYI,
262 			 "\n"
263 			 "flags:         0x%x\n"
264 			 "path_consumed: %d\n"
265 			 "server_type:   0x%x\n"
266 			 "ref_flag:      0x%x\n"
267 			 "path_name:     %s\n"
268 			 "node_name:     %s\n"
269 			 "ttl:           %d (%dm)\n",
270 			 ref->flags, ref->path_consumed, ref->server_type,
271 			 ref->ref_flag, ref->path_name, ref->node_name,
272 			 ref->ttl, ref->ttl / 60);
273 	}
274 }
275 #else
276 #define dump_tgts(e)
277 #define dump_ce(e)
278 #define dump_refs(r, n)
279 #endif
280 
281 /**
282  * dfs_cache_init - Initialize DFS referral cache.
283  *
284  * Return zero if initialized successfully, otherwise non-zero.
285  */
286 int dfs_cache_init(void)
287 {
288 	int rc;
289 	int i;
290 
291 	dfscache_wq = alloc_workqueue("cifs-dfscache",
292 				      WQ_UNBOUND|WQ_FREEZABLE|WQ_MEM_RECLAIM,
293 				      0);
294 	if (!dfscache_wq)
295 		return -ENOMEM;
296 
297 	cache_slab = kmem_cache_create("cifs_dfs_cache",
298 				       sizeof(struct cache_entry), 0,
299 				       SLAB_HWCACHE_ALIGN, NULL);
300 	if (!cache_slab) {
301 		rc = -ENOMEM;
302 		goto out_destroy_wq;
303 	}
304 
305 	for (i = 0; i < CACHE_HTABLE_SIZE; i++)
306 		INIT_HLIST_HEAD(&cache_htable[i]);
307 
308 	atomic_set(&cache_count, 0);
309 	atomic_set(&dfs_cache_ttl, CACHE_DEFAULT_TTL);
310 	cache_cp = load_nls("utf8");
311 	if (!cache_cp)
312 		cache_cp = load_nls_default();
313 
314 	cifs_dbg(FYI, "%s: initialized DFS referral cache\n", __func__);
315 	return 0;
316 
317 out_destroy_wq:
318 	destroy_workqueue(dfscache_wq);
319 	return rc;
320 }
321 
322 static int cache_entry_hash(const void *data, int size, unsigned int *hash)
323 {
324 	int i, clen;
325 	const unsigned char *s = data;
326 	wchar_t c;
327 	unsigned int h = 0;
328 
329 	for (i = 0; i < size; i += clen) {
330 		clen = cache_cp->char2uni(&s[i], size - i, &c);
331 		if (unlikely(clen < 0)) {
332 			cifs_dbg(VFS, "%s: can't convert char\n", __func__);
333 			return clen;
334 		}
335 		c = cifs_toupper(c);
336 		h = jhash(&c, sizeof(c), h);
337 	}
338 	*hash = h % CACHE_HTABLE_SIZE;
339 	return 0;
340 }
341 
342 /* Return target hint of a DFS cache entry */
343 static inline char *get_tgt_name(const struct cache_entry *ce)
344 {
345 	struct cache_dfs_tgt *t = READ_ONCE(ce->tgthint);
346 
347 	return t ? t->name : ERR_PTR(-ENOENT);
348 }
349 
350 /* Return expire time out of a new entry's TTL */
351 static inline struct timespec64 get_expire_time(int ttl)
352 {
353 	struct timespec64 ts = {
354 		.tv_sec = ttl,
355 		.tv_nsec = 0,
356 	};
357 	struct timespec64 now;
358 
359 	ktime_get_coarse_real_ts64(&now);
360 	return timespec64_add(now, ts);
361 }
362 
363 /* Allocate a new DFS target */
364 static struct cache_dfs_tgt *alloc_target(const char *name, int path_consumed)
365 {
366 	struct cache_dfs_tgt *t;
367 
368 	t = kmalloc_obj(*t, GFP_KERNEL);
369 	if (!t)
370 		return ERR_PTR(-ENOMEM);
371 	t->name = kstrdup(name, GFP_KERNEL);
372 	if (!t->name) {
373 		kfree(t);
374 		return ERR_PTR(-ENOMEM);
375 	}
376 	t->path_consumed = path_consumed;
377 	INIT_LIST_HEAD(&t->list);
378 	return t;
379 }
380 
381 /*
382  * Copy DFS referral information to a cache entry and conditionally update
383  * target hint.
384  */
385 static int copy_ref_data(const struct dfs_info3_param *refs, int numrefs,
386 			 struct cache_entry *ce, const char *tgthint)
387 {
388 	struct cache_dfs_tgt *target;
389 	int i;
390 
391 	ce->ttl = max_t(int, refs[0].ttl, CACHE_MIN_TTL);
392 	ce->etime = get_expire_time(ce->ttl);
393 	ce->srvtype = refs[0].server_type;
394 	ce->hdr_flags = refs[0].flags;
395 	ce->ref_flags = refs[0].ref_flag;
396 	ce->path_consumed = refs[0].path_consumed;
397 
398 	for (i = 0; i < numrefs; i++) {
399 		struct cache_dfs_tgt *t;
400 
401 		t = alloc_target(refs[i].node_name, refs[i].path_consumed);
402 		if (IS_ERR(t)) {
403 			free_tgts(ce);
404 			return PTR_ERR(t);
405 		}
406 		if (tgthint && !strcasecmp(t->name, tgthint)) {
407 			list_add(&t->list, &ce->tlist);
408 			tgthint = NULL;
409 		} else {
410 			list_add_tail(&t->list, &ce->tlist);
411 		}
412 		ce->numtgts++;
413 	}
414 
415 	target = list_first_entry_or_null(&ce->tlist, struct cache_dfs_tgt,
416 					  list);
417 	WRITE_ONCE(ce->tgthint, target);
418 
419 	return 0;
420 }
421 
422 /* Allocate a new cache entry */
423 static struct cache_entry *alloc_cache_entry(struct dfs_info3_param *refs, int numrefs)
424 {
425 	struct cache_entry *ce;
426 	int rc;
427 
428 	ce = kmem_cache_zalloc(cache_slab, GFP_KERNEL);
429 	if (!ce)
430 		return ERR_PTR(-ENOMEM);
431 
432 	ce->path = refs[0].path_name;
433 	refs[0].path_name = NULL;
434 
435 	INIT_HLIST_NODE(&ce->hlist);
436 	INIT_LIST_HEAD(&ce->tlist);
437 
438 	rc = copy_ref_data(refs, numrefs, ce, NULL);
439 	if (rc) {
440 		kfree(ce->path);
441 		kmem_cache_free(cache_slab, ce);
442 		ce = ERR_PTR(rc);
443 	}
444 	return ce;
445 }
446 
447 /* Remove all referrals that have a single target or oldest entry */
448 static void purge_cache(void)
449 {
450 	int i;
451 	struct cache_entry *ce;
452 	struct cache_entry *oldest = NULL;
453 
454 	for (i = 0; i < CACHE_HTABLE_SIZE; i++) {
455 		struct hlist_head *l = &cache_htable[i];
456 		struct hlist_node *n;
457 
458 		hlist_for_each_entry_safe(ce, n, l, hlist) {
459 			if (hlist_unhashed(&ce->hlist))
460 				continue;
461 			if (ce->numtgts == 1)
462 				flush_cache_ent(ce);
463 			else if (!oldest ||
464 				 timespec64_compare(&ce->etime,
465 						    &oldest->etime) < 0)
466 				oldest = ce;
467 		}
468 	}
469 
470 	if (atomic_read(&cache_count) >= CACHE_MAX_ENTRIES && oldest)
471 		flush_cache_ent(oldest);
472 }
473 
474 /* Add a new DFS cache entry */
475 static struct cache_entry *add_cache_entry_locked(struct dfs_info3_param *refs,
476 						  int numrefs)
477 {
478 	int rc;
479 	struct cache_entry *ce;
480 	unsigned int hash;
481 	int ttl;
482 
483 	WARN_ON(!rwsem_is_locked(&htable_rw_lock));
484 
485 	if (atomic_read(&cache_count) >= CACHE_MAX_ENTRIES) {
486 		cifs_dbg(FYI, "%s: reached max cache size (%d)\n", __func__, CACHE_MAX_ENTRIES);
487 		purge_cache();
488 	}
489 
490 	rc = cache_entry_hash(refs[0].path_name, strlen(refs[0].path_name), &hash);
491 	if (rc)
492 		return ERR_PTR(rc);
493 
494 	ce = alloc_cache_entry(refs, numrefs);
495 	if (IS_ERR(ce))
496 		return ce;
497 
498 	ttl = min_t(int, atomic_read(&dfs_cache_ttl), ce->ttl);
499 	atomic_set(&dfs_cache_ttl, ttl);
500 
501 	hlist_add_head(&ce->hlist, &cache_htable[hash]);
502 	dump_ce(ce);
503 
504 	atomic_inc(&cache_count);
505 
506 	return ce;
507 }
508 
509 /* Check if two DFS paths are equal.  @s1 and @s2 are expected to be in @cache_cp's charset */
510 static bool dfs_path_equal(const char *s1, int len1, const char *s2, int len2)
511 {
512 	int i, l1, l2;
513 	wchar_t c1, c2;
514 
515 	if (len1 != len2)
516 		return false;
517 
518 	for (i = 0; i < len1; i += l1) {
519 		l1 = cache_cp->char2uni(&s1[i], len1 - i, &c1);
520 		l2 = cache_cp->char2uni(&s2[i], len2 - i, &c2);
521 		if (unlikely(l1 < 0 && l2 < 0)) {
522 			if (s1[i] != s2[i])
523 				return false;
524 			l1 = 1;
525 			continue;
526 		}
527 		if (l1 != l2)
528 			return false;
529 		if (cifs_toupper(c1) != cifs_toupper(c2))
530 			return false;
531 	}
532 	return true;
533 }
534 
535 static struct cache_entry *__lookup_cache_entry(const char *path, unsigned int hash, int len)
536 {
537 	struct cache_entry *ce;
538 
539 	hlist_for_each_entry(ce, &cache_htable[hash], hlist) {
540 		if (dfs_path_equal(ce->path, strlen(ce->path), path, len)) {
541 			dump_ce(ce);
542 			return ce;
543 		}
544 	}
545 	return ERR_PTR(-ENOENT);
546 }
547 
548 /*
549  * Find a DFS cache entry in hash table and optionally check prefix path against normalized @path.
550  *
551  * Use whole path components in the match.  Must be called with htable_rw_lock held.
552  *
553  * Return cached entry if successful.
554  * Return ERR_PTR(-ENOENT) if the entry is not found.
555  * Return error ptr otherwise.
556  */
557 static struct cache_entry *lookup_cache_entry(const char *path)
558 {
559 	struct cache_entry *ce;
560 	int cnt = 0;
561 	const char *s = path, *e;
562 	char sep = *s;
563 	unsigned int hash;
564 	int rc;
565 
566 	while ((s = strchr(s, sep)) && ++cnt < 3)
567 		s++;
568 
569 	if (cnt < 3) {
570 		rc = cache_entry_hash(path, strlen(path), &hash);
571 		if (rc)
572 			return ERR_PTR(rc);
573 		return __lookup_cache_entry(path, hash, strlen(path));
574 	}
575 	/*
576 	 * Handle paths that have more than two path components and are a complete prefix of the DFS
577 	 * referral request path (@path).
578 	 *
579 	 * See MS-DFSC 3.2.5.5 "Receiving a Root Referral Request or Link Referral Request".
580 	 */
581 	e = path + strlen(path) - 1;
582 	while (e > s) {
583 		int len;
584 
585 		/* skip separators */
586 		while (e > s && *e == sep)
587 			e--;
588 		if (e == s)
589 			break;
590 
591 		len = e + 1 - path;
592 		rc = cache_entry_hash(path, len, &hash);
593 		if (rc)
594 			return ERR_PTR(rc);
595 		ce = __lookup_cache_entry(path, hash, len);
596 		if (!IS_ERR(ce))
597 			return ce;
598 
599 		/* backward until separator */
600 		while (e > s && *e != sep)
601 			e--;
602 	}
603 	return ERR_PTR(-ENOENT);
604 }
605 
606 /**
607  * dfs_cache_destroy - destroy DFS referral cache
608  */
609 void dfs_cache_destroy(void)
610 {
611 	unload_nls(cache_cp);
612 	flush_cache_ents();
613 	kmem_cache_destroy(cache_slab);
614 	destroy_workqueue(dfscache_wq);
615 
616 	cifs_dbg(FYI, "%s: destroyed DFS referral cache\n", __func__);
617 }
618 
619 /* Update a cache entry with the new referral in @refs */
620 static int update_cache_entry_locked(struct cache_entry *ce, const struct dfs_info3_param *refs,
621 				     int numrefs)
622 {
623 	struct cache_dfs_tgt *target;
624 	char *th = NULL;
625 	int rc;
626 
627 	WARN_ON(!rwsem_is_locked(&htable_rw_lock));
628 
629 	target = READ_ONCE(ce->tgthint);
630 	if (target) {
631 		th = kstrdup(target->name, GFP_KERNEL);
632 		if (!th)
633 			return -ENOMEM;
634 	}
635 
636 	free_tgts(ce);
637 	ce->numtgts = 0;
638 
639 	rc = copy_ref_data(refs, numrefs, ce, th);
640 
641 	kfree(th);
642 
643 	return rc;
644 }
645 
646 static int get_dfs_referral(const unsigned int xid, struct cifs_ses *ses, const char *path,
647 			    struct dfs_info3_param **refs, int *numrefs)
648 {
649 	int rc;
650 	int i;
651 
652 	*refs = NULL;
653 	*numrefs = 0;
654 
655 	if (!ses || !ses->server || !ses->server->ops->get_dfs_refer)
656 		return -EOPNOTSUPP;
657 	if (unlikely(!cache_cp))
658 		return -EINVAL;
659 
660 	cifs_dbg(FYI, "%s: ipc=%s referral=%s\n", __func__, ses->tcon_ipc->tree_name, path);
661 	rc =  ses->server->ops->get_dfs_refer(xid, ses, path, refs, numrefs, cache_cp,
662 					      NO_MAP_UNI_RSVD);
663 	if (!rc) {
664 		struct dfs_info3_param *ref = *refs;
665 
666 		for (i = 0; i < *numrefs; i++)
667 			convert_delimiter(ref[i].path_name, '\\');
668 	}
669 	return rc;
670 }
671 
672 /*
673  * Find, create or update a DFS cache entry.
674  *
675  * If the entry wasn't found, it will create a new one. Or if it was found but
676  * expired, then it will update the entry accordingly.
677  *
678  * For interlinks, cifs_mount() and expand_dfs_referral() are supposed to
679  * handle them properly.
680  *
681  * On success, return entry with acquired lock for reading, otherwise error ptr.
682  */
683 static struct cache_entry *cache_refresh_path(const unsigned int xid,
684 					      struct cifs_ses *ses,
685 					      const char *path,
686 					      bool force_refresh)
687 {
688 	struct dfs_info3_param *refs = NULL;
689 	struct cache_entry *ce;
690 	int numrefs = 0;
691 	int rc;
692 
693 	cifs_dbg(FYI, "%s: search path: %s\n", __func__, path);
694 
695 	down_read(&htable_rw_lock);
696 
697 	ce = lookup_cache_entry(path);
698 	if (!IS_ERR(ce)) {
699 		if (!force_refresh && !cache_entry_expired(ce))
700 			return ce;
701 	} else if (PTR_ERR(ce) != -ENOENT) {
702 		up_read(&htable_rw_lock);
703 		return ce;
704 	}
705 
706 	/*
707 	 * Unlock shared access as we don't want to hold any locks while getting
708 	 * a new referral.  The @ses used for performing the I/O could be
709 	 * reconnecting and it acquires @htable_rw_lock to look up the dfs cache
710 	 * in order to failover -- if necessary.
711 	 */
712 	up_read(&htable_rw_lock);
713 
714 	/*
715 	 * Either the entry was not found, or it is expired, or it is a forced
716 	 * refresh.
717 	 * Request a new DFS referral in order to create or update a cache entry.
718 	 */
719 	rc = get_dfs_referral(xid, ses, path, &refs, &numrefs);
720 	if (rc) {
721 		ce = ERR_PTR(rc);
722 		goto out;
723 	}
724 
725 	dump_refs(refs, numrefs);
726 
727 	down_write(&htable_rw_lock);
728 	/* Re-check as another task might have it added or refreshed already */
729 	ce = lookup_cache_entry(path);
730 	if (!IS_ERR(ce)) {
731 		if (force_refresh || cache_entry_expired(ce)) {
732 			rc = update_cache_entry_locked(ce, refs, numrefs);
733 			if (rc)
734 				ce = ERR_PTR(rc);
735 		}
736 	} else if (PTR_ERR(ce) == -ENOENT) {
737 		ce = add_cache_entry_locked(refs, numrefs);
738 	}
739 
740 	if (IS_ERR(ce)) {
741 		up_write(&htable_rw_lock);
742 		goto out;
743 	}
744 
745 	downgrade_write(&htable_rw_lock);
746 out:
747 	free_dfs_info_array(refs, numrefs);
748 	return ce;
749 }
750 
751 /*
752  * Set up a DFS referral from a given cache entry.
753  *
754  * Must be called with htable_rw_lock held.
755  */
756 static int setup_referral(const char *path, struct cache_entry *ce,
757 			  struct dfs_info3_param *ref, const char *target)
758 {
759 	int rc;
760 
761 	cifs_dbg(FYI, "%s: set up new ref\n", __func__);
762 
763 	memset(ref, 0, sizeof(*ref));
764 
765 	ref->path_name = kstrdup(path, GFP_KERNEL);
766 	if (!ref->path_name)
767 		return -ENOMEM;
768 
769 	ref->node_name = kstrdup(target, GFP_KERNEL);
770 	if (!ref->node_name) {
771 		rc = -ENOMEM;
772 		goto err_free_path;
773 	}
774 
775 	ref->path_consumed = ce->path_consumed;
776 	ref->ttl = ce->ttl;
777 	ref->server_type = ce->srvtype;
778 	ref->ref_flag = ce->ref_flags;
779 	ref->flags = ce->hdr_flags;
780 
781 	return 0;
782 
783 err_free_path:
784 	kfree(ref->path_name);
785 	ref->path_name = NULL;
786 	return rc;
787 }
788 
789 /* Return target list of a DFS cache entry */
790 static int get_targets(struct cache_entry *ce, struct dfs_cache_tgt_list *tl)
791 {
792 	int rc;
793 	struct list_head *head = &tl->tl_list;
794 	struct cache_dfs_tgt *t;
795 	struct dfs_cache_tgt_iterator *it, *nit;
796 
797 	memset(tl, 0, sizeof(*tl));
798 	INIT_LIST_HEAD(head);
799 
800 	list_for_each_entry(t, &ce->tlist, list) {
801 		it = kzalloc_obj(*it, GFP_ATOMIC);
802 		if (!it) {
803 			rc = -ENOMEM;
804 			goto err_free_it;
805 		}
806 
807 		it->it_name = kstrdup(t->name, GFP_ATOMIC);
808 		if (!it->it_name) {
809 			kfree(it);
810 			rc = -ENOMEM;
811 			goto err_free_it;
812 		}
813 		it->it_path_consumed = t->path_consumed;
814 
815 		if (READ_ONCE(ce->tgthint) == t)
816 			list_add(&it->it_list, head);
817 		else
818 			list_add_tail(&it->it_list, head);
819 	}
820 
821 	tl->tl_numtgts = ce->numtgts;
822 
823 	return 0;
824 
825 err_free_it:
826 	list_for_each_entry_safe(it, nit, head, it_list) {
827 		list_del(&it->it_list);
828 		kfree(it->it_name);
829 		kfree(it);
830 	}
831 	return rc;
832 }
833 
834 /**
835  * dfs_cache_find - find a DFS cache entry
836  *
837  * If it doesn't find the cache entry, then it will get a DFS referral
838  * for @path and create a new entry.
839  *
840  * In case the cache entry exists but expired, it will get a DFS referral
841  * for @path and then update the respective cache entry.
842  *
843  * These parameters are passed down to the get_dfs_refer() call if it
844  * needs to be issued:
845  * @xid: syscall xid
846  * @ses: smb session to issue the request on
847  * @cp: codepage
848  * @remap: path character remapping type
849  * @path: path to lookup in DFS referral cache.
850  *
851  * @ref: when non-NULL, store single DFS referral result in it.
852  * @tgt_list: when non-NULL, store complete DFS target list in it.
853  *
854  * Return zero if the target was found, otherwise non-zero.
855  */
856 int dfs_cache_find(const unsigned int xid, struct cifs_ses *ses, const struct nls_table *cp,
857 		   int remap, const char *path, struct dfs_info3_param *ref,
858 		   struct dfs_cache_tgt_list *tgt_list)
859 {
860 	int rc;
861 	const char *npath;
862 	struct cache_entry *ce;
863 
864 	npath = dfs_cache_canonical_path(path, cp, remap);
865 	if (IS_ERR(npath))
866 		return PTR_ERR(npath);
867 
868 	ce = cache_refresh_path(xid, ses, npath, false);
869 	if (IS_ERR(ce)) {
870 		rc = PTR_ERR(ce);
871 		goto out_free_path;
872 	}
873 
874 	if (ref) {
875 		char *target = get_tgt_name(ce);
876 
877 		if (IS_ERR(target)) {
878 			rc = PTR_ERR(target);
879 			goto out_unlock;
880 		}
881 		rc = setup_referral(path, ce, ref, target);
882 	} else {
883 		rc = 0;
884 	}
885 
886 	if (!rc && tgt_list)
887 		rc = get_targets(ce, tgt_list);
888 
889 out_unlock:
890 	up_read(&htable_rw_lock);
891 
892 out_free_path:
893 	kfree(npath);
894 	return rc;
895 }
896 
897 /**
898  * dfs_cache_noreq_find - find a DFS cache entry without sending any requests to
899  * the currently connected server.
900  *
901  * NOTE: This function will neither update a cache entry in case it was
902  * expired, nor create a new cache entry if @path hasn't been found. It heavily
903  * relies on an existing cache entry.
904  *
905  * @path: canonical DFS path to lookup in the DFS referral cache.
906  * @ref: when non-NULL, store single DFS referral result in it.
907  * @tgt_list: when non-NULL, store complete DFS target list in it.
908  *
909  * Return 0 if successful.
910  * Return -ENOENT if the entry was not found.
911  * Return non-zero for other errors.
912  */
913 int dfs_cache_noreq_find(const char *path, struct dfs_info3_param *ref,
914 			 struct dfs_cache_tgt_list *tgt_list)
915 {
916 	int rc;
917 	struct cache_entry *ce;
918 
919 	cifs_dbg(FYI, "%s: path: %s\n", __func__, path);
920 
921 	down_read(&htable_rw_lock);
922 
923 	ce = lookup_cache_entry(path);
924 	if (IS_ERR(ce)) {
925 		rc = PTR_ERR(ce);
926 		goto out_unlock;
927 	}
928 
929 	if (ref) {
930 		char *target = get_tgt_name(ce);
931 
932 		if (IS_ERR(target)) {
933 			rc = PTR_ERR(target);
934 			goto out_unlock;
935 		}
936 		rc = setup_referral(path, ce, ref, target);
937 	} else {
938 		rc = 0;
939 	}
940 	if (!rc && tgt_list)
941 		rc = get_targets(ce, tgt_list);
942 
943 out_unlock:
944 	up_read(&htable_rw_lock);
945 	return rc;
946 }
947 
948 /**
949  * dfs_cache_noreq_update_tgthint - update target hint of a DFS cache entry
950  * without sending any requests to the currently connected server.
951  *
952  * NOTE: This function will neither update a cache entry in case it was
953  * expired, nor create a new cache entry if @path hasn't been found. It heavily
954  * relies on an existing cache entry.
955  *
956  * @path: canonical DFS path to lookup in DFS referral cache.
957  * @it: target iterator which contains the target hint to update the cache
958  * entry with.
959  *
960  * Return zero if the target hint was updated successfully, otherwise non-zero.
961  */
962 void dfs_cache_noreq_update_tgthint(const char *path, const struct dfs_cache_tgt_iterator *it)
963 {
964 	struct cache_dfs_tgt *t;
965 	struct cache_entry *ce;
966 
967 	if (!path || !it)
968 		return;
969 
970 	cifs_dbg(FYI, "%s: path: %s\n", __func__, path);
971 
972 	down_read(&htable_rw_lock);
973 
974 	ce = lookup_cache_entry(path);
975 	if (IS_ERR(ce))
976 		goto out_unlock;
977 
978 	t = READ_ONCE(ce->tgthint);
979 
980 	/* Check 't' in case ce->tgthint was cleared by free_tgts() */
981 	if (t && unlikely(!strcasecmp(it->it_name, t->name)))
982 		goto out_unlock;
983 
984 	list_for_each_entry(t, &ce->tlist, list) {
985 		if (!strcasecmp(t->name, it->it_name)) {
986 			WRITE_ONCE(ce->tgthint, t);
987 			cifs_dbg(FYI, "%s: new target hint: %s\n", __func__,
988 				 it->it_name);
989 			break;
990 		}
991 	}
992 
993 out_unlock:
994 	up_read(&htable_rw_lock);
995 }
996 
997 /**
998  * dfs_cache_get_tgt_referral - returns a DFS referral (@ref) from a given
999  * target iterator (@it).
1000  *
1001  * @path: canonical DFS path to lookup in DFS referral cache.
1002  * @it: DFS target iterator.
1003  * @ref: DFS referral pointer to set up the gathered information.
1004  *
1005  * Return zero if the DFS referral was set up correctly, otherwise non-zero.
1006  */
1007 int dfs_cache_get_tgt_referral(const char *path, const struct dfs_cache_tgt_iterator *it,
1008 			       struct dfs_info3_param *ref)
1009 {
1010 	int rc;
1011 	struct cache_entry *ce;
1012 
1013 	if (!it || !ref)
1014 		return -EINVAL;
1015 
1016 	cifs_dbg(FYI, "%s: path: %s\n", __func__, path);
1017 
1018 	down_read(&htable_rw_lock);
1019 
1020 	ce = lookup_cache_entry(path);
1021 	if (IS_ERR(ce)) {
1022 		rc = PTR_ERR(ce);
1023 		goto out_unlock;
1024 	}
1025 
1026 	cifs_dbg(FYI, "%s: target name: %s\n", __func__, it->it_name);
1027 
1028 	rc = setup_referral(path, ce, ref, it->it_name);
1029 
1030 out_unlock:
1031 	up_read(&htable_rw_lock);
1032 	return rc;
1033 }
1034 
1035 /* Extract share from DFS target and return a pointer to prefix path or NULL */
1036 static const char *parse_target_share(const char *target, char **share)
1037 {
1038 	const char *s, *seps = "/\\";
1039 	size_t len;
1040 
1041 	s = strpbrk(target + 1, seps);
1042 	if (!s)
1043 		return ERR_PTR(-EINVAL);
1044 
1045 	len = strcspn(s + 1, seps);
1046 	if (!len)
1047 		return ERR_PTR(-EINVAL);
1048 	s += len;
1049 
1050 	len = s - target + 1;
1051 	*share = kstrndup(target, len, GFP_KERNEL);
1052 	if (!*share)
1053 		return ERR_PTR(-ENOMEM);
1054 
1055 	s = target + len;
1056 	return s + strspn(s, seps);
1057 }
1058 
1059 /**
1060  * dfs_cache_get_tgt_share - parse a DFS target
1061  *
1062  * @path: DFS full path
1063  * @it: DFS target iterator.
1064  * @share: tree name.
1065  * @prefix: prefix path.
1066  *
1067  * Return zero if target was parsed correctly, otherwise non-zero.
1068  */
1069 int dfs_cache_get_tgt_share(char *path, const struct dfs_cache_tgt_iterator *it, char **share,
1070 			    char **prefix)
1071 {
1072 	char sep;
1073 	char *target_share;
1074 	char *ppath = NULL;
1075 	const char *target_ppath, *dfsref_ppath;
1076 	size_t target_pplen, dfsref_pplen;
1077 	size_t len, c;
1078 
1079 	if (!it || !path || !share || !prefix || strlen(path) < it->it_path_consumed)
1080 		return -EINVAL;
1081 
1082 	sep = it->it_name[0];
1083 	if (sep != '\\' && sep != '/')
1084 		return -EINVAL;
1085 
1086 	target_ppath = parse_target_share(it->it_name, &target_share);
1087 	if (IS_ERR(target_ppath))
1088 		return PTR_ERR(target_ppath);
1089 
1090 	/* point to prefix in DFS referral path */
1091 	dfsref_ppath = path + it->it_path_consumed;
1092 	dfsref_ppath += strspn(dfsref_ppath, "/\\");
1093 
1094 	target_pplen = strlen(target_ppath);
1095 	dfsref_pplen = strlen(dfsref_ppath);
1096 
1097 	/* merge prefix paths from DFS referral path and target node */
1098 	if (target_pplen || dfsref_pplen) {
1099 		len = target_pplen + dfsref_pplen + 2;
1100 		ppath = kzalloc(len, GFP_KERNEL);
1101 		if (!ppath) {
1102 			kfree(target_share);
1103 			return -ENOMEM;
1104 		}
1105 		c = strscpy(ppath, target_ppath, len);
1106 		if (c && dfsref_pplen)
1107 			ppath[c] = sep;
1108 		strlcat(ppath, dfsref_ppath, len);
1109 	}
1110 	*share = target_share;
1111 	*prefix = ppath;
1112 	return 0;
1113 }
1114 
1115 static bool target_share_equal(struct cifs_tcon *tcon, const char *s1)
1116 {
1117 	struct TCP_Server_Info *server = tcon->ses->server;
1118 	const char *s2 = &tcon->tree_name[1];
1119 	struct sockaddr_storage ss;
1120 	bool match;
1121 	int rc;
1122 
1123 	if (strcasecmp(s2, s1))
1124 		return false;
1125 
1126 	/*
1127 	 * Resolve share's hostname and check if server address matches.  Otherwise just ignore it
1128 	 * as we could not have upcall to resolve hostname or failed to convert ip address.
1129 	 */
1130 	rc = dns_resolve_unc(server->dns_dom, s1, (struct sockaddr *)&ss);
1131 	if (rc < 0)
1132 		return true;
1133 
1134 	cifs_server_lock(server);
1135 	match = cifs_match_ipaddr((struct sockaddr *)&server->dstaddr, (struct sockaddr *)&ss);
1136 	cifs_dbg(FYI, "%s: [share=%s] ipaddr matched: %s\n", __func__, s1, str_yes_no(match));
1137 	cifs_server_unlock(server);
1138 
1139 	return match;
1140 }
1141 
1142 static bool is_ses_good(struct cifs_tcon *tcon, struct cifs_ses *ses)
1143 {
1144 	struct TCP_Server_Info *server = ses->server;
1145 	struct cifs_tcon *ipc = NULL;
1146 	bool ret;
1147 
1148 	spin_lock(&cifs_tcp_ses_lock);
1149 	spin_lock(&ses->ses_lock);
1150 	spin_lock(&ses->chan_lock);
1151 
1152 	ret = !cifs_chan_needs_reconnect(ses, server) &&
1153 		ses->ses_status == SES_GOOD;
1154 
1155 	spin_unlock(&ses->chan_lock);
1156 
1157 	if (!ret)
1158 		goto out;
1159 
1160 	if (likely(ses->tcon_ipc)) {
1161 		if (ses->tcon_ipc->need_reconnect) {
1162 			ret = false;
1163 			goto out;
1164 		}
1165 	} else {
1166 		spin_unlock(&ses->ses_lock);
1167 		spin_unlock(&cifs_tcp_ses_lock);
1168 
1169 		ipc = cifs_setup_ipc(ses, tcon->seal);
1170 
1171 		spin_lock(&cifs_tcp_ses_lock);
1172 		spin_lock(&ses->ses_lock);
1173 		if (!IS_ERR(ipc)) {
1174 			if (!ses->tcon_ipc) {
1175 				ses->tcon_ipc = ipc;
1176 				ipc = NULL;
1177 			}
1178 		} else {
1179 			ret = false;
1180 			ipc = NULL;
1181 		}
1182 	}
1183 
1184 out:
1185 	spin_unlock(&ses->ses_lock);
1186 	spin_unlock(&cifs_tcp_ses_lock);
1187 	if (ipc && server->ops->tree_disconnect) {
1188 		unsigned int xid = get_xid();
1189 
1190 		(void)server->ops->tree_disconnect(xid, ipc);
1191 		_free_xid(xid);
1192 	}
1193 	tconInfoFree(ipc, netfs_trace_tcon_ref_free_ipc);
1194 	return ret;
1195 }
1196 
1197 /* Refresh dfs referral of @ses */
1198 static void refresh_ses_referral(struct cifs_tcon *tcon, struct cifs_ses *ses)
1199 {
1200 	struct cache_entry *ce;
1201 	unsigned int xid;
1202 	const char *path;
1203 	int rc = 0;
1204 
1205 	xid = get_xid();
1206 
1207 	path = dfs_ses_refpath(ses);
1208 	if (IS_ERR(path)) {
1209 		rc = PTR_ERR(path);
1210 		goto out;
1211 	}
1212 
1213 	ses = CIFS_DFS_ROOT_SES(ses);
1214 	if (!is_ses_good(tcon, ses)) {
1215 		cifs_dbg(FYI, "%s: skip cache refresh due to disconnected ipc\n",
1216 			 __func__);
1217 		goto out;
1218 	}
1219 
1220 	ce = cache_refresh_path(xid, ses, path, false);
1221 	if (!IS_ERR(ce))
1222 		up_read(&htable_rw_lock);
1223 	else
1224 		rc = PTR_ERR(ce);
1225 
1226 out:
1227 	free_xid(xid);
1228 }
1229 
1230 static int __refresh_tcon_referral(struct cifs_tcon *tcon,
1231 				   const char *path,
1232 				   struct dfs_info3_param *refs,
1233 				   int numrefs, bool force_refresh)
1234 {
1235 	struct cache_entry *ce;
1236 	bool reconnect = force_refresh;
1237 	int rc = 0;
1238 	int i;
1239 
1240 	if (unlikely(!numrefs))
1241 		return 0;
1242 
1243 	if (force_refresh) {
1244 		for (i = 0; i < numrefs; i++) {
1245 			/* TODO: include prefix paths in the matching */
1246 			if (target_share_equal(tcon, refs[i].node_name)) {
1247 				reconnect = false;
1248 				break;
1249 			}
1250 		}
1251 	}
1252 
1253 	down_write(&htable_rw_lock);
1254 	ce = lookup_cache_entry(path);
1255 	if (!IS_ERR(ce)) {
1256 		if (force_refresh || cache_entry_expired(ce))
1257 			rc = update_cache_entry_locked(ce, refs, numrefs);
1258 	} else if (PTR_ERR(ce) == -ENOENT) {
1259 		ce = add_cache_entry_locked(refs, numrefs);
1260 	}
1261 	up_write(&htable_rw_lock);
1262 
1263 	if (IS_ERR(ce))
1264 		rc = PTR_ERR(ce);
1265 	if (reconnect) {
1266 		cifs_tcon_dbg(FYI, "%s: mark for reconnect\n", __func__);
1267 		cifs_signal_cifsd_for_reconnect(tcon->ses->server, true);
1268 	}
1269 	return rc;
1270 }
1271 
1272 static void refresh_tcon_referral(struct cifs_tcon *tcon, bool force_refresh)
1273 {
1274 	struct dfs_info3_param *refs = NULL;
1275 	struct cache_entry *ce;
1276 	struct cifs_ses *ses;
1277 	bool needs_refresh;
1278 	const char *path;
1279 	unsigned int xid;
1280 	int numrefs = 0;
1281 	int rc = 0;
1282 
1283 	xid = get_xid();
1284 	ses = tcon->ses;
1285 
1286 	path = dfs_ses_refpath(ses);
1287 	if (IS_ERR(path)) {
1288 		rc = PTR_ERR(path);
1289 		goto out;
1290 	}
1291 
1292 	down_read(&htable_rw_lock);
1293 	ce = lookup_cache_entry(path);
1294 	needs_refresh = force_refresh || IS_ERR(ce) || cache_entry_expired(ce);
1295 	if (!needs_refresh) {
1296 		up_read(&htable_rw_lock);
1297 		goto out;
1298 	}
1299 	up_read(&htable_rw_lock);
1300 
1301 	ses = CIFS_DFS_ROOT_SES(ses);
1302 	if (!is_ses_good(tcon, ses)) {
1303 		cifs_dbg(FYI, "%s: skip cache refresh due to disconnected ipc\n",
1304 			 __func__);
1305 		goto out;
1306 	}
1307 
1308 	rc = get_dfs_referral(xid, ses, path, &refs, &numrefs);
1309 	if (!rc) {
1310 		rc = __refresh_tcon_referral(tcon, path, refs,
1311 					     numrefs, force_refresh);
1312 	}
1313 
1314 out:
1315 	free_xid(xid);
1316 	free_dfs_info_array(refs, numrefs);
1317 }
1318 
1319 /**
1320  * dfs_cache_remount_fs - remount a DFS share
1321  *
1322  * Reconfigure dfs mount by forcing a new DFS referral and if the currently cached targets do not
1323  * match any of the new targets, mark it for reconnect.
1324  *
1325  * @cifs_sb: cifs superblock.
1326  *
1327  * Return zero if remounted, otherwise non-zero.
1328  */
1329 int dfs_cache_remount_fs(struct cifs_sb_info *cifs_sb)
1330 {
1331 	struct cifs_tcon *tcon;
1332 
1333 	if (!cifs_sb || !cifs_sb->master_tlink)
1334 		return -EINVAL;
1335 
1336 	tcon = cifs_sb_master_tcon(cifs_sb);
1337 
1338 	spin_lock(&tcon->tc_lock);
1339 	if (!tcon->origin_fullpath) {
1340 		spin_unlock(&tcon->tc_lock);
1341 		cifs_dbg(FYI, "%s: not a dfs mount\n", __func__);
1342 		return 0;
1343 	}
1344 	spin_unlock(&tcon->tc_lock);
1345 
1346 	/*
1347 	 * After reconnecting to a different server, unique ids won't match anymore, so we disable
1348 	 * serverino. This prevents dentry revalidation to think the dentry are stale (ESTALE).
1349 	 */
1350 	cifs_autodisable_serverino(cifs_sb, "DFS failover may potentially connect to a different server, inode numbers won't match anymore", 0);
1351 	/*
1352 	 * Force the use of prefix path to support failover on DFS paths that resolve to targets
1353 	 * that have different prefix paths.
1354 	 */
1355 	atomic_or(CIFS_MOUNT_USE_PREFIX_PATH, &cifs_sb->mnt_cifs_flags);
1356 
1357 	refresh_tcon_referral(tcon, true);
1358 	return 0;
1359 }
1360 
1361 /* Refresh all DFS referrals related to DFS tcon */
1362 void dfs_cache_refresh(struct work_struct *work)
1363 {
1364 	struct cifs_tcon *tcon;
1365 	struct cifs_ses *ses;
1366 
1367 	tcon = container_of(work, struct cifs_tcon, dfs_cache_work.work);
1368 
1369 	list_for_each_entry(ses, &tcon->dfs_ses_list, dlist)
1370 		refresh_ses_referral(tcon, ses);
1371 	refresh_tcon_referral(tcon, false);
1372 
1373 	queue_delayed_work(dfscache_wq, &tcon->dfs_cache_work,
1374 			   atomic_read(&dfs_cache_ttl) * HZ);
1375 }
1376