object.c 25 KB

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