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