object.c 25 KB

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