FS-Cache: Add counters for entry/exit to/from cache operation functions
[linux-2.6.git] / fs / fscache / cookie.c
1 /* netfs cookie management
2  *
3  * Copyright (C) 2004-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/netfs-api.txt for more information on
12  * the netfs API.
13  */
14
15 #define FSCACHE_DEBUG_LEVEL COOKIE
16 #include <linux/module.h>
17 #include <linux/slab.h>
18 #include "internal.h"
19
20 struct kmem_cache *fscache_cookie_jar;
21
22 static atomic_t fscache_object_debug_id = ATOMIC_INIT(0);
23
24 static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie);
25 static int fscache_alloc_object(struct fscache_cache *cache,
26                                 struct fscache_cookie *cookie);
27 static int fscache_attach_object(struct fscache_cookie *cookie,
28                                  struct fscache_object *object);
29
30 /*
31  * initialise an cookie jar slab element prior to any use
32  */
33 void fscache_cookie_init_once(void *_cookie)
34 {
35         struct fscache_cookie *cookie = _cookie;
36
37         memset(cookie, 0, sizeof(*cookie));
38         spin_lock_init(&cookie->lock);
39         INIT_HLIST_HEAD(&cookie->backing_objects);
40 }
41
42 /*
43  * request a cookie to represent an object (index, datafile, xattr, etc)
44  * - parent specifies the parent object
45  *   - the top level index cookie for each netfs is stored in the fscache_netfs
46  *     struct upon registration
47  * - def points to the definition
48  * - the netfs_data will be passed to the functions pointed to in *def
49  * - all attached caches will be searched to see if they contain this object
50  * - index objects aren't stored on disk until there's a dependent file that
51  *   needs storing
52  * - other objects are stored in a selected cache immediately, and all the
53  *   indices forming the path to it are instantiated if necessary
54  * - we never let on to the netfs about errors
55  *   - we may set a negative cookie pointer, but that's okay
56  */
57 struct fscache_cookie *__fscache_acquire_cookie(
58         struct fscache_cookie *parent,
59         const struct fscache_cookie_def *def,
60         void *netfs_data)
61 {
62         struct fscache_cookie *cookie;
63
64         BUG_ON(!def);
65
66         _enter("{%s},{%s},%p",
67                parent ? (char *) parent->def->name : "<no-parent>",
68                def->name, netfs_data);
69
70         fscache_stat(&fscache_n_acquires);
71
72         /* if there's no parent cookie, then we don't create one here either */
73         if (!parent) {
74                 fscache_stat(&fscache_n_acquires_null);
75                 _leave(" [no parent]");
76                 return NULL;
77         }
78
79         /* validate the definition */
80         BUG_ON(!def->get_key);
81         BUG_ON(!def->name[0]);
82
83         BUG_ON(def->type == FSCACHE_COOKIE_TYPE_INDEX &&
84                parent->def->type != FSCACHE_COOKIE_TYPE_INDEX);
85
86         /* allocate and initialise a cookie */
87         cookie = kmem_cache_alloc(fscache_cookie_jar, GFP_KERNEL);
88         if (!cookie) {
89                 fscache_stat(&fscache_n_acquires_oom);
90                 _leave(" [ENOMEM]");
91                 return NULL;
92         }
93
94         atomic_set(&cookie->usage, 1);
95         atomic_set(&cookie->n_children, 0);
96
97         atomic_inc(&parent->usage);
98         atomic_inc(&parent->n_children);
99
100         cookie->def             = def;
101         cookie->parent          = parent;
102         cookie->netfs_data      = netfs_data;
103         cookie->flags           = 0;
104
105         INIT_RADIX_TREE(&cookie->stores, GFP_NOFS);
106
107         switch (cookie->def->type) {
108         case FSCACHE_COOKIE_TYPE_INDEX:
109                 fscache_stat(&fscache_n_cookie_index);
110                 break;
111         case FSCACHE_COOKIE_TYPE_DATAFILE:
112                 fscache_stat(&fscache_n_cookie_data);
113                 break;
114         default:
115                 fscache_stat(&fscache_n_cookie_special);
116                 break;
117         }
118
119         /* if the object is an index then we need do nothing more here - we
120          * create indices on disk when we need them as an index may exist in
121          * multiple caches */
122         if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) {
123                 if (fscache_acquire_non_index_cookie(cookie) < 0) {
124                         atomic_dec(&parent->n_children);
125                         __fscache_cookie_put(cookie);
126                         fscache_stat(&fscache_n_acquires_nobufs);
127                         _leave(" = NULL");
128                         return NULL;
129                 }
130         }
131
132         fscache_stat(&fscache_n_acquires_ok);
133         _leave(" = %p", cookie);
134         return cookie;
135 }
136 EXPORT_SYMBOL(__fscache_acquire_cookie);
137
138 /*
139  * acquire a non-index cookie
140  * - this must make sure the index chain is instantiated and instantiate the
141  *   object representation too
142  */
143 static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie)
144 {
145         struct fscache_object *object;
146         struct fscache_cache *cache;
147         uint64_t i_size;
148         int ret;
149
150         _enter("");
151
152         cookie->flags = 1 << FSCACHE_COOKIE_UNAVAILABLE;
153
154         /* now we need to see whether the backing objects for this cookie yet
155          * exist, if not there'll be nothing to search */
156         down_read(&fscache_addremove_sem);
157
158         if (list_empty(&fscache_cache_list)) {
159                 up_read(&fscache_addremove_sem);
160                 _leave(" = 0 [no caches]");
161                 return 0;
162         }
163
164         /* select a cache in which to store the object */
165         cache = fscache_select_cache_for_object(cookie->parent);
166         if (!cache) {
167                 up_read(&fscache_addremove_sem);
168                 fscache_stat(&fscache_n_acquires_no_cache);
169                 _leave(" = -ENOMEDIUM [no cache]");
170                 return -ENOMEDIUM;
171         }
172
173         _debug("cache %s", cache->tag->name);
174
175         cookie->flags =
176                 (1 << FSCACHE_COOKIE_LOOKING_UP) |
177                 (1 << FSCACHE_COOKIE_CREATING) |
178                 (1 << FSCACHE_COOKIE_NO_DATA_YET);
179
180         /* ask the cache to allocate objects for this cookie and its parent
181          * chain */
182         ret = fscache_alloc_object(cache, cookie);
183         if (ret < 0) {
184                 up_read(&fscache_addremove_sem);
185                 _leave(" = %d", ret);
186                 return ret;
187         }
188
189         /* pass on how big the object we're caching is supposed to be */
190         cookie->def->get_attr(cookie->netfs_data, &i_size);
191
192         spin_lock(&cookie->lock);
193         if (hlist_empty(&cookie->backing_objects)) {
194                 spin_unlock(&cookie->lock);
195                 goto unavailable;
196         }
197
198         object = hlist_entry(cookie->backing_objects.first,
199                              struct fscache_object, cookie_link);
200
201         fscache_set_store_limit(object, i_size);
202
203         /* initiate the process of looking up all the objects in the chain
204          * (done by fscache_initialise_object()) */
205         fscache_enqueue_object(object);
206
207         spin_unlock(&cookie->lock);
208
209         /* we may be required to wait for lookup to complete at this point */
210         if (!fscache_defer_lookup) {
211                 _debug("non-deferred lookup %p", &cookie->flags);
212                 wait_on_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP,
213                             fscache_wait_bit, TASK_UNINTERRUPTIBLE);
214                 _debug("complete");
215                 if (test_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags))
216                         goto unavailable;
217         }
218
219         up_read(&fscache_addremove_sem);
220         _leave(" = 0 [deferred]");
221         return 0;
222
223 unavailable:
224         up_read(&fscache_addremove_sem);
225         _leave(" = -ENOBUFS");
226         return -ENOBUFS;
227 }
228
229 /*
230  * recursively allocate cache object records for a cookie/cache combination
231  * - caller must be holding the addremove sem
232  */
233 static int fscache_alloc_object(struct fscache_cache *cache,
234                                 struct fscache_cookie *cookie)
235 {
236         struct fscache_object *object;
237         struct hlist_node *_n;
238         int ret;
239
240         _enter("%p,%p{%s}", cache, cookie, cookie->def->name);
241
242         spin_lock(&cookie->lock);
243         hlist_for_each_entry(object, _n, &cookie->backing_objects,
244                              cookie_link) {
245                 if (object->cache == cache)
246                         goto object_already_extant;
247         }
248         spin_unlock(&cookie->lock);
249
250         /* ask the cache to allocate an object (we may end up with duplicate
251          * objects at this stage, but we sort that out later) */
252         fscache_stat(&fscache_n_cop_alloc_object);
253         object = cache->ops->alloc_object(cache, cookie);
254         fscache_stat_d(&fscache_n_cop_alloc_object);
255         if (IS_ERR(object)) {
256                 fscache_stat(&fscache_n_object_no_alloc);
257                 ret = PTR_ERR(object);
258                 goto error;
259         }
260
261         fscache_stat(&fscache_n_object_alloc);
262
263         object->debug_id = atomic_inc_return(&fscache_object_debug_id);
264
265         _debug("ALLOC OBJ%x: %s {%lx}",
266                object->debug_id, cookie->def->name, object->events);
267
268         ret = fscache_alloc_object(cache, cookie->parent);
269         if (ret < 0)
270                 goto error_put;
271
272         /* only attach if we managed to allocate all we needed, otherwise
273          * discard the object we just allocated and instead use the one
274          * attached to the cookie */
275         if (fscache_attach_object(cookie, object) < 0) {
276                 fscache_stat(&fscache_n_cop_put_object);
277                 cache->ops->put_object(object);
278                 fscache_stat_d(&fscache_n_cop_put_object);
279         }
280
281         _leave(" = 0");
282         return 0;
283
284 object_already_extant:
285         ret = -ENOBUFS;
286         if (object->state >= FSCACHE_OBJECT_DYING) {
287                 spin_unlock(&cookie->lock);
288                 goto error;
289         }
290         spin_unlock(&cookie->lock);
291         _leave(" = 0 [found]");
292         return 0;
293
294 error_put:
295         fscache_stat(&fscache_n_cop_put_object);
296         cache->ops->put_object(object);
297         fscache_stat_d(&fscache_n_cop_put_object);
298 error:
299         _leave(" = %d", ret);
300         return ret;
301 }
302
303 /*
304  * attach a cache object to a cookie
305  */
306 static int fscache_attach_object(struct fscache_cookie *cookie,
307                                  struct fscache_object *object)
308 {
309         struct fscache_object *p;
310         struct fscache_cache *cache = object->cache;
311         struct hlist_node *_n;
312         int ret;
313
314         _enter("{%s},{OBJ%x}", cookie->def->name, object->debug_id);
315
316         spin_lock(&cookie->lock);
317
318         /* there may be multiple initial creations of this object, but we only
319          * want one */
320         ret = -EEXIST;
321         hlist_for_each_entry(p, _n, &cookie->backing_objects, cookie_link) {
322                 if (p->cache == object->cache) {
323                         if (p->state >= FSCACHE_OBJECT_DYING)
324                                 ret = -ENOBUFS;
325                         goto cant_attach_object;
326                 }
327         }
328
329         /* pin the parent object */
330         spin_lock_nested(&cookie->parent->lock, 1);
331         hlist_for_each_entry(p, _n, &cookie->parent->backing_objects,
332                              cookie_link) {
333                 if (p->cache == object->cache) {
334                         if (p->state >= FSCACHE_OBJECT_DYING) {
335                                 ret = -ENOBUFS;
336                                 spin_unlock(&cookie->parent->lock);
337                                 goto cant_attach_object;
338                         }
339                         object->parent = p;
340                         spin_lock(&p->lock);
341                         p->n_children++;
342                         spin_unlock(&p->lock);
343                         break;
344                 }
345         }
346         spin_unlock(&cookie->parent->lock);
347
348         /* attach to the cache's object list */
349         if (list_empty(&object->cache_link)) {
350                 spin_lock(&cache->object_list_lock);
351                 list_add(&object->cache_link, &cache->object_list);
352                 spin_unlock(&cache->object_list_lock);
353         }
354
355         /* attach to the cookie */
356         object->cookie = cookie;
357         atomic_inc(&cookie->usage);
358         hlist_add_head(&object->cookie_link, &cookie->backing_objects);
359
360         fscache_objlist_add(object);
361         ret = 0;
362
363 cant_attach_object:
364         spin_unlock(&cookie->lock);
365         _leave(" = %d", ret);
366         return ret;
367 }
368
369 /*
370  * update the index entries backing a cookie
371  */
372 void __fscache_update_cookie(struct fscache_cookie *cookie)
373 {
374         struct fscache_object *object;
375         struct hlist_node *_p;
376
377         fscache_stat(&fscache_n_updates);
378
379         if (!cookie) {
380                 fscache_stat(&fscache_n_updates_null);
381                 _leave(" [no cookie]");
382                 return;
383         }
384
385         _enter("{%s}", cookie->def->name);
386
387         BUG_ON(!cookie->def->get_aux);
388
389         spin_lock(&cookie->lock);
390
391         /* update the index entry on disk in each cache backing this cookie */
392         hlist_for_each_entry(object, _p,
393                              &cookie->backing_objects, cookie_link) {
394                 fscache_raise_event(object, FSCACHE_OBJECT_EV_UPDATE);
395         }
396
397         spin_unlock(&cookie->lock);
398         _leave("");
399 }
400 EXPORT_SYMBOL(__fscache_update_cookie);
401
402 /*
403  * release a cookie back to the cache
404  * - the object will be marked as recyclable on disk if retire is true
405  * - all dependents of this cookie must have already been unregistered
406  *   (indices/files/pages)
407  */
408 void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
409 {
410         struct fscache_cache *cache;
411         struct fscache_object *object;
412         unsigned long event;
413
414         fscache_stat(&fscache_n_relinquishes);
415
416         if (!cookie) {
417                 fscache_stat(&fscache_n_relinquishes_null);
418                 _leave(" [no cookie]");
419                 return;
420         }
421
422         _enter("%p{%s,%p},%d",
423                cookie, cookie->def->name, cookie->netfs_data, retire);
424
425         if (atomic_read(&cookie->n_children) != 0) {
426                 printk(KERN_ERR "FS-Cache: Cookie '%s' still has children\n",
427                        cookie->def->name);
428                 BUG();
429         }
430
431         /* wait for the cookie to finish being instantiated (or to fail) */
432         if (test_bit(FSCACHE_COOKIE_CREATING, &cookie->flags)) {
433                 fscache_stat(&fscache_n_relinquishes_waitcrt);
434                 wait_on_bit(&cookie->flags, FSCACHE_COOKIE_CREATING,
435                             fscache_wait_bit, TASK_UNINTERRUPTIBLE);
436         }
437
438         event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE;
439
440         /* detach pointers back to the netfs */
441         spin_lock(&cookie->lock);
442
443         cookie->netfs_data      = NULL;
444         cookie->def             = NULL;
445
446         /* break links with all the active objects */
447         while (!hlist_empty(&cookie->backing_objects)) {
448                 object = hlist_entry(cookie->backing_objects.first,
449                                      struct fscache_object,
450                                      cookie_link);
451
452                 _debug("RELEASE OBJ%x", object->debug_id);
453
454                 /* detach each cache object from the object cookie */
455                 spin_lock(&object->lock);
456                 hlist_del_init(&object->cookie_link);
457
458                 cache = object->cache;
459                 object->cookie = NULL;
460                 fscache_raise_event(object, event);
461                 spin_unlock(&object->lock);
462
463                 if (atomic_dec_and_test(&cookie->usage))
464                         /* the cookie refcount shouldn't be reduced to 0 yet */
465                         BUG();
466         }
467
468         spin_unlock(&cookie->lock);
469
470         if (cookie->parent) {
471                 ASSERTCMP(atomic_read(&cookie->parent->usage), >, 0);
472                 ASSERTCMP(atomic_read(&cookie->parent->n_children), >, 0);
473                 atomic_dec(&cookie->parent->n_children);
474         }
475
476         /* finally dispose of the cookie */
477         ASSERTCMP(atomic_read(&cookie->usage), >, 0);
478         fscache_cookie_put(cookie);
479
480         _leave("");
481 }
482 EXPORT_SYMBOL(__fscache_relinquish_cookie);
483
484 /*
485  * destroy a cookie
486  */
487 void __fscache_cookie_put(struct fscache_cookie *cookie)
488 {
489         struct fscache_cookie *parent;
490
491         _enter("%p", cookie);
492
493         for (;;) {
494                 _debug("FREE COOKIE %p", cookie);
495                 parent = cookie->parent;
496                 BUG_ON(!hlist_empty(&cookie->backing_objects));
497                 kmem_cache_free(fscache_cookie_jar, cookie);
498
499                 if (!parent)
500                         break;
501
502                 cookie = parent;
503                 BUG_ON(atomic_read(&cookie->usage) <= 0);
504                 if (!atomic_dec_and_test(&cookie->usage))
505                         break;
506         }
507
508         _leave("");
509 }