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