dfs_cache.c 31 KB

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