cifs: reduce number of referral requests in DFS link lookups
[platform/kernel/linux-rpi.git] / fs / cifs / dfs_cache.c
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 "cifsglob.h"
15 #include "smb2pdu.h"
16 #include "smb2proto.h"
17 #include "cifsproto.h"
18 #include "cifs_debug.h"
19 #include "cifs_unicode.h"
20 #include "smb2glob.h"
21
22 #include "dfs_cache.h"
23
24 #define CACHE_HTABLE_SIZE 32
25 #define CACHE_MAX_ENTRIES 64
26
27 #define IS_INTERLINK_SET(v) ((v) & (DFSREF_REFERRAL_SERVER | \
28                                     DFSREF_STORAGE_SERVER))
29
30 struct cache_dfs_tgt {
31         char *name;
32         struct list_head list;
33 };
34
35 struct cache_entry {
36         struct hlist_node hlist;
37         const char *path;
38         int ttl;
39         int srvtype;
40         int flags;
41         struct timespec64 etime;
42         int path_consumed;
43         int numtgts;
44         struct list_head tlist;
45         struct cache_dfs_tgt *tgthint;
46 };
47
48 struct vol_info {
49         char *fullpath;
50         spinlock_t smb_vol_lock;
51         struct smb_vol smb_vol;
52         char *mntdata;
53         struct list_head list;
54         struct list_head rlist;
55         struct kref refcnt;
56 };
57
58 static struct kmem_cache *cache_slab __read_mostly;
59 static struct workqueue_struct *dfscache_wq __read_mostly;
60
61 static int cache_ttl;
62 static DEFINE_SPINLOCK(cache_ttl_lock);
63
64 static struct nls_table *cache_nlsc;
65
66 /*
67  * Number of entries in the cache
68  */
69 static atomic_t cache_count;
70
71 static struct hlist_head cache_htable[CACHE_HTABLE_SIZE];
72 static DECLARE_RWSEM(htable_rw_lock);
73
74 static LIST_HEAD(vol_list);
75 static DEFINE_SPINLOCK(vol_list_lock);
76
77 static void refresh_cache_worker(struct work_struct *work);
78
79 static DECLARE_DELAYED_WORK(refresh_task, refresh_cache_worker);
80
81 static int get_normalized_path(const char *path, char **npath)
82 {
83         if (!path || strlen(path) < 3 || (*path != '\\' && *path != '/'))
84                 return -EINVAL;
85
86         if (*path == '\\') {
87                 *npath = (char *)path;
88         } else {
89                 *npath = kstrndup(path, strlen(path), GFP_KERNEL);
90                 if (!*npath)
91                         return -ENOMEM;
92                 convert_delimiter(*npath, '\\');
93         }
94         return 0;
95 }
96
97 static inline void free_normalized_path(const char *path, char *npath)
98 {
99         if (path != npath)
100                 kfree(npath);
101 }
102
103 static inline bool cache_entry_expired(const struct cache_entry *ce)
104 {
105         struct timespec64 ts;
106
107         ktime_get_coarse_real_ts64(&ts);
108         return timespec64_compare(&ts, &ce->etime) >= 0;
109 }
110
111 static inline void free_tgts(struct cache_entry *ce)
112 {
113         struct cache_dfs_tgt *t, *n;
114
115         list_for_each_entry_safe(t, n, &ce->tlist, list) {
116                 list_del(&t->list);
117                 kfree(t->name);
118                 kfree(t);
119         }
120 }
121
122 static inline void flush_cache_ent(struct cache_entry *ce)
123 {
124         hlist_del_init(&ce->hlist);
125         kfree(ce->path);
126         free_tgts(ce);
127         atomic_dec(&cache_count);
128         kmem_cache_free(cache_slab, ce);
129 }
130
131 static void flush_cache_ents(void)
132 {
133         int i;
134
135         for (i = 0; i < CACHE_HTABLE_SIZE; i++) {
136                 struct hlist_head *l = &cache_htable[i];
137                 struct hlist_node *n;
138                 struct cache_entry *ce;
139
140                 hlist_for_each_entry_safe(ce, n, l, hlist) {
141                         if (!hlist_unhashed(&ce->hlist))
142                                 flush_cache_ent(ce);
143                 }
144         }
145 }
146
147 /*
148  * dfs cache /proc file
149  */
150 static int dfscache_proc_show(struct seq_file *m, void *v)
151 {
152         int i;
153         struct cache_entry *ce;
154         struct cache_dfs_tgt *t;
155
156         seq_puts(m, "DFS cache\n---------\n");
157
158         down_read(&htable_rw_lock);
159         for (i = 0; i < CACHE_HTABLE_SIZE; i++) {
160                 struct hlist_head *l = &cache_htable[i];
161
162                 hlist_for_each_entry(ce, l, hlist) {
163                         if (hlist_unhashed(&ce->hlist))
164                                 continue;
165
166                         seq_printf(m,
167                                    "cache entry: path=%s,type=%s,ttl=%d,etime=%ld,"
168                                    "interlink=%s,path_consumed=%d,expired=%s\n",
169                                    ce->path,
170                                    ce->srvtype == DFS_TYPE_ROOT ? "root" : "link",
171                                    ce->ttl, ce->etime.tv_nsec,
172                                    IS_INTERLINK_SET(ce->flags) ? "yes" : "no",
173                                    ce->path_consumed,
174                                    cache_entry_expired(ce) ? "yes" : "no");
175
176                         list_for_each_entry(t, &ce->tlist, list) {
177                                 seq_printf(m, "  %s%s\n",
178                                            t->name,
179                                            ce->tgthint == t ? " (target hint)" : "");
180                         }
181                 }
182         }
183         up_read(&htable_rw_lock);
184
185         return 0;
186 }
187
188 static ssize_t dfscache_proc_write(struct file *file, const char __user *buffer,
189                                    size_t count, loff_t *ppos)
190 {
191         char c;
192         int rc;
193
194         rc = get_user(c, buffer);
195         if (rc)
196                 return rc;
197
198         if (c != '0')
199                 return -EINVAL;
200
201         cifs_dbg(FYI, "clearing dfs cache\n");
202
203         down_write(&htable_rw_lock);
204         flush_cache_ents();
205         up_write(&htable_rw_lock);
206
207         return count;
208 }
209
210 static int dfscache_proc_open(struct inode *inode, struct file *file)
211 {
212         return single_open(file, dfscache_proc_show, NULL);
213 }
214
215 const struct proc_ops dfscache_proc_ops = {
216         .proc_open      = dfscache_proc_open,
217         .proc_read      = seq_read,
218         .proc_lseek     = seq_lseek,
219         .proc_release   = single_release,
220         .proc_write     = dfscache_proc_write,
221 };
222
223 #ifdef CONFIG_CIFS_DEBUG2
224 static inline void dump_tgts(const struct cache_entry *ce)
225 {
226         struct cache_dfs_tgt *t;
227
228         cifs_dbg(FYI, "target list:\n");
229         list_for_each_entry(t, &ce->tlist, list) {
230                 cifs_dbg(FYI, "  %s%s\n", t->name,
231                          ce->tgthint == t ? " (target hint)" : "");
232         }
233 }
234
235 static inline void dump_ce(const struct cache_entry *ce)
236 {
237         cifs_dbg(FYI, "cache entry: path=%s,type=%s,ttl=%d,etime=%ld,interlink=%s,path_consumed=%d,expired=%s\n",
238                  ce->path,
239                  ce->srvtype == DFS_TYPE_ROOT ? "root" : "link", ce->ttl,
240                  ce->etime.tv_nsec,
241                  IS_INTERLINK_SET(ce->flags) ? "yes" : "no",
242                  ce->path_consumed,
243                  cache_entry_expired(ce) ? "yes" : "no");
244         dump_tgts(ce);
245 }
246
247 static inline void dump_refs(const struct dfs_info3_param *refs, int numrefs)
248 {
249         int i;
250
251         cifs_dbg(FYI, "DFS referrals returned by the server:\n");
252         for (i = 0; i < numrefs; i++) {
253                 const struct dfs_info3_param *ref = &refs[i];
254
255                 cifs_dbg(FYI,
256                          "\n"
257                          "flags:         0x%x\n"
258                          "path_consumed: %d\n"
259                          "server_type:   0x%x\n"
260                          "ref_flag:      0x%x\n"
261                          "path_name:     %s\n"
262                          "node_name:     %s\n"
263                          "ttl:           %d (%dm)\n",
264                          ref->flags, ref->path_consumed, ref->server_type,
265                          ref->ref_flag, ref->path_name, ref->node_name,
266                          ref->ttl, ref->ttl / 60);
267         }
268 }
269 #else
270 #define dump_tgts(e)
271 #define dump_ce(e)
272 #define dump_refs(r, n)
273 #endif
274
275 /**
276  * dfs_cache_init - Initialize DFS referral cache.
277  *
278  * Return zero if initialized successfully, otherwise non-zero.
279  */
280 int dfs_cache_init(void)
281 {
282         int rc;
283         int i;
284
285         dfscache_wq = alloc_workqueue("cifs-dfscache",
286                                       WQ_FREEZABLE | WQ_MEM_RECLAIM, 1);
287         if (!dfscache_wq)
288                 return -ENOMEM;
289
290         cache_slab = kmem_cache_create("cifs_dfs_cache",
291                                        sizeof(struct cache_entry), 0,
292                                        SLAB_HWCACHE_ALIGN, NULL);
293         if (!cache_slab) {
294                 rc = -ENOMEM;
295                 goto out_destroy_wq;
296         }
297
298         for (i = 0; i < CACHE_HTABLE_SIZE; i++)
299                 INIT_HLIST_HEAD(&cache_htable[i]);
300
301         atomic_set(&cache_count, 0);
302         cache_nlsc = load_nls_default();
303
304         cifs_dbg(FYI, "%s: initialized DFS referral cache\n", __func__);
305         return 0;
306
307 out_destroy_wq:
308         destroy_workqueue(dfscache_wq);
309         return rc;
310 }
311
312 static inline unsigned int cache_entry_hash(const void *data, int size)
313 {
314         unsigned int h;
315
316         h = jhash(data, size, 0);
317         return h & (CACHE_HTABLE_SIZE - 1);
318 }
319
320 /* Check whether second path component of @path is SYSVOL or NETLOGON */
321 static inline bool is_sysvol_or_netlogon(const char *path)
322 {
323         const char *s;
324         char sep = path[0];
325
326         s = strchr(path + 1, sep) + 1;
327         return !strncasecmp(s, "sysvol", strlen("sysvol")) ||
328                 !strncasecmp(s, "netlogon", strlen("netlogon"));
329 }
330
331 /* Return target hint of a DFS cache entry */
332 static inline char *get_tgt_name(const struct cache_entry *ce)
333 {
334         struct cache_dfs_tgt *t = ce->tgthint;
335
336         return t ? t->name : ERR_PTR(-ENOENT);
337 }
338
339 /* Return expire time out of a new entry's TTL */
340 static inline struct timespec64 get_expire_time(int ttl)
341 {
342         struct timespec64 ts = {
343                 .tv_sec = ttl,
344                 .tv_nsec = 0,
345         };
346         struct timespec64 now;
347
348         ktime_get_coarse_real_ts64(&now);
349         return timespec64_add(now, ts);
350 }
351
352 /* Allocate a new DFS target */
353 static struct cache_dfs_tgt *alloc_target(const char *name)
354 {
355         struct cache_dfs_tgt *t;
356
357         t = kmalloc(sizeof(*t), GFP_ATOMIC);
358         if (!t)
359                 return ERR_PTR(-ENOMEM);
360         t->name = kstrndup(name, strlen(name), GFP_ATOMIC);
361         if (!t->name) {
362                 kfree(t);
363                 return ERR_PTR(-ENOMEM);
364         }
365         INIT_LIST_HEAD(&t->list);
366         return t;
367 }
368
369 /*
370  * Copy DFS referral information to a cache entry and conditionally update
371  * target hint.
372  */
373 static int copy_ref_data(const struct dfs_info3_param *refs, int numrefs,
374                          struct cache_entry *ce, const char *tgthint)
375 {
376         int i;
377
378         ce->ttl = refs[0].ttl;
379         ce->etime = get_expire_time(ce->ttl);
380         ce->srvtype = refs[0].server_type;
381         ce->flags = refs[0].ref_flag;
382         ce->path_consumed = refs[0].path_consumed;
383
384         for (i = 0; i < numrefs; i++) {
385                 struct cache_dfs_tgt *t;
386
387                 t = alloc_target(refs[i].node_name);
388                 if (IS_ERR(t)) {
389                         free_tgts(ce);
390                         return PTR_ERR(t);
391                 }
392                 if (tgthint && !strcasecmp(t->name, tgthint)) {
393                         list_add(&t->list, &ce->tlist);
394                         tgthint = NULL;
395                 } else {
396                         list_add_tail(&t->list, &ce->tlist);
397                 }
398                 ce->numtgts++;
399         }
400
401         ce->tgthint = list_first_entry_or_null(&ce->tlist,
402                                                struct cache_dfs_tgt, list);
403
404         return 0;
405 }
406
407 /* Allocate a new cache entry */
408 static struct cache_entry *alloc_cache_entry(const char *path,
409                                              const struct dfs_info3_param *refs,
410                                              int numrefs)
411 {
412         struct cache_entry *ce;
413         int rc;
414
415         ce = kmem_cache_zalloc(cache_slab, GFP_KERNEL);
416         if (!ce)
417                 return ERR_PTR(-ENOMEM);
418
419         ce->path = kstrndup(path, strlen(path), GFP_KERNEL);
420         if (!ce->path) {
421                 kmem_cache_free(cache_slab, ce);
422                 return ERR_PTR(-ENOMEM);
423         }
424         INIT_HLIST_NODE(&ce->hlist);
425         INIT_LIST_HEAD(&ce->tlist);
426
427         rc = copy_ref_data(refs, numrefs, ce, NULL);
428         if (rc) {
429                 kfree(ce->path);
430                 kmem_cache_free(cache_slab, ce);
431                 ce = ERR_PTR(rc);
432         }
433         return ce;
434 }
435
436 /* Must be called with htable_rw_lock held */
437 static void remove_oldest_entry(void)
438 {
439         int i;
440         struct cache_entry *ce;
441         struct cache_entry *to_del = NULL;
442
443         for (i = 0; i < CACHE_HTABLE_SIZE; i++) {
444                 struct hlist_head *l = &cache_htable[i];
445
446                 hlist_for_each_entry(ce, l, hlist) {
447                         if (hlist_unhashed(&ce->hlist))
448                                 continue;
449                         if (!to_del || timespec64_compare(&ce->etime,
450                                                           &to_del->etime) < 0)
451                                 to_del = ce;
452                 }
453         }
454
455         if (!to_del) {
456                 cifs_dbg(FYI, "%s: no entry to remove\n", __func__);
457                 return;
458         }
459
460         cifs_dbg(FYI, "%s: removing entry\n", __func__);
461         dump_ce(to_del);
462         flush_cache_ent(to_del);
463 }
464
465 /* Add a new DFS cache entry */
466 static int add_cache_entry(const char *path, unsigned int hash,
467                            struct dfs_info3_param *refs, int numrefs)
468 {
469         struct cache_entry *ce;
470
471         ce = alloc_cache_entry(path, refs, numrefs);
472         if (IS_ERR(ce))
473                 return PTR_ERR(ce);
474
475         spin_lock(&cache_ttl_lock);
476         if (!cache_ttl) {
477                 cache_ttl = ce->ttl;
478                 queue_delayed_work(dfscache_wq, &refresh_task, cache_ttl * HZ);
479         } else {
480                 cache_ttl = min_t(int, cache_ttl, ce->ttl);
481                 mod_delayed_work(dfscache_wq, &refresh_task, cache_ttl * HZ);
482         }
483         spin_unlock(&cache_ttl_lock);
484
485         down_write(&htable_rw_lock);
486         hlist_add_head(&ce->hlist, &cache_htable[hash]);
487         dump_ce(ce);
488         up_write(&htable_rw_lock);
489
490         return 0;
491 }
492
493 static struct cache_entry *__lookup_cache_entry(const char *path)
494 {
495         struct cache_entry *ce;
496         unsigned int h;
497         bool found = false;
498
499         h = cache_entry_hash(path, strlen(path));
500
501         hlist_for_each_entry(ce, &cache_htable[h], hlist) {
502                 if (!strcasecmp(path, ce->path)) {
503                         found = true;
504                         dump_ce(ce);
505                         break;
506                 }
507         }
508
509         if (!found)
510                 ce = ERR_PTR(-ENOENT);
511         return ce;
512 }
513
514 /*
515  * Find a DFS cache entry in hash table and optionally check prefix path against
516  * @path.
517  * Use whole path components in the match.
518  * Must be called with htable_rw_lock held.
519  *
520  * Return ERR_PTR(-ENOENT) if the entry is not found.
521  */
522 static struct cache_entry *lookup_cache_entry(const char *path, unsigned int *hash)
523 {
524         struct cache_entry *ce = ERR_PTR(-ENOENT);
525         unsigned int h;
526         int cnt = 0;
527         char *npath;
528         char *s, *e;
529         char sep;
530
531         npath = kstrndup(path, strlen(path), GFP_KERNEL);
532         if (!npath)
533                 return ERR_PTR(-ENOMEM);
534
535         s = npath;
536         sep = *npath;
537         while ((s = strchr(s, sep)) && ++cnt < 3)
538                 s++;
539
540         if (cnt < 3) {
541                 h = cache_entry_hash(path, strlen(path));
542                 ce = __lookup_cache_entry(path);
543                 goto out;
544         }
545         /*
546          * Handle paths that have more than two path components and are a complete prefix of the DFS
547          * referral request path (@path).
548          *
549          * See MS-DFSC 3.2.5.5 "Receiving a Root Referral Request or Link Referral Request".
550          */
551         h = cache_entry_hash(npath, strlen(npath));
552         e = npath + strlen(npath) - 1;
553         while (e > s) {
554                 char tmp;
555
556                 /* skip separators */
557                 while (e > s && *e == sep)
558                         e--;
559                 if (e == s)
560                         goto out;
561
562                 tmp = *(e+1);
563                 *(e+1) = 0;
564
565                 ce = __lookup_cache_entry(npath);
566                 if (!IS_ERR(ce)) {
567                         h = cache_entry_hash(npath, strlen(npath));
568                         break;
569                 }
570
571                 *(e+1) = tmp;
572                 /* backward until separator */
573                 while (e > s && *e != sep)
574                         e--;
575         }
576 out:
577         if (hash)
578                 *hash = h;
579         kfree(npath);
580         return ce;
581 }
582
583 static void __vol_release(struct vol_info *vi)
584 {
585         kfree(vi->fullpath);
586         kfree(vi->mntdata);
587         cifs_cleanup_volume_info_contents(&vi->smb_vol);
588         kfree(vi);
589 }
590
591 static void vol_release(struct kref *kref)
592 {
593         struct vol_info *vi = container_of(kref, struct vol_info, refcnt);
594
595         spin_lock(&vol_list_lock);
596         list_del(&vi->list);
597         spin_unlock(&vol_list_lock);
598         __vol_release(vi);
599 }
600
601 static inline void free_vol_list(void)
602 {
603         struct vol_info *vi, *nvi;
604
605         list_for_each_entry_safe(vi, nvi, &vol_list, list) {
606                 list_del_init(&vi->list);
607                 __vol_release(vi);
608         }
609 }
610
611 /**
612  * dfs_cache_destroy - destroy DFS referral cache
613  */
614 void dfs_cache_destroy(void)
615 {
616         cancel_delayed_work_sync(&refresh_task);
617         unload_nls(cache_nlsc);
618         free_vol_list();
619         flush_cache_ents();
620         kmem_cache_destroy(cache_slab);
621         destroy_workqueue(dfscache_wq);
622
623         cifs_dbg(FYI, "%s: destroyed DFS referral cache\n", __func__);
624 }
625
626 /* Must be called with htable_rw_lock held */
627 static int __update_cache_entry(const char *path,
628                                 const struct dfs_info3_param *refs,
629                                 int numrefs)
630 {
631         int rc;
632         struct cache_entry *ce;
633         char *s, *th = NULL;
634
635         ce = lookup_cache_entry(path, NULL);
636         if (IS_ERR(ce))
637                 return PTR_ERR(ce);
638
639         if (ce->tgthint) {
640                 s = ce->tgthint->name;
641                 th = kstrndup(s, strlen(s), GFP_ATOMIC);
642                 if (!th)
643                         return -ENOMEM;
644         }
645
646         free_tgts(ce);
647         ce->numtgts = 0;
648
649         rc = copy_ref_data(refs, numrefs, ce, th);
650
651         kfree(th);
652
653         return rc;
654 }
655
656 static int get_dfs_referral(const unsigned int xid, struct cifs_ses *ses,
657                             const struct nls_table *nls_codepage, int remap,
658                             const char *path,  struct dfs_info3_param **refs,
659                             int *numrefs)
660 {
661         cifs_dbg(FYI, "%s: get an DFS referral for %s\n", __func__, path);
662
663         if (!ses || !ses->server || !ses->server->ops->get_dfs_refer)
664                 return -EOPNOTSUPP;
665         if (unlikely(!nls_codepage))
666                 return -EINVAL;
667
668         *refs = NULL;
669         *numrefs = 0;
670
671         return ses->server->ops->get_dfs_refer(xid, ses, path, refs, numrefs,
672                                                nls_codepage, remap);
673 }
674
675 /* Update an expired cache entry by getting a new DFS referral from server */
676 static int update_cache_entry(const char *path,
677                               const struct dfs_info3_param *refs,
678                               int numrefs)
679 {
680
681         int rc;
682
683         down_write(&htable_rw_lock);
684         rc = __update_cache_entry(path, refs, numrefs);
685         up_write(&htable_rw_lock);
686
687         return rc;
688 }
689
690 /*
691  * Find, create or update a DFS cache entry.
692  *
693  * If the entry wasn't found, it will create a new one. Or if it was found but
694  * expired, then it will update the entry accordingly.
695  *
696  * For interlinks, __cifs_dfs_mount() and expand_dfs_referral() are supposed to
697  * handle them properly.
698  */
699 static int __dfs_cache_find(const unsigned int xid, struct cifs_ses *ses,
700                             const struct nls_table *nls_codepage, int remap,
701                             const char *path, bool noreq)
702 {
703         int rc;
704         unsigned int hash;
705         struct cache_entry *ce;
706         struct dfs_info3_param *refs = NULL;
707         int numrefs = 0;
708         bool newent = false;
709
710         cifs_dbg(FYI, "%s: search path: %s\n", __func__, path);
711
712         down_read(&htable_rw_lock);
713
714         ce = lookup_cache_entry(path, &hash);
715
716         /*
717          * If @noreq is set, no requests will be sent to the server. Just return
718          * the cache entry.
719          */
720         if (noreq) {
721                 up_read(&htable_rw_lock);
722                 return PTR_ERR_OR_ZERO(ce);
723         }
724
725         if (!IS_ERR(ce)) {
726                 if (!cache_entry_expired(ce)) {
727                         dump_ce(ce);
728                         up_read(&htable_rw_lock);
729                         return 0;
730                 }
731         } else {
732                 newent = true;
733         }
734
735         up_read(&htable_rw_lock);
736
737         /*
738          * No entry was found.
739          *
740          * Request a new DFS referral in order to create a new cache entry, or
741          * updating an existing one.
742          */
743         rc = get_dfs_referral(xid, ses, nls_codepage, remap, path,
744                               &refs, &numrefs);
745         if (rc)
746                 return rc;
747
748         dump_refs(refs, numrefs);
749
750         if (!newent) {
751                 rc = update_cache_entry(path, refs, numrefs);
752                 goto out_free_refs;
753         }
754
755         if (atomic_read(&cache_count) >= CACHE_MAX_ENTRIES) {
756                 cifs_dbg(FYI, "%s: reached max cache size (%d)\n",
757                          __func__, CACHE_MAX_ENTRIES);
758                 down_write(&htable_rw_lock);
759                 remove_oldest_entry();
760                 up_write(&htable_rw_lock);
761         }
762
763         rc = add_cache_entry(path, hash, refs, numrefs);
764         if (!rc)
765                 atomic_inc(&cache_count);
766
767 out_free_refs:
768         free_dfs_info_array(refs, numrefs);
769         return rc;
770 }
771
772 /*
773  * Set up a DFS referral from a given cache entry.
774  *
775  * Must be called with htable_rw_lock held.
776  */
777 static int setup_referral(const char *path, struct cache_entry *ce,
778                           struct dfs_info3_param *ref, const char *target)
779 {
780         int rc;
781
782         cifs_dbg(FYI, "%s: set up new ref\n", __func__);
783
784         memset(ref, 0, sizeof(*ref));
785
786         ref->path_name = kstrndup(path, strlen(path), GFP_ATOMIC);
787         if (!ref->path_name)
788                 return -ENOMEM;
789
790         ref->node_name = kstrndup(target, strlen(target), GFP_ATOMIC);
791         if (!ref->node_name) {
792                 rc = -ENOMEM;
793                 goto err_free_path;
794         }
795
796         ref->path_consumed = ce->path_consumed;
797         ref->ttl = ce->ttl;
798         ref->server_type = ce->srvtype;
799         ref->ref_flag = ce->flags;
800
801         return 0;
802
803 err_free_path:
804         kfree(ref->path_name);
805         ref->path_name = NULL;
806         return rc;
807 }
808
809 /* Return target list of a DFS cache entry */
810 static int get_targets(struct cache_entry *ce, struct dfs_cache_tgt_list *tl)
811 {
812         int rc;
813         struct list_head *head = &tl->tl_list;
814         struct cache_dfs_tgt *t;
815         struct dfs_cache_tgt_iterator *it, *nit;
816
817         memset(tl, 0, sizeof(*tl));
818         INIT_LIST_HEAD(head);
819
820         list_for_each_entry(t, &ce->tlist, list) {
821                 it = kzalloc(sizeof(*it), GFP_ATOMIC);
822                 if (!it) {
823                         rc = -ENOMEM;
824                         goto err_free_it;
825                 }
826
827                 it->it_name = kstrndup(t->name, strlen(t->name), GFP_ATOMIC);
828                 if (!it->it_name) {
829                         kfree(it);
830                         rc = -ENOMEM;
831                         goto err_free_it;
832                 }
833
834                 if (ce->tgthint == t)
835                         list_add(&it->it_list, head);
836                 else
837                         list_add_tail(&it->it_list, head);
838         }
839
840         tl->tl_numtgts = ce->numtgts;
841
842         return 0;
843
844 err_free_it:
845         list_for_each_entry_safe(it, nit, head, it_list) {
846                 kfree(it->it_name);
847                 kfree(it);
848         }
849         return rc;
850 }
851
852 /**
853  * dfs_cache_find - find a DFS cache entry
854  *
855  * If it doesn't find the cache entry, then it will get a DFS referral
856  * for @path and create a new entry.
857  *
858  * In case the cache entry exists but expired, it will get a DFS referral
859  * for @path and then update the respective cache entry.
860  *
861  * These parameters are passed down to the get_dfs_refer() call if it
862  * needs to be issued:
863  * @xid: syscall xid
864  * @ses: smb session to issue the request on
865  * @nls_codepage: charset conversion
866  * @remap: path character remapping type
867  * @path: path to lookup in DFS referral cache.
868  *
869  * @ref: when non-NULL, store single DFS referral result in it.
870  * @tgt_list: when non-NULL, store complete DFS target list in it.
871  *
872  * Return zero if the target was found, otherwise non-zero.
873  */
874 int dfs_cache_find(const unsigned int xid, struct cifs_ses *ses,
875                    const struct nls_table *nls_codepage, int remap,
876                    const char *path, struct dfs_info3_param *ref,
877                    struct dfs_cache_tgt_list *tgt_list)
878 {
879         int rc;
880         char *npath;
881         struct cache_entry *ce;
882
883         rc = get_normalized_path(path, &npath);
884         if (rc)
885                 return rc;
886
887         rc = __dfs_cache_find(xid, ses, nls_codepage, remap, npath, false);
888         if (rc)
889                 goto out_free_path;
890
891         down_read(&htable_rw_lock);
892
893         ce = lookup_cache_entry(npath, NULL);
894         if (IS_ERR(ce)) {
895                 up_read(&htable_rw_lock);
896                 rc = PTR_ERR(ce);
897                 goto out_free_path;
898         }
899
900         if (ref)
901                 rc = setup_referral(path, ce, ref, get_tgt_name(ce));
902         else
903                 rc = 0;
904         if (!rc && tgt_list)
905                 rc = get_targets(ce, tgt_list);
906
907         up_read(&htable_rw_lock);
908
909 out_free_path:
910         free_normalized_path(path, npath);
911         return rc;
912 }
913
914 /**
915  * dfs_cache_noreq_find - find a DFS cache entry without sending any requests to
916  * the currently connected server.
917  *
918  * NOTE: This function will neither update a cache entry in case it was
919  * expired, nor create a new cache entry if @path hasn't been found. It heavily
920  * relies on an existing cache entry.
921  *
922  * @path: path to lookup in the DFS referral cache.
923  * @ref: when non-NULL, store single DFS referral result in it.
924  * @tgt_list: when non-NULL, store complete DFS target list in it.
925  *
926  * Return 0 if successful.
927  * Return -ENOENT if the entry was not found.
928  * Return non-zero for other errors.
929  */
930 int dfs_cache_noreq_find(const char *path, struct dfs_info3_param *ref,
931                          struct dfs_cache_tgt_list *tgt_list)
932 {
933         int rc;
934         char *npath;
935         struct cache_entry *ce;
936
937         rc = get_normalized_path(path, &npath);
938         if (rc)
939                 return rc;
940
941         cifs_dbg(FYI, "%s: path: %s\n", __func__, npath);
942
943         down_read(&htable_rw_lock);
944
945         ce = lookup_cache_entry(npath, NULL);
946         if (IS_ERR(ce)) {
947                 rc = PTR_ERR(ce);
948                 goto out_unlock;
949         }
950
951         if (ref)
952                 rc = setup_referral(path, ce, ref, get_tgt_name(ce));
953         else
954                 rc = 0;
955         if (!rc && tgt_list)
956                 rc = get_targets(ce, tgt_list);
957
958 out_unlock:
959         up_read(&htable_rw_lock);
960         free_normalized_path(path, npath);
961
962         return rc;
963 }
964
965 /**
966  * dfs_cache_update_tgthint - update target hint of a DFS cache entry
967  *
968  * If it doesn't find the cache entry, then it will get a DFS referral for @path
969  * and create a new entry.
970  *
971  * In case the cache entry exists but expired, it will get a DFS referral
972  * for @path and then update the respective cache entry.
973  *
974  * @xid: syscall id
975  * @ses: smb session
976  * @nls_codepage: charset conversion
977  * @remap: type of character remapping for paths
978  * @path: path to lookup in DFS referral cache.
979  * @it: DFS target iterator
980  *
981  * Return zero if the target hint was updated successfully, otherwise non-zero.
982  */
983 int dfs_cache_update_tgthint(const unsigned int xid, struct cifs_ses *ses,
984                              const struct nls_table *nls_codepage, int remap,
985                              const char *path,
986                              const struct dfs_cache_tgt_iterator *it)
987 {
988         int rc;
989         char *npath;
990         struct cache_entry *ce;
991         struct cache_dfs_tgt *t;
992
993         rc = get_normalized_path(path, &npath);
994         if (rc)
995                 return rc;
996
997         cifs_dbg(FYI, "%s: update target hint - path: %s\n", __func__, npath);
998
999         rc = __dfs_cache_find(xid, ses, nls_codepage, remap, npath, false);
1000         if (rc)
1001                 goto out_free_path;
1002
1003         down_write(&htable_rw_lock);
1004
1005         ce = lookup_cache_entry(npath, NULL);
1006         if (IS_ERR(ce)) {
1007                 rc = PTR_ERR(ce);
1008                 goto out_unlock;
1009         }
1010
1011         t = ce->tgthint;
1012
1013         if (likely(!strcasecmp(it->it_name, t->name)))
1014                 goto out_unlock;
1015
1016         list_for_each_entry(t, &ce->tlist, list) {
1017                 if (!strcasecmp(t->name, it->it_name)) {
1018                         ce->tgthint = t;
1019                         cifs_dbg(FYI, "%s: new target hint: %s\n", __func__,
1020                                  it->it_name);
1021                         break;
1022                 }
1023         }
1024
1025 out_unlock:
1026         up_write(&htable_rw_lock);
1027 out_free_path:
1028         free_normalized_path(path, npath);
1029
1030         return rc;
1031 }
1032
1033 /**
1034  * dfs_cache_noreq_update_tgthint - update target hint of a DFS cache entry
1035  * without sending any requests to the currently connected server.
1036  *
1037  * NOTE: This function will neither update a cache entry in case it was
1038  * expired, nor create a new cache entry if @path hasn't been found. It heavily
1039  * relies on an existing cache entry.
1040  *
1041  * @path: path to lookup in DFS referral cache.
1042  * @it: target iterator which contains the target hint to update the cache
1043  * entry with.
1044  *
1045  * Return zero if the target hint was updated successfully, otherwise non-zero.
1046  */
1047 int dfs_cache_noreq_update_tgthint(const char *path,
1048                                    const struct dfs_cache_tgt_iterator *it)
1049 {
1050         int rc;
1051         char *npath;
1052         struct cache_entry *ce;
1053         struct cache_dfs_tgt *t;
1054
1055         if (!it)
1056                 return -EINVAL;
1057
1058         rc = get_normalized_path(path, &npath);
1059         if (rc)
1060                 return rc;
1061
1062         cifs_dbg(FYI, "%s: path: %s\n", __func__, npath);
1063
1064         down_write(&htable_rw_lock);
1065
1066         ce = lookup_cache_entry(npath, NULL);
1067         if (IS_ERR(ce)) {
1068                 rc = PTR_ERR(ce);
1069                 goto out_unlock;
1070         }
1071
1072         rc = 0;
1073         t = ce->tgthint;
1074
1075         if (unlikely(!strcasecmp(it->it_name, t->name)))
1076                 goto out_unlock;
1077
1078         list_for_each_entry(t, &ce->tlist, list) {
1079                 if (!strcasecmp(t->name, it->it_name)) {
1080                         ce->tgthint = t;
1081                         cifs_dbg(FYI, "%s: new target hint: %s\n", __func__,
1082                                  it->it_name);
1083                         break;
1084                 }
1085         }
1086
1087 out_unlock:
1088         up_write(&htable_rw_lock);
1089         free_normalized_path(path, npath);
1090
1091         return rc;
1092 }
1093
1094 /**
1095  * dfs_cache_get_tgt_referral - returns a DFS referral (@ref) from a given
1096  * target iterator (@it).
1097  *
1098  * @path: path to lookup in DFS referral cache.
1099  * @it: DFS target iterator.
1100  * @ref: DFS referral pointer to set up the gathered information.
1101  *
1102  * Return zero if the DFS referral was set up correctly, otherwise non-zero.
1103  */
1104 int dfs_cache_get_tgt_referral(const char *path,
1105                                const struct dfs_cache_tgt_iterator *it,
1106                                struct dfs_info3_param *ref)
1107 {
1108         int rc;
1109         char *npath;
1110         struct cache_entry *ce;
1111
1112         if (!it || !ref)
1113                 return -EINVAL;
1114
1115         rc = get_normalized_path(path, &npath);
1116         if (rc)
1117                 return rc;
1118
1119         cifs_dbg(FYI, "%s: path: %s\n", __func__, npath);
1120
1121         down_read(&htable_rw_lock);
1122
1123         ce = lookup_cache_entry(npath, NULL);
1124         if (IS_ERR(ce)) {
1125                 rc = PTR_ERR(ce);
1126                 goto out_unlock;
1127         }
1128
1129         cifs_dbg(FYI, "%s: target name: %s\n", __func__, it->it_name);
1130
1131         rc = setup_referral(path, ce, ref, it->it_name);
1132
1133 out_unlock:
1134         up_read(&htable_rw_lock);
1135         free_normalized_path(path, npath);
1136
1137         return rc;
1138 }
1139
1140 static int dup_vol(struct smb_vol *vol, struct smb_vol *new)
1141 {
1142         memcpy(new, vol, sizeof(*new));
1143
1144         if (vol->username) {
1145                 new->username = kstrndup(vol->username, strlen(vol->username),
1146                                          GFP_KERNEL);
1147                 if (!new->username)
1148                         return -ENOMEM;
1149         }
1150         if (vol->password) {
1151                 new->password = kstrndup(vol->password, strlen(vol->password),
1152                                          GFP_KERNEL);
1153                 if (!new->password)
1154                         goto err_free_username;
1155         }
1156         if (vol->UNC) {
1157                 cifs_dbg(FYI, "%s: vol->UNC: %s\n", __func__, vol->UNC);
1158                 new->UNC = kstrndup(vol->UNC, strlen(vol->UNC), GFP_KERNEL);
1159                 if (!new->UNC)
1160                         goto err_free_password;
1161         }
1162         if (vol->domainname) {
1163                 new->domainname = kstrndup(vol->domainname,
1164                                            strlen(vol->domainname), GFP_KERNEL);
1165                 if (!new->domainname)
1166                         goto err_free_unc;
1167         }
1168         if (vol->iocharset) {
1169                 new->iocharset = kstrndup(vol->iocharset,
1170                                           strlen(vol->iocharset), GFP_KERNEL);
1171                 if (!new->iocharset)
1172                         goto err_free_domainname;
1173         }
1174         if (vol->prepath) {
1175                 cifs_dbg(FYI, "%s: vol->prepath: %s\n", __func__, vol->prepath);
1176                 new->prepath = kstrndup(vol->prepath, strlen(vol->prepath),
1177                                         GFP_KERNEL);
1178                 if (!new->prepath)
1179                         goto err_free_iocharset;
1180         }
1181
1182         return 0;
1183
1184 err_free_iocharset:
1185         kfree(new->iocharset);
1186 err_free_domainname:
1187         kfree(new->domainname);
1188 err_free_unc:
1189         kfree(new->UNC);
1190 err_free_password:
1191         kzfree(new->password);
1192 err_free_username:
1193         kfree(new->username);
1194         kfree(new);
1195         return -ENOMEM;
1196 }
1197
1198 /**
1199  * dfs_cache_add_vol - add a cifs volume during mount() that will be handled by
1200  * DFS cache refresh worker.
1201  *
1202  * @mntdata: mount data.
1203  * @vol: cifs volume.
1204  * @fullpath: origin full path.
1205  *
1206  * Return zero if volume was set up correctly, otherwise non-zero.
1207  */
1208 int dfs_cache_add_vol(char *mntdata, struct smb_vol *vol, const char *fullpath)
1209 {
1210         int rc;
1211         struct vol_info *vi;
1212
1213         if (!vol || !fullpath || !mntdata)
1214                 return -EINVAL;
1215
1216         cifs_dbg(FYI, "%s: fullpath: %s\n", __func__, fullpath);
1217
1218         vi = kzalloc(sizeof(*vi), GFP_KERNEL);
1219         if (!vi)
1220                 return -ENOMEM;
1221
1222         vi->fullpath = kstrndup(fullpath, strlen(fullpath), GFP_KERNEL);
1223         if (!vi->fullpath) {
1224                 rc = -ENOMEM;
1225                 goto err_free_vi;
1226         }
1227
1228         rc = dup_vol(vol, &vi->smb_vol);
1229         if (rc)
1230                 goto err_free_fullpath;
1231
1232         vi->mntdata = mntdata;
1233         spin_lock_init(&vi->smb_vol_lock);
1234         kref_init(&vi->refcnt);
1235
1236         spin_lock(&vol_list_lock);
1237         list_add_tail(&vi->list, &vol_list);
1238         spin_unlock(&vol_list_lock);
1239
1240         return 0;
1241
1242 err_free_fullpath:
1243         kfree(vi->fullpath);
1244 err_free_vi:
1245         kfree(vi);
1246         return rc;
1247 }
1248
1249 /* Must be called with vol_list_lock held */
1250 static struct vol_info *find_vol(const char *fullpath)
1251 {
1252         struct vol_info *vi;
1253
1254         list_for_each_entry(vi, &vol_list, list) {
1255                 cifs_dbg(FYI, "%s: vi->fullpath: %s\n", __func__, vi->fullpath);
1256                 if (!strcasecmp(vi->fullpath, fullpath))
1257                         return vi;
1258         }
1259         return ERR_PTR(-ENOENT);
1260 }
1261
1262 /**
1263  * dfs_cache_update_vol - update vol info in DFS cache after failover
1264  *
1265  * @fullpath: fullpath to look up in volume list.
1266  * @server: TCP ses pointer.
1267  *
1268  * Return zero if volume was updated, otherwise non-zero.
1269  */
1270 int dfs_cache_update_vol(const char *fullpath, struct TCP_Server_Info *server)
1271 {
1272         struct vol_info *vi;
1273
1274         if (!fullpath || !server)
1275                 return -EINVAL;
1276
1277         cifs_dbg(FYI, "%s: fullpath: %s\n", __func__, fullpath);
1278
1279         spin_lock(&vol_list_lock);
1280         vi = find_vol(fullpath);
1281         if (IS_ERR(vi)) {
1282                 spin_unlock(&vol_list_lock);
1283                 return PTR_ERR(vi);
1284         }
1285         kref_get(&vi->refcnt);
1286         spin_unlock(&vol_list_lock);
1287
1288         cifs_dbg(FYI, "%s: updating volume info\n", __func__);
1289         spin_lock(&vi->smb_vol_lock);
1290         memcpy(&vi->smb_vol.dstaddr, &server->dstaddr,
1291                sizeof(vi->smb_vol.dstaddr));
1292         spin_unlock(&vi->smb_vol_lock);
1293
1294         kref_put(&vi->refcnt, vol_release);
1295
1296         return 0;
1297 }
1298
1299 /**
1300  * dfs_cache_del_vol - remove volume info in DFS cache during umount()
1301  *
1302  * @fullpath: fullpath to look up in volume list.
1303  */
1304 void dfs_cache_del_vol(const char *fullpath)
1305 {
1306         struct vol_info *vi;
1307
1308         if (!fullpath || !*fullpath)
1309                 return;
1310
1311         cifs_dbg(FYI, "%s: fullpath: %s\n", __func__, fullpath);
1312
1313         spin_lock(&vol_list_lock);
1314         vi = find_vol(fullpath);
1315         spin_unlock(&vol_list_lock);
1316
1317         kref_put(&vi->refcnt, vol_release);
1318 }
1319
1320 /**
1321  * dfs_cache_get_tgt_share - parse a DFS target
1322  *
1323  * @it: DFS target iterator.
1324  * @share: tree name.
1325  * @share_len: length of tree name.
1326  * @prefix: prefix path.
1327  * @prefix_len: length of prefix path.
1328  *
1329  * Return zero if target was parsed correctly, otherwise non-zero.
1330  */
1331 int dfs_cache_get_tgt_share(const struct dfs_cache_tgt_iterator *it,
1332                             const char **share, size_t *share_len,
1333                             const char **prefix, size_t *prefix_len)
1334 {
1335         char *s, sep;
1336
1337         if (!it || !share || !share_len || !prefix || !prefix_len)
1338                 return -EINVAL;
1339
1340         sep = it->it_name[0];
1341         if (sep != '\\' && sep != '/')
1342                 return -EINVAL;
1343
1344         s = strchr(it->it_name + 1, sep);
1345         if (!s)
1346                 return -EINVAL;
1347
1348         s = strchrnul(s + 1, sep);
1349
1350         *share = it->it_name;
1351         *share_len = s - it->it_name;
1352         *prefix = *s ? s + 1 : s;
1353         *prefix_len = &it->it_name[strlen(it->it_name)] - *prefix;
1354
1355         return 0;
1356 }
1357
1358 /* Get all tcons that are within a DFS namespace and can be refreshed */
1359 static void get_tcons(struct TCP_Server_Info *server, struct list_head *head)
1360 {
1361         struct cifs_ses *ses;
1362         struct cifs_tcon *tcon;
1363
1364         INIT_LIST_HEAD(head);
1365
1366         spin_lock(&cifs_tcp_ses_lock);
1367         list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
1368                 list_for_each_entry(tcon, &ses->tcon_list, tcon_list) {
1369                         if (!tcon->need_reconnect && !tcon->need_reopen_files &&
1370                             tcon->dfs_path) {
1371                                 tcon->tc_count++;
1372                                 list_add_tail(&tcon->ulist, head);
1373                         }
1374                 }
1375                 if (ses->tcon_ipc && !ses->tcon_ipc->need_reconnect &&
1376                     ses->tcon_ipc->dfs_path) {
1377                         list_add_tail(&ses->tcon_ipc->ulist, head);
1378                 }
1379         }
1380         spin_unlock(&cifs_tcp_ses_lock);
1381 }
1382
1383 static bool is_dfs_link(const char *path)
1384 {
1385         char *s;
1386
1387         s = strchr(path + 1, '\\');
1388         if (!s)
1389                 return false;
1390         return !!strchr(s + 1, '\\');
1391 }
1392
1393 static char *get_dfs_root(const char *path)
1394 {
1395         char *s, *npath;
1396
1397         s = strchr(path + 1, '\\');
1398         if (!s)
1399                 return ERR_PTR(-EINVAL);
1400
1401         s = strchr(s + 1, '\\');
1402         if (!s)
1403                 return ERR_PTR(-EINVAL);
1404
1405         npath = kstrndup(path, s - path, GFP_KERNEL);
1406         if (!npath)
1407                 return ERR_PTR(-ENOMEM);
1408
1409         return npath;
1410 }
1411
1412 static inline void put_tcp_server(struct TCP_Server_Info *server)
1413 {
1414         cifs_put_tcp_session(server, 0);
1415 }
1416
1417 static struct TCP_Server_Info *get_tcp_server(struct smb_vol *vol)
1418 {
1419         struct TCP_Server_Info *server;
1420
1421         server = cifs_find_tcp_session(vol);
1422         if (IS_ERR_OR_NULL(server))
1423                 return NULL;
1424
1425         spin_lock(&GlobalMid_Lock);
1426         if (server->tcpStatus != CifsGood) {
1427                 spin_unlock(&GlobalMid_Lock);
1428                 put_tcp_server(server);
1429                 return NULL;
1430         }
1431         spin_unlock(&GlobalMid_Lock);
1432
1433         return server;
1434 }
1435
1436 /* Find root SMB session out of a DFS link path */
1437 static struct cifs_ses *find_root_ses(struct vol_info *vi,
1438                                       struct cifs_tcon *tcon,
1439                                       const char *path)
1440 {
1441         char *rpath;
1442         int rc;
1443         struct cache_entry *ce;
1444         struct dfs_info3_param ref = {0};
1445         char *mdata = NULL, *devname = NULL;
1446         struct TCP_Server_Info *server;
1447         struct cifs_ses *ses;
1448         struct smb_vol vol = {NULL};
1449
1450         rpath = get_dfs_root(path);
1451         if (IS_ERR(rpath))
1452                 return ERR_CAST(rpath);
1453
1454         down_read(&htable_rw_lock);
1455
1456         ce = lookup_cache_entry(rpath, NULL);
1457         if (IS_ERR(ce)) {
1458                 up_read(&htable_rw_lock);
1459                 ses = ERR_CAST(ce);
1460                 goto out;
1461         }
1462
1463         rc = setup_referral(path, ce, &ref, get_tgt_name(ce));
1464         if (rc) {
1465                 up_read(&htable_rw_lock);
1466                 ses = ERR_PTR(rc);
1467                 goto out;
1468         }
1469
1470         up_read(&htable_rw_lock);
1471
1472         mdata = cifs_compose_mount_options(vi->mntdata, rpath, &ref,
1473                                            &devname);
1474         free_dfs_info_param(&ref);
1475
1476         if (IS_ERR(mdata)) {
1477                 ses = ERR_CAST(mdata);
1478                 mdata = NULL;
1479                 goto out;
1480         }
1481
1482         rc = cifs_setup_volume_info(&vol, mdata, devname, false);
1483         kfree(devname);
1484
1485         if (rc) {
1486                 ses = ERR_PTR(rc);
1487                 goto out;
1488         }
1489
1490         server = get_tcp_server(&vol);
1491         if (!server) {
1492                 ses = ERR_PTR(-EHOSTDOWN);
1493                 goto out;
1494         }
1495
1496         ses = cifs_get_smb_ses(server, &vol);
1497
1498 out:
1499         cifs_cleanup_volume_info_contents(&vol);
1500         kfree(mdata);
1501         kfree(rpath);
1502
1503         return ses;
1504 }
1505
1506 /* Refresh DFS cache entry from a given tcon */
1507 static int refresh_tcon(struct vol_info *vi, struct cifs_tcon *tcon)
1508 {
1509         int rc = 0;
1510         unsigned int xid;
1511         char *path, *npath;
1512         struct cache_entry *ce;
1513         struct cifs_ses *root_ses = NULL, *ses;
1514         struct dfs_info3_param *refs = NULL;
1515         int numrefs = 0;
1516
1517         xid = get_xid();
1518
1519         path = tcon->dfs_path + 1;
1520
1521         rc = get_normalized_path(path, &npath);
1522         if (rc)
1523                 goto out_free_xid;
1524
1525         down_read(&htable_rw_lock);
1526
1527         ce = lookup_cache_entry(npath, NULL);
1528         if (IS_ERR(ce)) {
1529                 rc = PTR_ERR(ce);
1530                 up_read(&htable_rw_lock);
1531                 goto out_free_path;
1532         }
1533
1534         if (!cache_entry_expired(ce)) {
1535                 up_read(&htable_rw_lock);
1536                 goto out_free_path;
1537         }
1538
1539         up_read(&htable_rw_lock);
1540
1541         /* If it's a DFS Link, then use root SMB session for refreshing it */
1542         if (is_dfs_link(npath)) {
1543                 ses = root_ses = find_root_ses(vi, tcon, npath);
1544                 if (IS_ERR(ses)) {
1545                         rc = PTR_ERR(ses);
1546                         root_ses = NULL;
1547                         goto out_free_path;
1548                 }
1549         } else {
1550                 ses = tcon->ses;
1551         }
1552
1553         rc = get_dfs_referral(xid, ses, cache_nlsc, tcon->remap, npath, &refs,
1554                               &numrefs);
1555         if (!rc) {
1556                 dump_refs(refs, numrefs);
1557                 rc = update_cache_entry(npath, refs, numrefs);
1558                 free_dfs_info_array(refs, numrefs);
1559         }
1560
1561         if (root_ses)
1562                 cifs_put_smb_ses(root_ses);
1563
1564 out_free_path:
1565         free_normalized_path(path, npath);
1566
1567 out_free_xid:
1568         free_xid(xid);
1569         return rc;
1570 }
1571
1572 /*
1573  * Worker that will refresh DFS cache based on lowest TTL value from a DFS
1574  * referral.
1575  */
1576 static void refresh_cache_worker(struct work_struct *work)
1577 {
1578         struct vol_info *vi, *nvi;
1579         struct TCP_Server_Info *server;
1580         LIST_HEAD(vols);
1581         LIST_HEAD(tcons);
1582         struct cifs_tcon *tcon, *ntcon;
1583         int rc;
1584
1585         /*
1586          * Find SMB volumes that are eligible (server->tcpStatus == CifsGood)
1587          * for refreshing.
1588          */
1589         spin_lock(&vol_list_lock);
1590         list_for_each_entry(vi, &vol_list, list) {
1591                 server = get_tcp_server(&vi->smb_vol);
1592                 if (!server)
1593                         continue;
1594
1595                 kref_get(&vi->refcnt);
1596                 list_add_tail(&vi->rlist, &vols);
1597                 put_tcp_server(server);
1598         }
1599         spin_unlock(&vol_list_lock);
1600
1601         /* Walk through all TCONs and refresh any expired cache entry */
1602         list_for_each_entry_safe(vi, nvi, &vols, rlist) {
1603                 spin_lock(&vi->smb_vol_lock);
1604                 server = get_tcp_server(&vi->smb_vol);
1605                 spin_unlock(&vi->smb_vol_lock);
1606
1607                 if (!server)
1608                         goto next_vol;
1609
1610                 get_tcons(server, &tcons);
1611                 rc = 0;
1612
1613                 list_for_each_entry_safe(tcon, ntcon, &tcons, ulist) {
1614                         /*
1615                          * Skip tcp server if any of its tcons failed to refresh
1616                          * (possibily due to reconnects).
1617                          */
1618                         if (!rc)
1619                                 rc = refresh_tcon(vi, tcon);
1620
1621                         list_del_init(&tcon->ulist);
1622                         cifs_put_tcon(tcon);
1623                 }
1624
1625                 put_tcp_server(server);
1626
1627 next_vol:
1628                 list_del_init(&vi->rlist);
1629                 kref_put(&vi->refcnt, vol_release);
1630         }
1631
1632         spin_lock(&cache_ttl_lock);
1633         queue_delayed_work(dfscache_wq, &refresh_task, cache_ttl * HZ);
1634         spin_unlock(&cache_ttl_lock);
1635 }