string: factorize skip_spaces and export it to be generally available
[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         start = jiffies;
357         fscache_object_state_machine(object);
358         fscache_hist(fscache_objs_histogram, start);
359         if (object->events & object->event_mask)
360                 fscache_enqueue_object(object);
361         clear_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
362 }
363
364 /*
365  * describe an object for slow-work debugging
366  */
367 #ifdef CONFIG_SLOW_WORK_PROC
368 static void fscache_object_slow_work_desc(struct slow_work *work,
369                                           struct seq_file *m)
370 {
371         struct fscache_object *object =
372                 container_of(work, struct fscache_object, work);
373
374         seq_printf(m, "FSC: OBJ%x: %s",
375                    object->debug_id,
376                    fscache_object_states_short[object->state]);
377 }
378 #endif
379
380 /*
381  * initialise an object
382  * - check the specified object's parent to see if we can make use of it
383  *   immediately to do a creation
384  * - we may need to start the process of creating a parent and we need to wait
385  *   for the parent's lookup and creation to complete if it's not there yet
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_initialise_object(struct fscache_object *object)
390 {
391         struct fscache_object *parent;
392
393         _enter("");
394         ASSERT(object->cookie != NULL);
395         ASSERT(object->cookie->parent != NULL);
396         ASSERT(list_empty(&object->work.link));
397
398         if (object->events & ((1 << FSCACHE_OBJECT_EV_ERROR) |
399                               (1 << FSCACHE_OBJECT_EV_RELEASE) |
400                               (1 << FSCACHE_OBJECT_EV_RETIRE) |
401                               (1 << FSCACHE_OBJECT_EV_WITHDRAW))) {
402                 _debug("abort init %lx", object->events);
403                 spin_lock(&object->lock);
404                 object->state = FSCACHE_OBJECT_ABORT_INIT;
405                 spin_unlock(&object->lock);
406                 return;
407         }
408
409         spin_lock(&object->cookie->lock);
410         spin_lock_nested(&object->cookie->parent->lock, 1);
411
412         parent = object->parent;
413         if (!parent) {
414                 _debug("no parent");
415                 set_bit(FSCACHE_OBJECT_EV_WITHDRAW, &object->events);
416         } else {
417                 spin_lock(&object->lock);
418                 spin_lock_nested(&parent->lock, 1);
419                 _debug("parent %s", fscache_object_states[parent->state]);
420
421                 if (parent->state >= FSCACHE_OBJECT_DYING) {
422                         _debug("bad parent");
423                         set_bit(FSCACHE_OBJECT_EV_WITHDRAW, &object->events);
424                 } else if (parent->state < FSCACHE_OBJECT_AVAILABLE) {
425                         _debug("wait");
426
427                         /* we may get woken up in this state by child objects
428                          * binding on to us, so we need to make sure we don't
429                          * add ourself to the list multiple times */
430                         if (list_empty(&object->dep_link)) {
431                                 fscache_stat(&fscache_n_cop_grab_object);
432                                 object->cache->ops->grab_object(object);
433                                 fscache_stat_d(&fscache_n_cop_grab_object);
434                                 list_add(&object->dep_link,
435                                          &parent->dependents);
436
437                                 /* fscache_acquire_non_index_cookie() uses this
438                                  * to wake the chain up */
439                                 if (parent->state == FSCACHE_OBJECT_INIT)
440                                         fscache_enqueue_object(parent);
441                         }
442                 } else {
443                         _debug("go");
444                         parent->n_ops++;
445                         parent->n_obj_ops++;
446                         object->lookup_jif = jiffies;
447                         object->state = FSCACHE_OBJECT_LOOKING_UP;
448                         set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
449                 }
450
451                 spin_unlock(&parent->lock);
452                 spin_unlock(&object->lock);
453         }
454
455         spin_unlock(&object->cookie->parent->lock);
456         spin_unlock(&object->cookie->lock);
457         _leave("");
458 }
459
460 /*
461  * look an object up in the cache from which it was allocated
462  * - we hold an "access lock" on the parent object, so the parent object cannot
463  *   be withdrawn by either party till we've finished
464  * - an object's cookie is pinned until we clear FSCACHE_COOKIE_CREATING on the
465  *   leaf-most cookies of the object and all its children
466  */
467 static void fscache_lookup_object(struct fscache_object *object)
468 {
469         struct fscache_cookie *cookie = object->cookie;
470         struct fscache_object *parent;
471         int ret;
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         ret = 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         if (ret == -ETIMEDOUT) {
504                 /* probably stuck behind another object, so move this one to
505                  * the back of the queue */
506                 fscache_stat(&fscache_n_object_lookups_timed_out);
507                 set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
508         }
509
510         _leave("");
511 }
512
513 /**
514  * fscache_object_lookup_negative - Note negative cookie lookup
515  * @object: Object pointing to cookie to mark
516  *
517  * Note negative lookup, permitting those waiting to read data from an already
518  * existing backing object to continue as there's no data for them to read.
519  */
520 void fscache_object_lookup_negative(struct fscache_object *object)
521 {
522         struct fscache_cookie *cookie = object->cookie;
523
524         _enter("{OBJ%x,%s}",
525                object->debug_id, fscache_object_states[object->state]);
526
527         spin_lock(&object->lock);
528         if (object->state == FSCACHE_OBJECT_LOOKING_UP) {
529                 fscache_stat(&fscache_n_object_lookups_negative);
530
531                 /* transit here to allow write requests to begin stacking up
532                  * and read requests to begin returning ENODATA */
533                 object->state = FSCACHE_OBJECT_CREATING;
534                 spin_unlock(&object->lock);
535
536                 set_bit(FSCACHE_COOKIE_PENDING_FILL, &cookie->flags);
537                 set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
538
539                 _debug("wake up lookup %p", &cookie->flags);
540                 smp_mb__before_clear_bit();
541                 clear_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags);
542                 smp_mb__after_clear_bit();
543                 wake_up_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP);
544                 set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
545         } else {
546                 ASSERTCMP(object->state, ==, FSCACHE_OBJECT_CREATING);
547                 spin_unlock(&object->lock);
548         }
549
550         _leave("");
551 }
552 EXPORT_SYMBOL(fscache_object_lookup_negative);
553
554 /**
555  * fscache_obtained_object - Note successful object lookup or creation
556  * @object: Object pointing to cookie to mark
557  *
558  * Note successful lookup and/or creation, permitting those waiting to write
559  * data to a backing object to continue.
560  *
561  * Note that after calling this, an object's cookie may be relinquished by the
562  * netfs, and so must be accessed with object lock held.
563  */
564 void fscache_obtained_object(struct fscache_object *object)
565 {
566         struct fscache_cookie *cookie = object->cookie;
567
568         _enter("{OBJ%x,%s}",
569                object->debug_id, fscache_object_states[object->state]);
570
571         /* if we were still looking up, then we must have a positive lookup
572          * result, in which case there may be data available */
573         spin_lock(&object->lock);
574         if (object->state == FSCACHE_OBJECT_LOOKING_UP) {
575                 fscache_stat(&fscache_n_object_lookups_positive);
576
577                 clear_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
578
579                 object->state = FSCACHE_OBJECT_AVAILABLE;
580                 spin_unlock(&object->lock);
581
582                 smp_mb__before_clear_bit();
583                 clear_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags);
584                 smp_mb__after_clear_bit();
585                 wake_up_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP);
586                 set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
587         } else {
588                 ASSERTCMP(object->state, ==, FSCACHE_OBJECT_CREATING);
589                 fscache_stat(&fscache_n_object_created);
590
591                 object->state = FSCACHE_OBJECT_AVAILABLE;
592                 spin_unlock(&object->lock);
593                 set_bit(FSCACHE_OBJECT_EV_REQUEUE, &object->events);
594                 smp_wmb();
595         }
596
597         if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, &cookie->flags))
598                 wake_up_bit(&cookie->flags, FSCACHE_COOKIE_CREATING);
599
600         _leave("");
601 }
602 EXPORT_SYMBOL(fscache_obtained_object);
603
604 /*
605  * handle an object that has just become available
606  */
607 static void fscache_object_available(struct fscache_object *object)
608 {
609         _enter("{OBJ%x}", object->debug_id);
610
611         spin_lock(&object->lock);
612
613         if (object->cookie &&
614             test_and_clear_bit(FSCACHE_COOKIE_CREATING, &object->cookie->flags))
615                 wake_up_bit(&object->cookie->flags, FSCACHE_COOKIE_CREATING);
616
617         fscache_done_parent_op(object);
618         if (object->n_in_progress == 0) {
619                 if (object->n_ops > 0) {
620                         ASSERTCMP(object->n_ops, >=, object->n_obj_ops);
621                         ASSERTIF(object->n_ops > object->n_obj_ops,
622                                  !list_empty(&object->pending_ops));
623                         fscache_start_operations(object);
624                 } else {
625                         ASSERT(list_empty(&object->pending_ops));
626                 }
627         }
628         spin_unlock(&object->lock);
629
630         fscache_stat(&fscache_n_cop_lookup_complete);
631         object->cache->ops->lookup_complete(object);
632         fscache_stat_d(&fscache_n_cop_lookup_complete);
633         fscache_enqueue_dependents(object);
634
635         fscache_hist(fscache_obj_instantiate_histogram, object->lookup_jif);
636         fscache_stat(&fscache_n_object_avail);
637
638         _leave("");
639 }
640
641 /*
642  * drop an object's attachments
643  */
644 static void fscache_drop_object(struct fscache_object *object)
645 {
646         struct fscache_object *parent = object->parent;
647         struct fscache_cache *cache = object->cache;
648
649         _enter("{OBJ%x,%d}", object->debug_id, object->n_children);
650
651         ASSERTCMP(object->cookie, ==, NULL);
652         ASSERT(hlist_unhashed(&object->cookie_link));
653
654         spin_lock(&cache->object_list_lock);
655         list_del_init(&object->cache_link);
656         spin_unlock(&cache->object_list_lock);
657
658         fscache_stat(&fscache_n_cop_drop_object);
659         cache->ops->drop_object(object);
660         fscache_stat_d(&fscache_n_cop_drop_object);
661
662         if (parent) {
663                 _debug("release parent OBJ%x {%d}",
664                        parent->debug_id, parent->n_children);
665
666                 spin_lock(&parent->lock);
667                 parent->n_children--;
668                 if (parent->n_children == 0)
669                         fscache_raise_event(parent, FSCACHE_OBJECT_EV_CLEARED);
670                 spin_unlock(&parent->lock);
671                 object->parent = NULL;
672         }
673
674         /* this just shifts the object release to the slow work processor */
675         fscache_stat(&fscache_n_cop_put_object);
676         object->cache->ops->put_object(object);
677         fscache_stat_d(&fscache_n_cop_put_object);
678
679         _leave("");
680 }
681
682 /*
683  * release or recycle an object that the netfs has discarded
684  */
685 static void fscache_release_object(struct fscache_object *object)
686 {
687         _enter("");
688
689         fscache_drop_object(object);
690 }
691
692 /*
693  * withdraw an object from active service
694  */
695 static void fscache_withdraw_object(struct fscache_object *object)
696 {
697         struct fscache_cookie *cookie;
698         bool detached;
699
700         _enter("");
701
702         spin_lock(&object->lock);
703         cookie = object->cookie;
704         if (cookie) {
705                 /* need to get the cookie lock before the object lock, starting
706                  * from the object pointer */
707                 atomic_inc(&cookie->usage);
708                 spin_unlock(&object->lock);
709
710                 detached = false;
711                 spin_lock(&cookie->lock);
712                 spin_lock(&object->lock);
713
714                 if (object->cookie == cookie) {
715                         hlist_del_init(&object->cookie_link);
716                         object->cookie = NULL;
717                         detached = true;
718                 }
719                 spin_unlock(&cookie->lock);
720                 fscache_cookie_put(cookie);
721                 if (detached)
722                         fscache_cookie_put(cookie);
723         }
724
725         spin_unlock(&object->lock);
726
727         fscache_drop_object(object);
728 }
729
730 /*
731  * withdraw an object from active service at the behest of the cache
732  * - need break the links to a cached object cookie
733  * - called under two situations:
734  *   (1) recycler decides to reclaim an in-use object
735  *   (2) a cache is unmounted
736  * - have to take care as the cookie can be being relinquished by the netfs
737  *   simultaneously
738  * - the object is pinned by the caller holding a refcount on it
739  */
740 void fscache_withdrawing_object(struct fscache_cache *cache,
741                                 struct fscache_object *object)
742 {
743         bool enqueue = false;
744
745         _enter(",OBJ%x", object->debug_id);
746
747         spin_lock(&object->lock);
748         if (object->state < FSCACHE_OBJECT_WITHDRAWING) {
749                 object->state = FSCACHE_OBJECT_WITHDRAWING;
750                 enqueue = true;
751         }
752         spin_unlock(&object->lock);
753
754         if (enqueue)
755                 fscache_enqueue_object(object);
756
757         _leave("");
758 }
759
760 /*
761  * allow the slow work item processor to get a ref on an object
762  */
763 static int fscache_object_slow_work_get_ref(struct slow_work *work)
764 {
765         struct fscache_object *object =
766                 container_of(work, struct fscache_object, work);
767         int ret;
768
769         fscache_stat(&fscache_n_cop_grab_object);
770         ret = object->cache->ops->grab_object(object) ? 0 : -EAGAIN;
771         fscache_stat_d(&fscache_n_cop_grab_object);
772         return ret;
773 }
774
775 /*
776  * allow the slow work item processor to discard a ref on a work item
777  */
778 static void fscache_object_slow_work_put_ref(struct slow_work *work)
779 {
780         struct fscache_object *object =
781                 container_of(work, struct fscache_object, work);
782
783         fscache_stat(&fscache_n_cop_put_object);
784         object->cache->ops->put_object(object);
785         fscache_stat_d(&fscache_n_cop_put_object);
786 }
787
788 /*
789  * enqueue an object for metadata-type processing
790  */
791 void fscache_enqueue_object(struct fscache_object *object)
792 {
793         _enter("{OBJ%x}", object->debug_id);
794
795         slow_work_enqueue(&object->work);
796 }
797
798 /*
799  * enqueue the dependents of an object for metadata-type processing
800  * - the caller must hold the object's lock
801  * - this may cause an already locked object to wind up being processed again
802  */
803 static void fscache_enqueue_dependents(struct fscache_object *object)
804 {
805         struct fscache_object *dep;
806
807         _enter("{OBJ%x}", object->debug_id);
808
809         if (list_empty(&object->dependents))
810                 return;
811
812         spin_lock(&object->lock);
813
814         while (!list_empty(&object->dependents)) {
815                 dep = list_entry(object->dependents.next,
816                                  struct fscache_object, dep_link);
817                 list_del_init(&dep->dep_link);
818
819
820                 /* sort onto appropriate lists */
821                 fscache_enqueue_object(dep);
822                 fscache_stat(&fscache_n_cop_put_object);
823                 dep->cache->ops->put_object(dep);
824                 fscache_stat_d(&fscache_n_cop_put_object);
825
826                 if (!list_empty(&object->dependents))
827                         cond_resched_lock(&object->lock);
828         }
829
830         spin_unlock(&object->lock);
831 }
832
833 /*
834  * remove an object from whatever queue it's waiting on
835  * - the caller must hold object->lock
836  */
837 void fscache_dequeue_object(struct fscache_object *object)
838 {
839         _enter("{OBJ%x}", object->debug_id);
840
841         if (!list_empty(&object->dep_link)) {
842                 spin_lock(&object->parent->lock);
843                 list_del_init(&object->dep_link);
844                 spin_unlock(&object->parent->lock);
845         }
846
847         _leave("");
848 }
849
850 /**
851  * fscache_check_aux - Ask the netfs whether an object on disk is still valid
852  * @object: The object to ask about
853  * @data: The auxiliary data for the object
854  * @datalen: The size of the auxiliary data
855  *
856  * This function consults the netfs about the coherency state of an object
857  */
858 enum fscache_checkaux fscache_check_aux(struct fscache_object *object,
859                                         const void *data, uint16_t datalen)
860 {
861         enum fscache_checkaux result;
862
863         if (!object->cookie->def->check_aux) {
864                 fscache_stat(&fscache_n_checkaux_none);
865                 return FSCACHE_CHECKAUX_OKAY;
866         }
867
868         result = object->cookie->def->check_aux(object->cookie->netfs_data,
869                                                 data, datalen);
870         switch (result) {
871                 /* entry okay as is */
872         case FSCACHE_CHECKAUX_OKAY:
873                 fscache_stat(&fscache_n_checkaux_okay);
874                 break;
875
876                 /* entry requires update */
877         case FSCACHE_CHECKAUX_NEEDS_UPDATE:
878                 fscache_stat(&fscache_n_checkaux_update);
879                 break;
880
881                 /* entry requires deletion */
882         case FSCACHE_CHECKAUX_OBSOLETE:
883                 fscache_stat(&fscache_n_checkaux_obsolete);
884                 break;
885
886         default:
887                 BUG();
888         }
889
890         return result;
891 }
892 EXPORT_SYMBOL(fscache_check_aux);