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