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