cached_dir.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * Functions to handle the cached directory entries
  4. *
  5. * Copyright (c) 2022, Ronnie Sahlberg <lsahlber@redhat.com>
  6. */
  7. #include <linux/namei.h>
  8. #include "cifsglob.h"
  9. #include "cifsproto.h"
  10. #include "cifs_debug.h"
  11. #include "smb2proto.h"
  12. #include "cached_dir.h"
  13. static struct cached_fid *init_cached_dir(const char *path);
  14. static void free_cached_dir(struct cached_fid *cfid);
  15. static void smb2_close_cached_fid(struct kref *ref);
  16. static void cfids_laundromat_worker(struct work_struct *work);
  17. struct cached_dir_dentry {
  18. struct list_head entry;
  19. struct dentry *dentry;
  20. };
  21. static struct cached_fid *find_or_create_cached_dir(struct cached_fids *cfids,
  22. const char *path,
  23. bool lookup_only,
  24. __u32 max_cached_dirs)
  25. {
  26. struct cached_fid *cfid;
  27. list_for_each_entry(cfid, &cfids->entries, entry) {
  28. if (!strcmp(cfid->path, path)) {
  29. /*
  30. * If it doesn't have a lease it is either not yet
  31. * fully cached or it may be in the process of
  32. * being deleted due to a lease break.
  33. */
  34. if (!cfid->time || !cfid->has_lease) {
  35. return NULL;
  36. }
  37. kref_get(&cfid->refcount);
  38. return cfid;
  39. }
  40. }
  41. if (lookup_only) {
  42. return NULL;
  43. }
  44. if (cfids->num_entries >= max_cached_dirs) {
  45. return NULL;
  46. }
  47. cfid = init_cached_dir(path);
  48. if (cfid == NULL) {
  49. return NULL;
  50. }
  51. cfid->cfids = cfids;
  52. cfids->num_entries++;
  53. list_add(&cfid->entry, &cfids->entries);
  54. cfid->on_list = true;
  55. kref_get(&cfid->refcount);
  56. /*
  57. * Set @cfid->has_lease to true during construction so that the lease
  58. * reference can be put in cached_dir_lease_break() due to a potential
  59. * lease break right after the request is sent or while @cfid is still
  60. * being cached, or if a reconnection is triggered during construction.
  61. * Concurrent processes won't be to use it yet due to @cfid->time being
  62. * zero.
  63. */
  64. cfid->has_lease = true;
  65. return cfid;
  66. }
  67. static struct dentry *
  68. path_to_dentry(struct cifs_sb_info *cifs_sb, const char *path)
  69. {
  70. struct dentry *dentry;
  71. const char *s, *p;
  72. char sep;
  73. sep = CIFS_DIR_SEP(cifs_sb);
  74. dentry = dget(cifs_sb->root);
  75. s = path;
  76. do {
  77. struct inode *dir = d_inode(dentry);
  78. struct dentry *child;
  79. if (!S_ISDIR(dir->i_mode)) {
  80. dput(dentry);
  81. dentry = ERR_PTR(-ENOTDIR);
  82. break;
  83. }
  84. /* skip separators */
  85. while (*s == sep)
  86. s++;
  87. if (!*s)
  88. break;
  89. p = s++;
  90. /* next separator */
  91. while (*s && *s != sep)
  92. s++;
  93. child = lookup_positive_unlocked(p, dentry, s - p);
  94. dput(dentry);
  95. dentry = child;
  96. } while (!IS_ERR(dentry));
  97. return dentry;
  98. }
  99. static const char *path_no_prefix(struct cifs_sb_info *cifs_sb,
  100. const char *path)
  101. {
  102. size_t len = 0;
  103. if (!*path)
  104. return path;
  105. if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_USE_PREFIX_PATH) &&
  106. cifs_sb->prepath) {
  107. len = strlen(cifs_sb->prepath) + 1;
  108. if (unlikely(len > strlen(path)))
  109. return ERR_PTR(-EINVAL);
  110. }
  111. return path + len;
  112. }
  113. /*
  114. * Open the and cache a directory handle.
  115. * If error then *cfid is not initialized.
  116. */
  117. int open_cached_dir(unsigned int xid, struct cifs_tcon *tcon,
  118. const char *path,
  119. struct cifs_sb_info *cifs_sb,
  120. bool lookup_only, struct cached_fid **ret_cfid)
  121. {
  122. struct cifs_ses *ses;
  123. struct TCP_Server_Info *server;
  124. struct cifs_open_parms oparms;
  125. struct smb2_create_rsp *o_rsp = NULL;
  126. struct smb2_query_info_rsp *qi_rsp = NULL;
  127. int resp_buftype[2];
  128. struct smb_rqst rqst[2];
  129. struct kvec rsp_iov[2];
  130. struct kvec open_iov[SMB2_CREATE_IOV_SIZE];
  131. struct kvec qi_iov[1];
  132. int rc, flags = 0;
  133. __le16 *utf16_path = NULL;
  134. u8 oplock = SMB2_OPLOCK_LEVEL_II;
  135. struct cifs_fid *pfid;
  136. struct dentry *dentry = NULL;
  137. struct cached_fid *cfid;
  138. struct cached_fids *cfids;
  139. const char *npath;
  140. int retries = 0, cur_sleep = 1;
  141. if (tcon == NULL || tcon->cfids == NULL || tcon->nohandlecache ||
  142. is_smb1_server(tcon->ses->server) || (dir_cache_timeout == 0))
  143. return -EOPNOTSUPP;
  144. ses = tcon->ses;
  145. cfids = tcon->cfids;
  146. if (cifs_sb->root == NULL)
  147. return -ENOENT;
  148. replay_again:
  149. /* reinitialize for possible replay */
  150. flags = 0;
  151. oplock = SMB2_OPLOCK_LEVEL_II;
  152. server = cifs_pick_channel(ses);
  153. if (!server->ops->new_lease_key)
  154. return -EIO;
  155. utf16_path = cifs_convert_path_to_utf16(path, cifs_sb);
  156. if (!utf16_path)
  157. return -ENOMEM;
  158. spin_lock(&cfids->cfid_list_lock);
  159. cfid = find_or_create_cached_dir(cfids, path, lookup_only, tcon->max_cached_dirs);
  160. if (cfid == NULL) {
  161. spin_unlock(&cfids->cfid_list_lock);
  162. kfree(utf16_path);
  163. return -ENOENT;
  164. }
  165. /*
  166. * Return cached fid if it is valid (has a lease and has a time).
  167. * Otherwise, it is either a new entry or laundromat worker removed it
  168. * from @cfids->entries. Caller will put last reference if the latter.
  169. */
  170. if (cfid->has_lease && cfid->time) {
  171. spin_unlock(&cfids->cfid_list_lock);
  172. *ret_cfid = cfid;
  173. kfree(utf16_path);
  174. return 0;
  175. }
  176. spin_unlock(&cfids->cfid_list_lock);
  177. /*
  178. * Skip any prefix paths in @path as lookup_positive_unlocked() ends up
  179. * calling ->lookup() which already adds those through
  180. * build_path_from_dentry(). Also, do it earlier as we might reconnect
  181. * below when trying to send compounded request and then potentially
  182. * having a different prefix path (e.g. after DFS failover).
  183. */
  184. npath = path_no_prefix(cifs_sb, path);
  185. if (IS_ERR(npath)) {
  186. rc = PTR_ERR(npath);
  187. goto out;
  188. }
  189. if (!npath[0]) {
  190. dentry = dget(cifs_sb->root);
  191. } else {
  192. dentry = path_to_dentry(cifs_sb, npath);
  193. if (IS_ERR(dentry)) {
  194. rc = -ENOENT;
  195. goto out;
  196. }
  197. }
  198. cfid->dentry = dentry;
  199. cfid->tcon = tcon;
  200. /*
  201. * We do not hold the lock for the open because in case
  202. * SMB2_open needs to reconnect.
  203. * This is safe because no other thread will be able to get a ref
  204. * to the cfid until we have finished opening the file and (possibly)
  205. * acquired a lease.
  206. */
  207. if (smb3_encryption_required(tcon))
  208. flags |= CIFS_TRANSFORM_REQ;
  209. pfid = &cfid->fid;
  210. server->ops->new_lease_key(pfid);
  211. memset(rqst, 0, sizeof(rqst));
  212. resp_buftype[0] = resp_buftype[1] = CIFS_NO_BUFFER;
  213. memset(rsp_iov, 0, sizeof(rsp_iov));
  214. /* Open */
  215. memset(&open_iov, 0, sizeof(open_iov));
  216. rqst[0].rq_iov = open_iov;
  217. rqst[0].rq_nvec = SMB2_CREATE_IOV_SIZE;
  218. oparms = (struct cifs_open_parms) {
  219. .tcon = tcon,
  220. .path = path,
  221. .create_options = cifs_create_options(cifs_sb, CREATE_NOT_FILE),
  222. .desired_access = FILE_READ_DATA | FILE_READ_ATTRIBUTES |
  223. FILE_READ_EA,
  224. .disposition = FILE_OPEN,
  225. .fid = pfid,
  226. .replay = !!(retries),
  227. };
  228. rc = SMB2_open_init(tcon, server,
  229. &rqst[0], &oplock, &oparms, utf16_path);
  230. if (rc)
  231. goto oshr_free;
  232. smb2_set_next_command(tcon, &rqst[0]);
  233. memset(&qi_iov, 0, sizeof(qi_iov));
  234. rqst[1].rq_iov = qi_iov;
  235. rqst[1].rq_nvec = 1;
  236. rc = SMB2_query_info_init(tcon, server,
  237. &rqst[1], COMPOUND_FID,
  238. COMPOUND_FID, FILE_ALL_INFORMATION,
  239. SMB2_O_INFO_FILE, 0,
  240. sizeof(struct smb2_file_all_info) +
  241. PATH_MAX * 2, 0, NULL);
  242. if (rc)
  243. goto oshr_free;
  244. smb2_set_related(&rqst[1]);
  245. if (retries) {
  246. smb2_set_replay(server, &rqst[0]);
  247. smb2_set_replay(server, &rqst[1]);
  248. }
  249. rc = compound_send_recv(xid, ses, server,
  250. flags, 2, rqst,
  251. resp_buftype, rsp_iov);
  252. if (rc) {
  253. if (rc == -EREMCHG) {
  254. tcon->need_reconnect = true;
  255. pr_warn_once("server share %s deleted\n",
  256. tcon->tree_name);
  257. }
  258. goto oshr_free;
  259. }
  260. cfid->is_open = true;
  261. spin_lock(&cfids->cfid_list_lock);
  262. o_rsp = (struct smb2_create_rsp *)rsp_iov[0].iov_base;
  263. oparms.fid->persistent_fid = o_rsp->PersistentFileId;
  264. oparms.fid->volatile_fid = o_rsp->VolatileFileId;
  265. #ifdef CONFIG_CIFS_DEBUG2
  266. oparms.fid->mid = le64_to_cpu(o_rsp->hdr.MessageId);
  267. #endif /* CIFS_DEBUG2 */
  268. if (o_rsp->OplockLevel != SMB2_OPLOCK_LEVEL_LEASE) {
  269. spin_unlock(&cfids->cfid_list_lock);
  270. rc = -EINVAL;
  271. goto oshr_free;
  272. }
  273. rc = smb2_parse_contexts(server, rsp_iov,
  274. &oparms.fid->epoch,
  275. oparms.fid->lease_key,
  276. &oplock, NULL, NULL);
  277. if (rc) {
  278. spin_unlock(&cfids->cfid_list_lock);
  279. goto oshr_free;
  280. }
  281. rc = -EINVAL;
  282. if (!(oplock & SMB2_LEASE_READ_CACHING_HE)) {
  283. spin_unlock(&cfids->cfid_list_lock);
  284. goto oshr_free;
  285. }
  286. qi_rsp = (struct smb2_query_info_rsp *)rsp_iov[1].iov_base;
  287. if (le32_to_cpu(qi_rsp->OutputBufferLength) < sizeof(struct smb2_file_all_info)) {
  288. spin_unlock(&cfids->cfid_list_lock);
  289. goto oshr_free;
  290. }
  291. if (!smb2_validate_and_copy_iov(
  292. le16_to_cpu(qi_rsp->OutputBufferOffset),
  293. sizeof(struct smb2_file_all_info),
  294. &rsp_iov[1], sizeof(struct smb2_file_all_info),
  295. (char *)&cfid->file_all_info))
  296. cfid->file_all_info_is_valid = true;
  297. cfid->time = jiffies;
  298. spin_unlock(&cfids->cfid_list_lock);
  299. /* At this point the directory handle is fully cached */
  300. rc = 0;
  301. oshr_free:
  302. SMB2_open_free(&rqst[0]);
  303. SMB2_query_info_free(&rqst[1]);
  304. free_rsp_buf(resp_buftype[0], rsp_iov[0].iov_base);
  305. free_rsp_buf(resp_buftype[1], rsp_iov[1].iov_base);
  306. out:
  307. if (rc) {
  308. spin_lock(&cfids->cfid_list_lock);
  309. if (cfid->on_list) {
  310. list_del(&cfid->entry);
  311. cfid->on_list = false;
  312. cfids->num_entries--;
  313. }
  314. if (cfid->has_lease) {
  315. /*
  316. * We are guaranteed to have two references at this
  317. * point. One for the caller and one for a potential
  318. * lease. Release one here, and the second below.
  319. */
  320. cfid->has_lease = false;
  321. kref_put(&cfid->refcount, smb2_close_cached_fid);
  322. }
  323. spin_unlock(&cfids->cfid_list_lock);
  324. kref_put(&cfid->refcount, smb2_close_cached_fid);
  325. } else {
  326. *ret_cfid = cfid;
  327. atomic_inc(&tcon->num_remote_opens);
  328. }
  329. kfree(utf16_path);
  330. if (is_replayable_error(rc) &&
  331. smb2_should_replay(tcon, &retries, &cur_sleep))
  332. goto replay_again;
  333. return rc;
  334. }
  335. int open_cached_dir_by_dentry(struct cifs_tcon *tcon,
  336. struct dentry *dentry,
  337. struct cached_fid **ret_cfid)
  338. {
  339. struct cached_fid *cfid;
  340. struct cached_fids *cfids = tcon->cfids;
  341. if (cfids == NULL)
  342. return -ENOENT;
  343. spin_lock(&cfids->cfid_list_lock);
  344. list_for_each_entry(cfid, &cfids->entries, entry) {
  345. if (dentry && cfid->dentry == dentry) {
  346. cifs_dbg(FYI, "found a cached file handle by dentry\n");
  347. kref_get(&cfid->refcount);
  348. *ret_cfid = cfid;
  349. spin_unlock(&cfids->cfid_list_lock);
  350. return 0;
  351. }
  352. }
  353. spin_unlock(&cfids->cfid_list_lock);
  354. return -ENOENT;
  355. }
  356. static void
  357. smb2_close_cached_fid(struct kref *ref)
  358. {
  359. struct cached_fid *cfid = container_of(ref, struct cached_fid,
  360. refcount);
  361. int rc;
  362. spin_lock(&cfid->cfids->cfid_list_lock);
  363. if (cfid->on_list) {
  364. list_del(&cfid->entry);
  365. cfid->on_list = false;
  366. cfid->cfids->num_entries--;
  367. }
  368. spin_unlock(&cfid->cfids->cfid_list_lock);
  369. dput(cfid->dentry);
  370. cfid->dentry = NULL;
  371. if (cfid->is_open) {
  372. rc = SMB2_close(0, cfid->tcon, cfid->fid.persistent_fid,
  373. cfid->fid.volatile_fid);
  374. if (rc) /* should we retry on -EBUSY or -EAGAIN? */
  375. cifs_dbg(VFS, "close cached dir rc %d\n", rc);
  376. }
  377. free_cached_dir(cfid);
  378. }
  379. void drop_cached_dir_by_name(const unsigned int xid, struct cifs_tcon *tcon,
  380. const char *name, struct cifs_sb_info *cifs_sb)
  381. {
  382. struct cached_fid *cfid = NULL;
  383. int rc;
  384. rc = open_cached_dir(xid, tcon, name, cifs_sb, true, &cfid);
  385. if (rc) {
  386. cifs_dbg(FYI, "no cached dir found for rmdir(%s)\n", name);
  387. return;
  388. }
  389. spin_lock(&cfid->cfids->cfid_list_lock);
  390. if (cfid->has_lease) {
  391. cfid->has_lease = false;
  392. kref_put(&cfid->refcount, smb2_close_cached_fid);
  393. }
  394. spin_unlock(&cfid->cfids->cfid_list_lock);
  395. close_cached_dir(cfid);
  396. }
  397. void close_cached_dir(struct cached_fid *cfid)
  398. {
  399. kref_put(&cfid->refcount, smb2_close_cached_fid);
  400. }
  401. /*
  402. * Called from cifs_kill_sb when we unmount a share
  403. */
  404. void close_all_cached_dirs(struct cifs_sb_info *cifs_sb)
  405. {
  406. struct rb_root *root = &cifs_sb->tlink_tree;
  407. struct rb_node *node;
  408. struct cached_fid *cfid;
  409. struct cifs_tcon *tcon;
  410. struct tcon_link *tlink;
  411. struct cached_fids *cfids;
  412. struct cached_dir_dentry *tmp_list, *q;
  413. LIST_HEAD(entry);
  414. spin_lock(&cifs_sb->tlink_tree_lock);
  415. for (node = rb_first(root); node; node = rb_next(node)) {
  416. tlink = rb_entry(node, struct tcon_link, tl_rbnode);
  417. tcon = tlink_tcon(tlink);
  418. if (IS_ERR(tcon))
  419. continue;
  420. cfids = tcon->cfids;
  421. if (cfids == NULL)
  422. continue;
  423. spin_lock(&cfids->cfid_list_lock);
  424. list_for_each_entry(cfid, &cfids->entries, entry) {
  425. tmp_list = kmalloc(sizeof(*tmp_list), GFP_ATOMIC);
  426. if (tmp_list == NULL) {
  427. /*
  428. * If the malloc() fails, we won't drop all
  429. * dentries, and unmounting is likely to trigger
  430. * a 'Dentry still in use' error.
  431. */
  432. cifs_tcon_dbg(VFS, "Out of memory while dropping dentries\n");
  433. spin_unlock(&cfids->cfid_list_lock);
  434. spin_unlock(&cifs_sb->tlink_tree_lock);
  435. goto done;
  436. }
  437. spin_lock(&cfid->fid_lock);
  438. tmp_list->dentry = cfid->dentry;
  439. cfid->dentry = NULL;
  440. spin_unlock(&cfid->fid_lock);
  441. list_add_tail(&tmp_list->entry, &entry);
  442. }
  443. spin_unlock(&cfids->cfid_list_lock);
  444. }
  445. spin_unlock(&cifs_sb->tlink_tree_lock);
  446. done:
  447. list_for_each_entry_safe(tmp_list, q, &entry, entry) {
  448. list_del(&tmp_list->entry);
  449. dput(tmp_list->dentry);
  450. kfree(tmp_list);
  451. }
  452. /* Flush any pending work that will drop dentries */
  453. flush_workqueue(cfid_put_wq);
  454. }
  455. /*
  456. * Invalidate all cached dirs when a TCON has been reset
  457. * due to a session loss.
  458. */
  459. void invalidate_all_cached_dirs(struct cifs_tcon *tcon)
  460. {
  461. struct cached_fids *cfids = tcon->cfids;
  462. struct cached_fid *cfid, *q;
  463. if (cfids == NULL)
  464. return;
  465. /*
  466. * Mark all the cfids as closed, and move them to the cfids->dying list.
  467. * They'll be cleaned up later by cfids_invalidation_worker. Take
  468. * a reference to each cfid during this process.
  469. */
  470. spin_lock(&cfids->cfid_list_lock);
  471. list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {
  472. list_move(&cfid->entry, &cfids->dying);
  473. cfids->num_entries--;
  474. cfid->is_open = false;
  475. cfid->on_list = false;
  476. if (cfid->has_lease) {
  477. /*
  478. * The lease was never cancelled from the server,
  479. * so steal that reference.
  480. */
  481. cfid->has_lease = false;
  482. } else
  483. kref_get(&cfid->refcount);
  484. }
  485. /*
  486. * Queue dropping of the dentries once locks have been dropped
  487. */
  488. if (!list_empty(&cfids->dying))
  489. queue_work(cfid_put_wq, &cfids->invalidation_work);
  490. spin_unlock(&cfids->cfid_list_lock);
  491. }
  492. static void
  493. cached_dir_offload_close(struct work_struct *work)
  494. {
  495. struct cached_fid *cfid = container_of(work,
  496. struct cached_fid, close_work);
  497. struct cifs_tcon *tcon = cfid->tcon;
  498. WARN_ON(cfid->on_list);
  499. kref_put(&cfid->refcount, smb2_close_cached_fid);
  500. cifs_put_tcon(tcon, netfs_trace_tcon_ref_put_cached_close);
  501. }
  502. /*
  503. * Release the cached directory's dentry, and then queue work to drop cached
  504. * directory itself (closing on server if needed).
  505. *
  506. * Must be called with a reference to the cached_fid and a reference to the
  507. * tcon.
  508. */
  509. static void cached_dir_put_work(struct work_struct *work)
  510. {
  511. struct cached_fid *cfid = container_of(work, struct cached_fid,
  512. put_work);
  513. struct dentry *dentry;
  514. spin_lock(&cfid->fid_lock);
  515. dentry = cfid->dentry;
  516. cfid->dentry = NULL;
  517. spin_unlock(&cfid->fid_lock);
  518. dput(dentry);
  519. queue_work(serverclose_wq, &cfid->close_work);
  520. }
  521. int cached_dir_lease_break(struct cifs_tcon *tcon, __u8 lease_key[16])
  522. {
  523. struct cached_fids *cfids = tcon->cfids;
  524. struct cached_fid *cfid;
  525. if (cfids == NULL)
  526. return false;
  527. spin_lock(&cfids->cfid_list_lock);
  528. list_for_each_entry(cfid, &cfids->entries, entry) {
  529. if (cfid->has_lease &&
  530. !memcmp(lease_key,
  531. cfid->fid.lease_key,
  532. SMB2_LEASE_KEY_SIZE)) {
  533. cfid->has_lease = false;
  534. cfid->time = 0;
  535. /*
  536. * We found a lease remove it from the list
  537. * so no threads can access it.
  538. */
  539. list_del(&cfid->entry);
  540. cfid->on_list = false;
  541. cfids->num_entries--;
  542. ++tcon->tc_count;
  543. trace_smb3_tcon_ref(tcon->debug_id, tcon->tc_count,
  544. netfs_trace_tcon_ref_get_cached_lease_break);
  545. queue_work(cfid_put_wq, &cfid->put_work);
  546. spin_unlock(&cfids->cfid_list_lock);
  547. return true;
  548. }
  549. }
  550. spin_unlock(&cfids->cfid_list_lock);
  551. return false;
  552. }
  553. static struct cached_fid *init_cached_dir(const char *path)
  554. {
  555. struct cached_fid *cfid;
  556. cfid = kzalloc(sizeof(*cfid), GFP_ATOMIC);
  557. if (!cfid)
  558. return NULL;
  559. cfid->path = kstrdup(path, GFP_ATOMIC);
  560. if (!cfid->path) {
  561. kfree(cfid);
  562. return NULL;
  563. }
  564. INIT_WORK(&cfid->close_work, cached_dir_offload_close);
  565. INIT_WORK(&cfid->put_work, cached_dir_put_work);
  566. INIT_LIST_HEAD(&cfid->entry);
  567. INIT_LIST_HEAD(&cfid->dirents.entries);
  568. mutex_init(&cfid->dirents.de_mutex);
  569. spin_lock_init(&cfid->fid_lock);
  570. kref_init(&cfid->refcount);
  571. return cfid;
  572. }
  573. static void free_cached_dir(struct cached_fid *cfid)
  574. {
  575. struct cached_dirent *dirent, *q;
  576. WARN_ON(work_pending(&cfid->close_work));
  577. WARN_ON(work_pending(&cfid->put_work));
  578. dput(cfid->dentry);
  579. cfid->dentry = NULL;
  580. /*
  581. * Delete all cached dirent names
  582. */
  583. list_for_each_entry_safe(dirent, q, &cfid->dirents.entries, entry) {
  584. list_del(&dirent->entry);
  585. kfree(dirent->name);
  586. kfree(dirent);
  587. }
  588. kfree(cfid->path);
  589. cfid->path = NULL;
  590. kfree(cfid);
  591. }
  592. static void cfids_invalidation_worker(struct work_struct *work)
  593. {
  594. struct cached_fids *cfids = container_of(work, struct cached_fids,
  595. invalidation_work);
  596. struct cached_fid *cfid, *q;
  597. LIST_HEAD(entry);
  598. spin_lock(&cfids->cfid_list_lock);
  599. /* move cfids->dying to the local list */
  600. list_cut_before(&entry, &cfids->dying, &cfids->dying);
  601. spin_unlock(&cfids->cfid_list_lock);
  602. list_for_each_entry_safe(cfid, q, &entry, entry) {
  603. list_del(&cfid->entry);
  604. /* Drop the ref-count acquired in invalidate_all_cached_dirs */
  605. kref_put(&cfid->refcount, smb2_close_cached_fid);
  606. }
  607. }
  608. static void cfids_laundromat_worker(struct work_struct *work)
  609. {
  610. struct cached_fids *cfids;
  611. struct cached_fid *cfid, *q;
  612. struct dentry *dentry;
  613. LIST_HEAD(entry);
  614. cfids = container_of(work, struct cached_fids, laundromat_work.work);
  615. spin_lock(&cfids->cfid_list_lock);
  616. list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {
  617. if (cfid->time &&
  618. time_after(jiffies, cfid->time + HZ * dir_cache_timeout)) {
  619. cfid->on_list = false;
  620. list_move(&cfid->entry, &entry);
  621. cfids->num_entries--;
  622. if (cfid->has_lease) {
  623. /*
  624. * Our lease has not yet been cancelled from the
  625. * server. Steal that reference.
  626. */
  627. cfid->has_lease = false;
  628. } else
  629. kref_get(&cfid->refcount);
  630. }
  631. }
  632. spin_unlock(&cfids->cfid_list_lock);
  633. list_for_each_entry_safe(cfid, q, &entry, entry) {
  634. list_del(&cfid->entry);
  635. spin_lock(&cfid->fid_lock);
  636. dentry = cfid->dentry;
  637. cfid->dentry = NULL;
  638. spin_unlock(&cfid->fid_lock);
  639. dput(dentry);
  640. if (cfid->is_open) {
  641. spin_lock(&cifs_tcp_ses_lock);
  642. ++cfid->tcon->tc_count;
  643. trace_smb3_tcon_ref(cfid->tcon->debug_id, cfid->tcon->tc_count,
  644. netfs_trace_tcon_ref_get_cached_laundromat);
  645. spin_unlock(&cifs_tcp_ses_lock);
  646. queue_work(serverclose_wq, &cfid->close_work);
  647. } else
  648. /*
  649. * Drop the ref-count from above, either the lease-ref (if there
  650. * was one) or the extra one acquired.
  651. */
  652. kref_put(&cfid->refcount, smb2_close_cached_fid);
  653. }
  654. queue_delayed_work(cfid_put_wq, &cfids->laundromat_work,
  655. dir_cache_timeout * HZ);
  656. }
  657. struct cached_fids *init_cached_dirs(void)
  658. {
  659. struct cached_fids *cfids;
  660. cfids = kzalloc(sizeof(*cfids), GFP_KERNEL);
  661. if (!cfids)
  662. return NULL;
  663. spin_lock_init(&cfids->cfid_list_lock);
  664. INIT_LIST_HEAD(&cfids->entries);
  665. INIT_LIST_HEAD(&cfids->dying);
  666. INIT_WORK(&cfids->invalidation_work, cfids_invalidation_worker);
  667. INIT_DELAYED_WORK(&cfids->laundromat_work, cfids_laundromat_worker);
  668. queue_delayed_work(cfid_put_wq, &cfids->laundromat_work,
  669. dir_cache_timeout * HZ);
  670. return cfids;
  671. }
  672. /*
  673. * Called from tconInfoFree when we are tearing down the tcon.
  674. * There are no active users or open files/directories at this point.
  675. */
  676. void free_cached_dirs(struct cached_fids *cfids)
  677. {
  678. struct cached_fid *cfid, *q;
  679. LIST_HEAD(entry);
  680. if (cfids == NULL)
  681. return;
  682. cancel_delayed_work_sync(&cfids->laundromat_work);
  683. cancel_work_sync(&cfids->invalidation_work);
  684. spin_lock(&cfids->cfid_list_lock);
  685. list_for_each_entry_safe(cfid, q, &cfids->entries, entry) {
  686. cfid->on_list = false;
  687. cfid->is_open = false;
  688. list_move(&cfid->entry, &entry);
  689. }
  690. list_for_each_entry_safe(cfid, q, &cfids->dying, entry) {
  691. cfid->on_list = false;
  692. cfid->is_open = false;
  693. list_move(&cfid->entry, &entry);
  694. }
  695. spin_unlock(&cfids->cfid_list_lock);
  696. list_for_each_entry_safe(cfid, q, &entry, entry) {
  697. list_del(&cfid->entry);
  698. free_cached_dir(cfid);
  699. }
  700. kfree(cfids);
  701. }