xref: /openbmc/linux/fs/fscache/cookie.c (revision b04b4f78)
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 	object = cache->ops->alloc_object(cache, cookie);
253 	if (IS_ERR(object)) {
254 		fscache_stat(&fscache_n_object_no_alloc);
255 		ret = PTR_ERR(object);
256 		goto error;
257 	}
258 
259 	fscache_stat(&fscache_n_object_alloc);
260 
261 	object->debug_id = atomic_inc_return(&fscache_object_debug_id);
262 
263 	_debug("ALLOC OBJ%x: %s {%lx}",
264 	       object->debug_id, cookie->def->name, object->events);
265 
266 	ret = fscache_alloc_object(cache, cookie->parent);
267 	if (ret < 0)
268 		goto error_put;
269 
270 	/* only attach if we managed to allocate all we needed, otherwise
271 	 * discard the object we just allocated and instead use the one
272 	 * attached to the cookie */
273 	if (fscache_attach_object(cookie, object) < 0)
274 		cache->ops->put_object(object);
275 
276 	_leave(" = 0");
277 	return 0;
278 
279 object_already_extant:
280 	ret = -ENOBUFS;
281 	if (object->state >= FSCACHE_OBJECT_DYING) {
282 		spin_unlock(&cookie->lock);
283 		goto error;
284 	}
285 	spin_unlock(&cookie->lock);
286 	_leave(" = 0 [found]");
287 	return 0;
288 
289 error_put:
290 	cache->ops->put_object(object);
291 error:
292 	_leave(" = %d", ret);
293 	return ret;
294 }
295 
296 /*
297  * attach a cache object to a cookie
298  */
299 static int fscache_attach_object(struct fscache_cookie *cookie,
300 				 struct fscache_object *object)
301 {
302 	struct fscache_object *p;
303 	struct fscache_cache *cache = object->cache;
304 	struct hlist_node *_n;
305 	int ret;
306 
307 	_enter("{%s},{OBJ%x}", cookie->def->name, object->debug_id);
308 
309 	spin_lock(&cookie->lock);
310 
311 	/* there may be multiple initial creations of this object, but we only
312 	 * want one */
313 	ret = -EEXIST;
314 	hlist_for_each_entry(p, _n, &cookie->backing_objects, cookie_link) {
315 		if (p->cache == object->cache) {
316 			if (p->state >= FSCACHE_OBJECT_DYING)
317 				ret = -ENOBUFS;
318 			goto cant_attach_object;
319 		}
320 	}
321 
322 	/* pin the parent object */
323 	spin_lock_nested(&cookie->parent->lock, 1);
324 	hlist_for_each_entry(p, _n, &cookie->parent->backing_objects,
325 			     cookie_link) {
326 		if (p->cache == object->cache) {
327 			if (p->state >= FSCACHE_OBJECT_DYING) {
328 				ret = -ENOBUFS;
329 				spin_unlock(&cookie->parent->lock);
330 				goto cant_attach_object;
331 			}
332 			object->parent = p;
333 			spin_lock(&p->lock);
334 			p->n_children++;
335 			spin_unlock(&p->lock);
336 			break;
337 		}
338 	}
339 	spin_unlock(&cookie->parent->lock);
340 
341 	/* attach to the cache's object list */
342 	if (list_empty(&object->cache_link)) {
343 		spin_lock(&cache->object_list_lock);
344 		list_add(&object->cache_link, &cache->object_list);
345 		spin_unlock(&cache->object_list_lock);
346 	}
347 
348 	/* attach to the cookie */
349 	object->cookie = cookie;
350 	atomic_inc(&cookie->usage);
351 	hlist_add_head(&object->cookie_link, &cookie->backing_objects);
352 	ret = 0;
353 
354 cant_attach_object:
355 	spin_unlock(&cookie->lock);
356 	_leave(" = %d", ret);
357 	return ret;
358 }
359 
360 /*
361  * update the index entries backing a cookie
362  */
363 void __fscache_update_cookie(struct fscache_cookie *cookie)
364 {
365 	struct fscache_object *object;
366 	struct hlist_node *_p;
367 
368 	fscache_stat(&fscache_n_updates);
369 
370 	if (!cookie) {
371 		fscache_stat(&fscache_n_updates_null);
372 		_leave(" [no cookie]");
373 		return;
374 	}
375 
376 	_enter("{%s}", cookie->def->name);
377 
378 	BUG_ON(!cookie->def->get_aux);
379 
380 	spin_lock(&cookie->lock);
381 
382 	/* update the index entry on disk in each cache backing this cookie */
383 	hlist_for_each_entry(object, _p,
384 			     &cookie->backing_objects, cookie_link) {
385 		fscache_raise_event(object, FSCACHE_OBJECT_EV_UPDATE);
386 	}
387 
388 	spin_unlock(&cookie->lock);
389 	_leave("");
390 }
391 EXPORT_SYMBOL(__fscache_update_cookie);
392 
393 /*
394  * release a cookie back to the cache
395  * - the object will be marked as recyclable on disk if retire is true
396  * - all dependents of this cookie must have already been unregistered
397  *   (indices/files/pages)
398  */
399 void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
400 {
401 	struct fscache_cache *cache;
402 	struct fscache_object *object;
403 	unsigned long event;
404 
405 	fscache_stat(&fscache_n_relinquishes);
406 
407 	if (!cookie) {
408 		fscache_stat(&fscache_n_relinquishes_null);
409 		_leave(" [no cookie]");
410 		return;
411 	}
412 
413 	_enter("%p{%s,%p},%d",
414 	       cookie, cookie->def->name, cookie->netfs_data, retire);
415 
416 	if (atomic_read(&cookie->n_children) != 0) {
417 		printk(KERN_ERR "FS-Cache: Cookie '%s' still has children\n",
418 		       cookie->def->name);
419 		BUG();
420 	}
421 
422 	/* wait for the cookie to finish being instantiated (or to fail) */
423 	if (test_bit(FSCACHE_COOKIE_CREATING, &cookie->flags)) {
424 		fscache_stat(&fscache_n_relinquishes_waitcrt);
425 		wait_on_bit(&cookie->flags, FSCACHE_COOKIE_CREATING,
426 			    fscache_wait_bit, TASK_UNINTERRUPTIBLE);
427 	}
428 
429 	event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE;
430 
431 	/* detach pointers back to the netfs */
432 	spin_lock(&cookie->lock);
433 
434 	cookie->netfs_data	= NULL;
435 	cookie->def		= NULL;
436 
437 	/* break links with all the active objects */
438 	while (!hlist_empty(&cookie->backing_objects)) {
439 		object = hlist_entry(cookie->backing_objects.first,
440 				     struct fscache_object,
441 				     cookie_link);
442 
443 		_debug("RELEASE OBJ%x", object->debug_id);
444 
445 		/* detach each cache object from the object cookie */
446 		spin_lock(&object->lock);
447 		hlist_del_init(&object->cookie_link);
448 
449 		cache = object->cache;
450 		object->cookie = NULL;
451 		fscache_raise_event(object, event);
452 		spin_unlock(&object->lock);
453 
454 		if (atomic_dec_and_test(&cookie->usage))
455 			/* the cookie refcount shouldn't be reduced to 0 yet */
456 			BUG();
457 	}
458 
459 	spin_unlock(&cookie->lock);
460 
461 	if (cookie->parent) {
462 		ASSERTCMP(atomic_read(&cookie->parent->usage), >, 0);
463 		ASSERTCMP(atomic_read(&cookie->parent->n_children), >, 0);
464 		atomic_dec(&cookie->parent->n_children);
465 	}
466 
467 	/* finally dispose of the cookie */
468 	ASSERTCMP(atomic_read(&cookie->usage), >, 0);
469 	fscache_cookie_put(cookie);
470 
471 	_leave("");
472 }
473 EXPORT_SYMBOL(__fscache_relinquish_cookie);
474 
475 /*
476  * destroy a cookie
477  */
478 void __fscache_cookie_put(struct fscache_cookie *cookie)
479 {
480 	struct fscache_cookie *parent;
481 
482 	_enter("%p", cookie);
483 
484 	for (;;) {
485 		_debug("FREE COOKIE %p", cookie);
486 		parent = cookie->parent;
487 		BUG_ON(!hlist_empty(&cookie->backing_objects));
488 		kmem_cache_free(fscache_cookie_jar, cookie);
489 
490 		if (!parent)
491 			break;
492 
493 		cookie = parent;
494 		BUG_ON(atomic_read(&cookie->usage) <= 0);
495 		if (!atomic_dec_and_test(&cookie->usage))
496 			break;
497 	}
498 
499 	_leave("");
500 }
501