object.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811
  1. /* FS-Cache object state machine handler
  2. *
  3. * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
  4. * Written by David Howells (dhowells@redhat.com)
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version
  9. * 2 of the License, or (at your option) any later version.
  10. *
  11. * See Documentation/filesystems/caching/object.txt for a description of the
  12. * object state machine and the in-kernel representations.
  13. */
  14. #define FSCACHE_DEBUG_LEVEL COOKIE
  15. #include <linux/module.h>
  16. #include "internal.h"
  17. const char *fscache_object_states[] = {
  18. [FSCACHE_OBJECT_INIT] = "OBJECT_INIT",
  19. [FSCACHE_OBJECT_LOOKING_UP] = "OBJECT_LOOKING_UP",
  20. [FSCACHE_OBJECT_CREATING] = "OBJECT_CREATING",
  21. [FSCACHE_OBJECT_AVAILABLE] = "OBJECT_AVAILABLE",
  22. [FSCACHE_OBJECT_ACTIVE] = "OBJECT_ACTIVE",
  23. [FSCACHE_OBJECT_UPDATING] = "OBJECT_UPDATING",
  24. [FSCACHE_OBJECT_DYING] = "OBJECT_DYING",
  25. [FSCACHE_OBJECT_LC_DYING] = "OBJECT_LC_DYING",
  26. [FSCACHE_OBJECT_ABORT_INIT] = "OBJECT_ABORT_INIT",
  27. [FSCACHE_OBJECT_RELEASING] = "OBJECT_RELEASING",
  28. [FSCACHE_OBJECT_RECYCLING] = "OBJECT_RECYCLING",
  29. [FSCACHE_OBJECT_WITHDRAWING] = "OBJECT_WITHDRAWING",
  30. [FSCACHE_OBJECT_DEAD] = "OBJECT_DEAD",
  31. };
  32. EXPORT_SYMBOL(fscache_object_states);
  33. static void fscache_object_slow_work_put_ref(struct slow_work *);
  34. static int fscache_object_slow_work_get_ref(struct slow_work *);
  35. static void fscache_object_slow_work_execute(struct slow_work *);
  36. static void fscache_initialise_object(struct fscache_object *);
  37. static void fscache_lookup_object(struct fscache_object *);
  38. static void fscache_object_available(struct fscache_object *);
  39. static void fscache_release_object(struct fscache_object *);
  40. static void fscache_withdraw_object(struct fscache_object *);
  41. static void fscache_enqueue_dependents(struct fscache_object *);
  42. static void fscache_dequeue_object(struct fscache_object *);
  43. const struct slow_work_ops fscache_object_slow_work_ops = {
  44. .owner = THIS_MODULE,
  45. .get_ref = fscache_object_slow_work_get_ref,
  46. .put_ref = fscache_object_slow_work_put_ref,
  47. .execute = fscache_object_slow_work_execute,
  48. };
  49. EXPORT_SYMBOL(fscache_object_slow_work_ops);
  50. /*
  51. * we need to notify the parent when an op completes that we had outstanding
  52. * upon it
  53. */
  54. static inline void fscache_done_parent_op(struct fscache_object *object)
  55. {
  56. struct fscache_object *parent = object->parent;
  57. _enter("OBJ%x {OBJ%x,%x}",
  58. object->debug_id, parent->debug_id, parent->n_ops);
  59. spin_lock_nested(&parent->lock, 1);
  60. parent->n_ops--;
  61. parent->n_obj_ops--;
  62. if (parent->n_ops == 0)
  63. fscache_raise_event(parent, FSCACHE_OBJECT_EV_CLEARED);
  64. spin_unlock(&parent->lock);
  65. }
  66. /*
  67. * process events that have been sent to an object's state machine
  68. * - initiates parent lookup
  69. * - does object lookup
  70. * - does object creation
  71. * - does object recycling and retirement
  72. * - does object withdrawal
  73. */
  74. static void fscache_object_state_machine(struct fscache_object *object)
  75. {
  76. enum fscache_object_state new_state;
  77. ASSERT(object != NULL);
  78. _enter("{OBJ%x,%s,%lx}",
  79. object->debug_id, fscache_object_states[object->state],
  80. object->events);
  81. switch (object->state) {
  82. /* wait for the parent object to become ready */
  83. case FSCACHE_OBJECT_INIT:
  84. object->event_mask =
  85. ULONG_MAX & ~(1 << FSCACHE_OBJECT_EV_CLEARED);
  86. fscache_initialise_object(object);
  87. goto done;
  88. /* look up the object metadata on disk */
  89. case FSCACHE_OBJECT_LOOKING_UP:
  90. fscache_lookup_object(object);
  91. goto lookup_transit;
  92. /* create the object metadata on disk */
  93. case FSCACHE_OBJECT_CREATING:
  94. fscache_lookup_object(object);
  95. goto lookup_transit;
  96. /* handle an object becoming available; start pending
  97. * operations and queue dependent operations for processing */
  98. case FSCACHE_OBJECT_AVAILABLE:
  99. fscache_object_available(object);
  100. goto active_transit;
  101. /* normal running state */
  102. case FSCACHE_OBJECT_ACTIVE:
  103. goto active_transit;
  104. /* update the object metadata on disk */
  105. case FSCACHE_OBJECT_UPDATING:
  106. clear_bit(FSCACHE_OBJECT_EV_UPDATE, &object->events);
  107. fscache_stat(&fscache_n_updates_run);
  108. object->cache->ops->update_object(object);
  109. goto active_transit;
  110. /* handle an object dying during lookup or creation */
  111. case FSCACHE_OBJECT_LC_DYING:
  112. object->event_mask &= ~(1 << FSCACHE_OBJECT_EV_UPDATE);
  113. object->cache->ops->lookup_complete(object);
  114. spin_lock(&object->lock);
  115. object->state = FSCACHE_OBJECT_DYING;
  116. if (test_and_clear_bit(FSCACHE_COOKIE_CREATING,
  117. &object->cookie->flags))
  118. wake_up_bit(&object->cookie->flags,
  119. FSCACHE_COOKIE_CREATING);
  120. spin_unlock(&object->lock);
  121. fscache_done_parent_op(object);
  122. /* wait for completion of all active operations on this object
  123. * and the death of all child objects of this object */
  124. case FSCACHE_OBJECT_DYING:
  125. dying:
  126. clear_bit(FSCACHE_OBJECT_EV_CLEARED, &object->events);
  127. spin_lock(&object->lock);
  128. _debug("dying OBJ%x {%d,%d}",
  129. object->debug_id, object->n_ops, object->n_children);
  130. if (object->n_ops == 0 && object->n_children == 0) {
  131. object->event_mask &=
  132. ~(1 << FSCACHE_OBJECT_EV_CLEARED);
  133. object->event_mask |=
  134. (1 << FSCACHE_OBJECT_EV_WITHDRAW) |
  135. (1 << FSCACHE_OBJECT_EV_RETIRE) |
  136. (1 << FSCACHE_OBJECT_EV_RELEASE) |
  137. (1 << FSCACHE_OBJECT_EV_ERROR);
  138. } else {
  139. object->event_mask &=
  140. ~((1 << FSCACHE_OBJECT_EV_WITHDRAW) |
  141. (1 << FSCACHE_OBJECT_EV_RETIRE) |
  142. (1 << FSCACHE_OBJECT_EV_RELEASE) |
  143. (1 << FSCACHE_OBJECT_EV_ERROR));
  144. object->event_mask |=
  145. 1 << FSCACHE_OBJECT_EV_CLEARED;
  146. }
  147. spin_unlock(&object->lock);
  148. fscache_enqueue_dependents(object);
  149. goto terminal_transit;
  150. /* handle an abort during initialisation */
  151. case FSCACHE_OBJECT_ABORT_INIT:
  152. _debug("handle abort init %lx", object->events);
  153. object->event_mask &= ~(1 << FSCACHE_OBJECT_EV_UPDATE);
  154. spin_lock(&object->lock);
  155. fscache_dequeue_object(object);
  156. object->state = FSCACHE_OBJECT_DYING;
  157. if (test_and_clear_bit(FSCACHE_COOKIE_CREATING,
  158. &object->cookie->flags))
  159. wake_up_bit(&object->cookie->flags,
  160. FSCACHE_COOKIE_CREATING);
  161. spin_unlock(&object->lock);
  162. goto dying;
  163. /* handle the netfs releasing an object and possibly marking it
  164. * obsolete too */
  165. case FSCACHE_OBJECT_RELEASING:
  166. case FSCACHE_OBJECT_RECYCLING:
  167. object->event_mask &=
  168. ~((1 << FSCACHE_OBJECT_EV_WITHDRAW) |
  169. (1 << FSCACHE_OBJECT_EV_RETIRE) |
  170. (1 << FSCACHE_OBJECT_EV_RELEASE) |
  171. (1 << FSCACHE_OBJECT_EV_ERROR));
  172. fscache_release_object(object);
  173. spin_lock(&object->lock);
  174. object->state = FSCACHE_OBJECT_DEAD;
  175. spin_unlock(&object->lock);
  176. fscache_stat(&fscache_n_object_dead);
  177. goto terminal_transit;
  178. /* handle the parent cache of this object being withdrawn from
  179. * active service */
  180. case FSCACHE_OBJECT_WITHDRAWING:
  181. object->event_mask &=
  182. ~((1 << FSCACHE_OBJECT_EV_WITHDRAW) |
  183. (1 << FSCACHE_OBJECT_EV_RETIRE) |
  184. (1 << FSCACHE_OBJECT_EV_RELEASE) |
  185. (1 << FSCACHE_OBJECT_EV_ERROR));
  186. fscache_withdraw_object(object);
  187. spin_lock(&object->lock);
  188. object->state = FSCACHE_OBJECT_DEAD;
  189. spin_unlock(&object->lock);
  190. fscache_stat(&fscache_n_object_dead);
  191. goto terminal_transit;
  192. /* complain about the object being woken up once it is
  193. * deceased */
  194. case FSCACHE_OBJECT_DEAD:
  195. printk(KERN_ERR "FS-Cache:"
  196. " Unexpected event in dead state %lx\n",
  197. object->events & object->event_mask);
  198. BUG();
  199. default:
  200. printk(KERN_ERR "FS-Cache: Unknown object state %u\n",
  201. object->state);
  202. BUG();
  203. }
  204. /* determine the transition from a lookup state */
  205. lookup_transit:
  206. switch (fls(object->events & object->event_mask) - 1) {
  207. case FSCACHE_OBJECT_EV_WITHDRAW:
  208. case FSCACHE_OBJECT_EV_RETIRE:
  209. case FSCACHE_OBJECT_EV_RELEASE:
  210. case FSCACHE_OBJECT_EV_ERROR:
  211. new_state = FSCACHE_OBJECT_LC_DYING;
  212. goto change_state;
  213. case FSCACHE_OBJECT_EV_REQUEUE:
  214. goto done;
  215. case -1:
  216. goto done; /* sleep until event */
  217. default:
  218. goto unsupported_event;
  219. }
  220. /* determine the transition from an active state */
  221. active_transit:
  222. switch (fls(object->events & object->event_mask) - 1) {
  223. case FSCACHE_OBJECT_EV_WITHDRAW:
  224. case FSCACHE_OBJECT_EV_RETIRE:
  225. case FSCACHE_OBJECT_EV_RELEASE:
  226. case FSCACHE_OBJECT_EV_ERROR:
  227. new_state = FSCACHE_OBJECT_DYING;
  228. goto change_state;
  229. case FSCACHE_OBJECT_EV_UPDATE:
  230. new_state = FSCACHE_OBJECT_UPDATING;
  231. goto change_state;
  232. case -1:
  233. new_state = FSCACHE_OBJECT_ACTIVE;
  234. goto change_state; /* sleep until event */
  235. default:
  236. goto unsupported_event;
  237. }
  238. /* determine the transition from a terminal state */
  239. terminal_transit:
  240. switch (fls(object->events & object->event_mask) - 1) {
  241. case FSCACHE_OBJECT_EV_WITHDRAW:
  242. new_state = FSCACHE_OBJECT_WITHDRAWING;
  243. goto change_state;
  244. case FSCACHE_OBJECT_EV_RETIRE:
  245. new_state = FSCACHE_OBJECT_RECYCLING;
  246. goto change_state;
  247. case FSCACHE_OBJECT_EV_RELEASE:
  248. new_state = FSCACHE_OBJECT_RELEASING;
  249. goto change_state;
  250. case FSCACHE_OBJECT_EV_ERROR:
  251. new_state = FSCACHE_OBJECT_WITHDRAWING;
  252. goto change_state;
  253. case FSCACHE_OBJECT_EV_CLEARED:
  254. new_state = FSCACHE_OBJECT_DYING;
  255. goto change_state;
  256. case -1:
  257. goto done; /* sleep until event */
  258. default:
  259. goto unsupported_event;
  260. }
  261. change_state:
  262. spin_lock(&object->lock);
  263. object->state = new_state;
  264. spin_unlock(&object->lock);
  265. done:
  266. _leave(" [->%s]", fscache_object_states[object->state]);
  267. return;
  268. unsupported_event:
  269. printk(KERN_ERR "FS-Cache:"
  270. " Unsupported event %lx [mask %lx] in state %s\n",
  271. object->events, object->event_mask,
  272. fscache_object_states[object->state]);
  273. BUG();
  274. }
  275. /*
  276. * execute an object
  277. */
  278. static void fscache_object_slow_work_execute(struct slow_work *work)
  279. {
  280. struct fscache_object *object =
  281. container_of(work, struct fscache_object, work);
  282. unsigned long start;
  283. _enter("{OBJ%x}", object->debug_id);
  284. clear_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
  285. start = jiffies;
  286. fscache_object_state_machine(object);
  287. fscache_hist(fscache_objs_histogram, start);
  288. if (object->events & object->event_mask)
  289. fscache_enqueue_object(object);
  290. }
  291. /*
  292. * initialise an object
  293. * - check the specified object's parent to see if we can make use of it
  294. * immediately to do a creation
  295. * - we may need to start the process of creating a parent and we need to wait
  296. * for the parent's lookup and creation to complete if it's not there yet
  297. * - an object's cookie is pinned until we clear FSCACHE_COOKIE_CREATING on the
  298. * leaf-most cookies of the object and all its children
  299. */
  300. static void fscache_initialise_object(struct fscache_object *object)
  301. {
  302. struct fscache_object *parent;
  303. _enter("");
  304. ASSERT(object->cookie != NULL);
  305. ASSERT(object->cookie->parent != NULL);
  306. ASSERT(list_empty(&object->work.link));
  307. if (object->events & ((1 << FSCACHE_OBJECT_EV_ERROR) |
  308. (1 << FSCACHE_OBJECT_EV_RELEASE) |
  309. (1 << FSCACHE_OBJECT_EV_RETIRE) |
  310. (1 << FSCACHE_OBJECT_EV_WITHDRAW))) {
  311. _debug("abort init %lx", object->events);
  312. spin_lock(&object->lock);
  313. object->state = FSCACHE_OBJECT_ABORT_INIT;
  314. spin_unlock(&object->lock);
  315. return;
  316. }
  317. spin_lock(&object->cookie->lock);
  318. spin_lock_nested(&object->cookie->parent->lock, 1);
  319. parent = object->parent;
  320. if (!parent) {
  321. _debug("no parent");
  322. set_bit(FSCACHE_OBJECT_EV_WITHDRAW, &object->events);
  323. } else {
  324. spin_lock(&object->lock);
  325. spin_lock_nested(&parent->lock, 1);
  326. _debug("parent %s", fscache_object_states[parent->state]);
  327. if (parent->state >= FSCACHE_OBJECT_DYING) {
  328. _debug("bad parent");
  329. set_bit(FSCACHE_OBJECT_EV_WITHDRAW, &object->events);
  330. } else if (parent->state < FSCACHE_OBJECT_AVAILABLE) {
  331. _debug("wait");
  332. /* we may get woken up in this state by child objects
  333. * binding on to us, so we need to make sure we don't
  334. * add ourself to the list multiple times */
  335. if (list_empty(&object->dep_link)) {
  336. object->cache->ops->grab_object(object);
  337. list_add(&object->dep_link,
  338. &parent->dependents);
  339. /* fscache_acquire_non_index_cookie() uses this
  340. * to wake the chain up */
  341. if (parent->state == FSCACHE_OBJECT_INIT)
  342. fscache_enqueue_object(parent);
  343. }
  344. } else {
  345. _debug("go");
  346. parent->n_ops++;
  347. parent->n_obj_ops++;
  348. object->lookup_jif = jiffies;
  349. object->state = FSCACHE_OBJECT_LOOKING_UP;
  350. set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
  351. }
  352. spin_unlock(&parent->lock);
  353. spin_unlock(&object->lock);
  354. }
  355. spin_unlock(&object->cookie->parent->lock);
  356. spin_unlock(&object->cookie->lock);
  357. _leave("");
  358. }
  359. /*
  360. * look an object up in the cache from which it was allocated
  361. * - we hold an "access lock" on the parent object, so the parent object cannot
  362. * be withdrawn by either party till we've finished
  363. * - an object's cookie is pinned until we clear FSCACHE_COOKIE_CREATING on the
  364. * leaf-most cookies of the object and all its children
  365. */
  366. static void fscache_lookup_object(struct fscache_object *object)
  367. {
  368. struct fscache_cookie *cookie = object->cookie;
  369. struct fscache_object *parent;
  370. _enter("");
  371. parent = object->parent;
  372. ASSERT(parent != NULL);
  373. ASSERTCMP(parent->n_ops, >, 0);
  374. ASSERTCMP(parent->n_obj_ops, >, 0);
  375. /* make sure the parent is still available */
  376. ASSERTCMP(parent->state, >=, FSCACHE_OBJECT_AVAILABLE);
  377. if (parent->state >= FSCACHE_OBJECT_DYING ||
  378. test_bit(FSCACHE_IOERROR, &object->cache->flags)) {
  379. _debug("unavailable");
  380. set_bit(FSCACHE_OBJECT_EV_WITHDRAW, &object->events);
  381. _leave("");
  382. return;
  383. }
  384. _debug("LOOKUP \"%s/%s\" in \"%s\"",
  385. parent->cookie->def->name, cookie->def->name,
  386. object->cache->tag->name);
  387. fscache_stat(&fscache_n_object_lookups);
  388. object->cache->ops->lookup_object(object);
  389. if (test_bit(FSCACHE_OBJECT_EV_ERROR, &object->events))
  390. set_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags);
  391. _leave("");
  392. }
  393. /**
  394. * fscache_object_lookup_negative - Note negative cookie lookup
  395. * @object: Object pointing to cookie to mark
  396. *
  397. * Note negative lookup, permitting those waiting to read data from an already
  398. * existing backing object to continue as there's no data for them to read.
  399. */
  400. void fscache_object_lookup_negative(struct fscache_object *object)
  401. {
  402. struct fscache_cookie *cookie = object->cookie;
  403. _enter("{OBJ%x,%s}",
  404. object->debug_id, fscache_object_states[object->state]);
  405. spin_lock(&object->lock);
  406. if (object->state == FSCACHE_OBJECT_LOOKING_UP) {
  407. fscache_stat(&fscache_n_object_lookups_negative);
  408. /* transit here to allow write requests to begin stacking up
  409. * and read requests to begin returning ENODATA */
  410. object->state = FSCACHE_OBJECT_CREATING;
  411. spin_unlock(&object->lock);
  412. set_bit(FSCACHE_COOKIE_PENDING_FILL, &cookie->flags);
  413. set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
  414. _debug("wake up lookup %p", &cookie->flags);
  415. smp_mb__before_clear_bit();
  416. clear_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags);
  417. smp_mb__after_clear_bit();
  418. wake_up_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP);
  419. set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
  420. } else {
  421. ASSERTCMP(object->state, ==, FSCACHE_OBJECT_CREATING);
  422. spin_unlock(&object->lock);
  423. }
  424. _leave("");
  425. }
  426. EXPORT_SYMBOL(fscache_object_lookup_negative);
  427. /**
  428. * fscache_obtained_object - Note successful object lookup or creation
  429. * @object: Object pointing to cookie to mark
  430. *
  431. * Note successful lookup and/or creation, permitting those waiting to write
  432. * data to a backing object to continue.
  433. *
  434. * Note that after calling this, an object's cookie may be relinquished by the
  435. * netfs, and so must be accessed with object lock held.
  436. */
  437. void fscache_obtained_object(struct fscache_object *object)
  438. {
  439. struct fscache_cookie *cookie = object->cookie;
  440. _enter("{OBJ%x,%s}",
  441. object->debug_id, fscache_object_states[object->state]);
  442. /* if we were still looking up, then we must have a positive lookup
  443. * result, in which case there may be data available */
  444. spin_lock(&object->lock);
  445. if (object->state == FSCACHE_OBJECT_LOOKING_UP) {
  446. fscache_stat(&fscache_n_object_lookups_positive);
  447. clear_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
  448. object->state = FSCACHE_OBJECT_AVAILABLE;
  449. spin_unlock(&object->lock);
  450. smp_mb__before_clear_bit();
  451. clear_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags);
  452. smp_mb__after_clear_bit();
  453. wake_up_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP);
  454. set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
  455. } else {
  456. ASSERTCMP(object->state, ==, FSCACHE_OBJECT_CREATING);
  457. fscache_stat(&fscache_n_object_created);
  458. object->state = FSCACHE_OBJECT_AVAILABLE;
  459. spin_unlock(&object->lock);
  460. set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
  461. smp_wmb();
  462. }
  463. if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, &cookie->flags))
  464. wake_up_bit(&cookie->flags, FSCACHE_COOKIE_CREATING);
  465. _leave("");
  466. }
  467. EXPORT_SYMBOL(fscache_obtained_object);
  468. /*
  469. * handle an object that has just become available
  470. */
  471. static void fscache_object_available(struct fscache_object *object)
  472. {
  473. _enter("{OBJ%x}", object->debug_id);
  474. spin_lock(&object->lock);
  475. if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, &object->cookie->flags))
  476. wake_up_bit(&object->cookie->flags, FSCACHE_COOKIE_CREATING);
  477. fscache_done_parent_op(object);
  478. if (object->n_in_progress == 0) {
  479. if (object->n_ops > 0) {
  480. ASSERTCMP(object->n_ops, >=, object->n_obj_ops);
  481. ASSERTIF(object->n_ops > object->n_obj_ops,
  482. !list_empty(&object->pending_ops));
  483. fscache_start_operations(object);
  484. } else {
  485. ASSERT(list_empty(&object->pending_ops));
  486. }
  487. }
  488. spin_unlock(&object->lock);
  489. object->cache->ops->lookup_complete(object);
  490. fscache_enqueue_dependents(object);
  491. fscache_hist(fscache_obj_instantiate_histogram, object->lookup_jif);
  492. fscache_stat(&fscache_n_object_avail);
  493. _leave("");
  494. }
  495. /*
  496. * drop an object's attachments
  497. */
  498. static void fscache_drop_object(struct fscache_object *object)
  499. {
  500. struct fscache_object *parent = object->parent;
  501. struct fscache_cache *cache = object->cache;
  502. _enter("{OBJ%x,%d}", object->debug_id, object->n_children);
  503. spin_lock(&cache->object_list_lock);
  504. list_del_init(&object->cache_link);
  505. spin_unlock(&cache->object_list_lock);
  506. cache->ops->drop_object(object);
  507. if (parent) {
  508. _debug("release parent OBJ%x {%d}",
  509. parent->debug_id, parent->n_children);
  510. spin_lock(&parent->lock);
  511. parent->n_children--;
  512. if (parent->n_children == 0)
  513. fscache_raise_event(parent, FSCACHE_OBJECT_EV_CLEARED);
  514. spin_unlock(&parent->lock);
  515. object->parent = NULL;
  516. }
  517. /* this just shifts the object release to the slow work processor */
  518. object->cache->ops->put_object(object);
  519. _leave("");
  520. }
  521. /*
  522. * release or recycle an object that the netfs has discarded
  523. */
  524. static void fscache_release_object(struct fscache_object *object)
  525. {
  526. _enter("");
  527. fscache_drop_object(object);
  528. }
  529. /*
  530. * withdraw an object from active service
  531. */
  532. static void fscache_withdraw_object(struct fscache_object *object)
  533. {
  534. struct fscache_cookie *cookie;
  535. bool detached;
  536. _enter("");
  537. spin_lock(&object->lock);
  538. cookie = object->cookie;
  539. if (cookie) {
  540. /* need to get the cookie lock before the object lock, starting
  541. * from the object pointer */
  542. atomic_inc(&cookie->usage);
  543. spin_unlock(&object->lock);
  544. detached = false;
  545. spin_lock(&cookie->lock);
  546. spin_lock(&object->lock);
  547. if (object->cookie == cookie) {
  548. hlist_del_init(&object->cookie_link);
  549. object->cookie = NULL;
  550. detached = true;
  551. }
  552. spin_unlock(&cookie->lock);
  553. fscache_cookie_put(cookie);
  554. if (detached)
  555. fscache_cookie_put(cookie);
  556. }
  557. spin_unlock(&object->lock);
  558. fscache_drop_object(object);
  559. }
  560. /*
  561. * withdraw an object from active service at the behest of the cache
  562. * - need break the links to a cached object cookie
  563. * - called under two situations:
  564. * (1) recycler decides to reclaim an in-use object
  565. * (2) a cache is unmounted
  566. * - have to take care as the cookie can be being relinquished by the netfs
  567. * simultaneously
  568. * - the object is pinned by the caller holding a refcount on it
  569. */
  570. void fscache_withdrawing_object(struct fscache_cache *cache,
  571. struct fscache_object *object)
  572. {
  573. bool enqueue = false;
  574. _enter(",OBJ%x", object->debug_id);
  575. spin_lock(&object->lock);
  576. if (object->state < FSCACHE_OBJECT_WITHDRAWING) {
  577. object->state = FSCACHE_OBJECT_WITHDRAWING;
  578. enqueue = true;
  579. }
  580. spin_unlock(&object->lock);
  581. if (enqueue)
  582. fscache_enqueue_object(object);
  583. _leave("");
  584. }
  585. /*
  586. * allow the slow work item processor to get a ref on an object
  587. */
  588. static int fscache_object_slow_work_get_ref(struct slow_work *work)
  589. {
  590. struct fscache_object *object =
  591. container_of(work, struct fscache_object, work);
  592. return object->cache->ops->grab_object(object) ? 0 : -EAGAIN;
  593. }
  594. /*
  595. * allow the slow work item processor to discard a ref on a work item
  596. */
  597. static void fscache_object_slow_work_put_ref(struct slow_work *work)
  598. {
  599. struct fscache_object *object =
  600. container_of(work, struct fscache_object, work);
  601. return object->cache->ops->put_object(object);
  602. }
  603. /*
  604. * enqueue an object for metadata-type processing
  605. */
  606. void fscache_enqueue_object(struct fscache_object *object)
  607. {
  608. _enter("{OBJ%x}", object->debug_id);
  609. slow_work_enqueue(&object->work);
  610. }
  611. /*
  612. * enqueue the dependents of an object for metadata-type processing
  613. * - the caller must hold the object's lock
  614. * - this may cause an already locked object to wind up being processed again
  615. */
  616. static void fscache_enqueue_dependents(struct fscache_object *object)
  617. {
  618. struct fscache_object *dep;
  619. _enter("{OBJ%x}", object->debug_id);
  620. if (list_empty(&object->dependents))
  621. return;
  622. spin_lock(&object->lock);
  623. while (!list_empty(&object->dependents)) {
  624. dep = list_entry(object->dependents.next,
  625. struct fscache_object, dep_link);
  626. list_del_init(&dep->dep_link);
  627. /* sort onto appropriate lists */
  628. fscache_enqueue_object(dep);
  629. dep->cache->ops->put_object(dep);
  630. if (!list_empty(&object->dependents))
  631. cond_resched_lock(&object->lock);
  632. }
  633. spin_unlock(&object->lock);
  634. }
  635. /*
  636. * remove an object from whatever queue it's waiting on
  637. * - the caller must hold object->lock
  638. */
  639. void fscache_dequeue_object(struct fscache_object *object)
  640. {
  641. _enter("{OBJ%x}", object->debug_id);
  642. if (!list_empty(&object->dep_link)) {
  643. spin_lock(&object->parent->lock);
  644. list_del_init(&object->dep_link);
  645. spin_unlock(&object->parent->lock);
  646. }
  647. _leave("");
  648. }
  649. /**
  650. * fscache_check_aux - Ask the netfs whether an object on disk is still valid
  651. * @object: The object to ask about
  652. * @data: The auxiliary data for the object
  653. * @datalen: The size of the auxiliary data
  654. *
  655. * This function consults the netfs about the coherency state of an object
  656. */
  657. enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
  658. const void *data, uint16_t datalen)
  659. {
  660. enum fscache_checkaux result;
  661. if (!object->cookie->def->check_aux) {
  662. fscache_stat(&fscache_n_checkaux_none);
  663. return FSCACHE_CHECKAUX_OKAY;
  664. }
  665. result = object->cookie->def->check_aux(object->cookie->netfs_data,
  666. data, datalen);
  667. switch (result) {
  668. /* entry okay as is */
  669. case FSCACHE_CHECKAUX_OKAY:
  670. fscache_stat(&fscache_n_checkaux_okay);
  671. break;
  672. /* entry requires update */
  673. case FSCACHE_CHECKAUX_NEEDS_UPDATE:
  674. fscache_stat(&fscache_n_checkaux_update);
  675. break;
  676. /* entry requires deletion */
  677. case FSCACHE_CHECKAUX_OBSOLETE:
  678. fscache_stat(&fscache_n_checkaux_obsolete);
  679. break;
  680. default:
  681. BUG();
  682. }
  683. return result;
  684. }
  685. EXPORT_SYMBOL(fscache_check_aux);