1
2
3
4
5
6
7
8
9
10
11
12
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
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
30
31
32
33struct fscache_cookie *fscache_alloc_cookie(
34 struct fscache_cookie *parent,
35 const struct fscache_cookie_def *def,
36 void *netfs_data)
37{
38 struct fscache_cookie *cookie;
39
40
41 cookie = kmem_cache_zalloc(fscache_cookie_jar, GFP_KERNEL);
42 if (!cookie)
43 return NULL;
44
45 atomic_set(&cookie->usage, 1);
46 atomic_set(&cookie->n_children, 0);
47
48
49
50
51 atomic_set(&cookie->n_active, 1);
52
53 cookie->def = def;
54 cookie->parent = parent;
55 cookie->netfs_data = netfs_data;
56 cookie->flags = (1 << FSCACHE_COOKIE_NO_DATA_YET);
57 spin_lock_init(&cookie->lock);
58 spin_lock_init(&cookie->stores_lock);
59 INIT_HLIST_HEAD(&cookie->backing_objects);
60
61
62
63 INIT_RADIX_TREE(&cookie->stores, GFP_NOFS & ~__GFP_WAIT);
64 return cookie;
65}
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82struct fscache_cookie *__fscache_acquire_cookie(
83 struct fscache_cookie *parent,
84 const struct fscache_cookie_def *def,
85 void *netfs_data,
86 bool enable)
87{
88 struct fscache_cookie *cookie;
89
90 BUG_ON(!def);
91
92 _enter("{%s},{%s},%p,%u",
93 parent ? (char *) parent->def->name : "<no-parent>",
94 def->name, netfs_data, enable);
95
96 fscache_stat(&fscache_n_acquires);
97
98
99 if (!parent) {
100 fscache_stat(&fscache_n_acquires_null);
101 _leave(" [no parent]");
102 return NULL;
103 }
104
105
106 BUG_ON(!def->get_key);
107 BUG_ON(!def->name[0]);
108
109 BUG_ON(def->type == FSCACHE_COOKIE_TYPE_INDEX &&
110 parent->def->type != FSCACHE_COOKIE_TYPE_INDEX);
111
112
113 cookie = fscache_alloc_cookie(parent, def, netfs_data);
114 if (!cookie) {
115 fscache_stat(&fscache_n_acquires_oom);
116 _leave(" [ENOMEM]");
117 return NULL;
118 }
119
120 atomic_inc(&parent->usage);
121 atomic_inc(&parent->n_children);
122
123 switch (cookie->def->type) {
124 case FSCACHE_COOKIE_TYPE_INDEX:
125 fscache_stat(&fscache_n_cookie_index);
126 break;
127 case FSCACHE_COOKIE_TYPE_DATAFILE:
128 fscache_stat(&fscache_n_cookie_data);
129 break;
130 default:
131 fscache_stat(&fscache_n_cookie_special);
132 break;
133 }
134
135 if (enable) {
136
137
138
139 if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) {
140 if (fscache_acquire_non_index_cookie(cookie) == 0) {
141 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
142 } else {
143 atomic_dec(&parent->n_children);
144 __fscache_cookie_put(cookie);
145 fscache_stat(&fscache_n_acquires_nobufs);
146 _leave(" = NULL");
147 return NULL;
148 }
149 } else {
150 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
151 }
152 }
153
154 fscache_stat(&fscache_n_acquires_ok);
155 _leave(" = %p", cookie);
156 return cookie;
157}
158EXPORT_SYMBOL(__fscache_acquire_cookie);
159
160
161
162
163void __fscache_enable_cookie(struct fscache_cookie *cookie,
164 bool (*can_enable)(void *data),
165 void *data)
166{
167 _enter("%p", cookie);
168
169 wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK,
170 TASK_UNINTERRUPTIBLE);
171
172 if (test_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags))
173 goto out_unlock;
174
175 if (can_enable && !can_enable(data)) {
176
177 } else if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX) {
178
179 __fscache_wait_on_invalidate(cookie);
180
181 if (fscache_acquire_non_index_cookie(cookie) == 0)
182 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
183 } else {
184 set_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags);
185 }
186
187out_unlock:
188 clear_bit_unlock(FSCACHE_COOKIE_ENABLEMENT_LOCK, &cookie->flags);
189 wake_up_bit(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK);
190}
191EXPORT_SYMBOL(__fscache_enable_cookie);
192
193
194
195
196
197
198static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie)
199{
200 struct fscache_object *object;
201 struct fscache_cache *cache;
202 uint64_t i_size;
203 int ret;
204
205 _enter("");
206
207 set_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags);
208
209
210
211 down_read(&fscache_addremove_sem);
212
213 if (list_empty(&fscache_cache_list)) {
214 up_read(&fscache_addremove_sem);
215 _leave(" = 0 [no caches]");
216 return 0;
217 }
218
219
220 cache = fscache_select_cache_for_object(cookie->parent);
221 if (!cache) {
222 up_read(&fscache_addremove_sem);
223 fscache_stat(&fscache_n_acquires_no_cache);
224 _leave(" = -ENOMEDIUM [no cache]");
225 return -ENOMEDIUM;
226 }
227
228 _debug("cache %s", cache->tag->name);
229
230 set_bit(FSCACHE_COOKIE_LOOKING_UP, &cookie->flags);
231
232
233
234 ret = fscache_alloc_object(cache, cookie);
235 if (ret < 0) {
236 up_read(&fscache_addremove_sem);
237 _leave(" = %d", ret);
238 return ret;
239 }
240
241
242 cookie->def->get_attr(cookie->netfs_data, &i_size);
243
244 spin_lock(&cookie->lock);
245 if (hlist_empty(&cookie->backing_objects)) {
246 spin_unlock(&cookie->lock);
247 goto unavailable;
248 }
249
250 object = hlist_entry(cookie->backing_objects.first,
251 struct fscache_object, cookie_link);
252
253 fscache_set_store_limit(object, i_size);
254
255
256
257 fscache_raise_event(object, FSCACHE_OBJECT_EV_NEW_CHILD);
258
259 spin_unlock(&cookie->lock);
260
261
262 if (!fscache_defer_lookup) {
263 _debug("non-deferred lookup %p", &cookie->flags);
264 wait_on_bit(&cookie->flags, FSCACHE_COOKIE_LOOKING_UP,
265 TASK_UNINTERRUPTIBLE);
266 _debug("complete");
267 if (test_bit(FSCACHE_COOKIE_UNAVAILABLE, &cookie->flags))
268 goto unavailable;
269 }
270
271 up_read(&fscache_addremove_sem);
272 _leave(" = 0 [deferred]");
273 return 0;
274
275unavailable:
276 up_read(&fscache_addremove_sem);
277 _leave(" = -ENOBUFS");
278 return -ENOBUFS;
279}
280
281
282
283
284
285static int fscache_alloc_object(struct fscache_cache *cache,
286 struct fscache_cookie *cookie)
287{
288 struct fscache_object *object;
289 int ret;
290
291 _enter("%p,%p{%s}", cache, cookie, cookie->def->name);
292
293 spin_lock(&cookie->lock);
294 hlist_for_each_entry(object, &cookie->backing_objects,
295 cookie_link) {
296 if (object->cache == cache)
297 goto object_already_extant;
298 }
299 spin_unlock(&cookie->lock);
300
301
302
303 fscache_stat(&fscache_n_cop_alloc_object);
304 object = cache->ops->alloc_object(cache, cookie);
305 fscache_stat_d(&fscache_n_cop_alloc_object);
306 if (IS_ERR(object)) {
307 fscache_stat(&fscache_n_object_no_alloc);
308 ret = PTR_ERR(object);
309 goto error;
310 }
311
312 ASSERTCMP(object->cookie, ==, cookie);
313 fscache_stat(&fscache_n_object_alloc);
314
315 object->debug_id = atomic_inc_return(&fscache_object_debug_id);
316
317 _debug("ALLOC OBJ%x: %s {%lx}",
318 object->debug_id, cookie->def->name, object->events);
319
320 ret = fscache_alloc_object(cache, cookie->parent);
321 if (ret < 0)
322 goto error_put;
323
324
325
326
327 if (fscache_attach_object(cookie, object) < 0) {
328 fscache_stat(&fscache_n_cop_put_object);
329 cache->ops->put_object(object);
330 fscache_stat_d(&fscache_n_cop_put_object);
331 }
332
333 _leave(" = 0");
334 return 0;
335
336object_already_extant:
337 ret = -ENOBUFS;
338 if (fscache_object_is_dying(object) ||
339 fscache_cache_is_broken(object)) {
340 spin_unlock(&cookie->lock);
341 goto error;
342 }
343 spin_unlock(&cookie->lock);
344 _leave(" = 0 [found]");
345 return 0;
346
347error_put:
348 fscache_stat(&fscache_n_cop_put_object);
349 cache->ops->put_object(object);
350 fscache_stat_d(&fscache_n_cop_put_object);
351error:
352 _leave(" = %d", ret);
353 return ret;
354}
355
356
357
358
359static int fscache_attach_object(struct fscache_cookie *cookie,
360 struct fscache_object *object)
361{
362 struct fscache_object *p;
363 struct fscache_cache *cache = object->cache;
364 int ret;
365
366 _enter("{%s},{OBJ%x}", cookie->def->name, object->debug_id);
367
368 ASSERTCMP(object->cookie, ==, cookie);
369
370 spin_lock(&cookie->lock);
371
372
373
374 ret = -EEXIST;
375 hlist_for_each_entry(p, &cookie->backing_objects, cookie_link) {
376 if (p->cache == object->cache) {
377 if (fscache_object_is_dying(p))
378 ret = -ENOBUFS;
379 goto cant_attach_object;
380 }
381 }
382
383
384 spin_lock_nested(&cookie->parent->lock, 1);
385 hlist_for_each_entry(p, &cookie->parent->backing_objects,
386 cookie_link) {
387 if (p->cache == object->cache) {
388 if (fscache_object_is_dying(p)) {
389 ret = -ENOBUFS;
390 spin_unlock(&cookie->parent->lock);
391 goto cant_attach_object;
392 }
393 object->parent = p;
394 spin_lock(&p->lock);
395 p->n_children++;
396 spin_unlock(&p->lock);
397 break;
398 }
399 }
400 spin_unlock(&cookie->parent->lock);
401
402
403 if (list_empty(&object->cache_link)) {
404 spin_lock(&cache->object_list_lock);
405 list_add(&object->cache_link, &cache->object_list);
406 spin_unlock(&cache->object_list_lock);
407 }
408
409
410 hlist_add_head(&object->cookie_link, &cookie->backing_objects);
411
412 fscache_objlist_add(object);
413 ret = 0;
414
415cant_attach_object:
416 spin_unlock(&cookie->lock);
417 _leave(" = %d", ret);
418 return ret;
419}
420
421
422
423
424void __fscache_invalidate(struct fscache_cookie *cookie)
425{
426 struct fscache_object *object;
427
428 _enter("{%s}", cookie->def->name);
429
430 fscache_stat(&fscache_n_invalidates);
431
432
433
434
435
436
437 ASSERTCMP(cookie->def->type, ==, FSCACHE_COOKIE_TYPE_DATAFILE);
438
439
440 BUG_ON(!cookie->def->get_aux);
441
442
443
444
445 if (!hlist_empty(&cookie->backing_objects)) {
446 spin_lock(&cookie->lock);
447
448 if (fscache_cookie_enabled(cookie) &&
449 !hlist_empty(&cookie->backing_objects) &&
450 !test_and_set_bit(FSCACHE_COOKIE_INVALIDATING,
451 &cookie->flags)) {
452 object = hlist_entry(cookie->backing_objects.first,
453 struct fscache_object,
454 cookie_link);
455 if (fscache_object_is_live(object))
456 fscache_raise_event(
457 object, FSCACHE_OBJECT_EV_INVALIDATE);
458 }
459
460 spin_unlock(&cookie->lock);
461 }
462
463 _leave("");
464}
465EXPORT_SYMBOL(__fscache_invalidate);
466
467
468
469
470void __fscache_wait_on_invalidate(struct fscache_cookie *cookie)
471{
472 _enter("%p", cookie);
473
474 wait_on_bit(&cookie->flags, FSCACHE_COOKIE_INVALIDATING,
475 TASK_UNINTERRUPTIBLE);
476
477 _leave("");
478}
479EXPORT_SYMBOL(__fscache_wait_on_invalidate);
480
481
482
483
484void __fscache_update_cookie(struct fscache_cookie *cookie)
485{
486 struct fscache_object *object;
487
488 fscache_stat(&fscache_n_updates);
489
490 if (!cookie) {
491 fscache_stat(&fscache_n_updates_null);
492 _leave(" [no cookie]");
493 return;
494 }
495
496 _enter("{%s}", cookie->def->name);
497
498 BUG_ON(!cookie->def->get_aux);
499
500 spin_lock(&cookie->lock);
501
502 if (fscache_cookie_enabled(cookie)) {
503
504
505
506 hlist_for_each_entry(object,
507 &cookie->backing_objects, cookie_link) {
508 fscache_raise_event(object, FSCACHE_OBJECT_EV_UPDATE);
509 }
510 }
511
512 spin_unlock(&cookie->lock);
513 _leave("");
514}
515EXPORT_SYMBOL(__fscache_update_cookie);
516
517
518
519
520void __fscache_disable_cookie(struct fscache_cookie *cookie, bool invalidate)
521{
522 struct fscache_object *object;
523 bool awaken = false;
524
525 _enter("%p,%u", cookie, invalidate);
526
527 ASSERTCMP(atomic_read(&cookie->n_active), >, 0);
528
529 if (atomic_read(&cookie->n_children) != 0) {
530 pr_err("Cookie '%s' still has children\n",
531 cookie->def->name);
532 BUG();
533 }
534
535 wait_on_bit_lock(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK,
536 TASK_UNINTERRUPTIBLE);
537 if (!test_and_clear_bit(FSCACHE_COOKIE_ENABLED, &cookie->flags))
538 goto out_unlock_enable;
539
540
541
542
543 __fscache_wait_on_invalidate(cookie);
544
545
546 set_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags);
547
548 spin_lock(&cookie->lock);
549 if (!hlist_empty(&cookie->backing_objects)) {
550 hlist_for_each_entry(object, &cookie->backing_objects, cookie_link) {
551 if (invalidate)
552 set_bit(FSCACHE_OBJECT_RETIRED, &object->flags);
553 clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags);
554 fscache_raise_event(object, FSCACHE_OBJECT_EV_KILL);
555 }
556 } else {
557 if (test_and_clear_bit(FSCACHE_COOKIE_INVALIDATING, &cookie->flags))
558 awaken = true;
559 }
560 spin_unlock(&cookie->lock);
561 if (awaken)
562 wake_up_bit(&cookie->flags, FSCACHE_COOKIE_INVALIDATING);
563
564
565
566
567
568 if (!atomic_dec_and_test(&cookie->n_active))
569 wait_on_atomic_t(&cookie->n_active, fscache_wait_atomic_t,
570 TASK_UNINTERRUPTIBLE);
571
572
573 if (cookie->def->type != FSCACHE_COOKIE_TYPE_INDEX)
574 fscache_invalidate_writes(cookie);
575
576
577 if (!test_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags)) {
578 atomic_inc(&cookie->n_active);
579 set_bit(FSCACHE_COOKIE_NO_DATA_YET, &cookie->flags);
580 }
581
582out_unlock_enable:
583 clear_bit_unlock(FSCACHE_COOKIE_ENABLEMENT_LOCK, &cookie->flags);
584 wake_up_bit(&cookie->flags, FSCACHE_COOKIE_ENABLEMENT_LOCK);
585 _leave("");
586}
587EXPORT_SYMBOL(__fscache_disable_cookie);
588
589
590
591
592
593
594
595void __fscache_relinquish_cookie(struct fscache_cookie *cookie, bool retire)
596{
597 fscache_stat(&fscache_n_relinquishes);
598 if (retire)
599 fscache_stat(&fscache_n_relinquishes_retire);
600
601 if (!cookie) {
602 fscache_stat(&fscache_n_relinquishes_null);
603 _leave(" [no cookie]");
604 return;
605 }
606
607 _enter("%p{%s,%p,%d},%d",
608 cookie, cookie->def->name, cookie->netfs_data,
609 atomic_read(&cookie->n_active), retire);
610
611
612 set_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags);
613
614 __fscache_disable_cookie(cookie, retire);
615
616
617 cookie->netfs_data = NULL;
618 cookie->def = NULL;
619 BUG_ON(cookie->stores.rnode);
620
621 if (cookie->parent) {
622 ASSERTCMP(atomic_read(&cookie->parent->usage), >, 0);
623 ASSERTCMP(atomic_read(&cookie->parent->n_children), >, 0);
624 atomic_dec(&cookie->parent->n_children);
625 }
626
627
628 ASSERTCMP(atomic_read(&cookie->usage), >, 0);
629 fscache_cookie_put(cookie);
630
631 _leave("");
632}
633EXPORT_SYMBOL(__fscache_relinquish_cookie);
634
635
636
637
638void __fscache_cookie_put(struct fscache_cookie *cookie)
639{
640 struct fscache_cookie *parent;
641
642 _enter("%p", cookie);
643
644 for (;;) {
645 _debug("FREE COOKIE %p", cookie);
646 parent = cookie->parent;
647 BUG_ON(!hlist_empty(&cookie->backing_objects));
648 kmem_cache_free(fscache_cookie_jar, cookie);
649
650 if (!parent)
651 break;
652
653 cookie = parent;
654 BUG_ON(atomic_read(&cookie->usage) <= 0);
655 if (!atomic_dec_and_test(&cookie->usage))
656 break;
657 }
658
659 _leave("");
660}
661
662
663
664
665
666
667int __fscache_check_consistency(struct fscache_cookie *cookie)
668{
669 struct fscache_operation *op;
670 struct fscache_object *object;
671 bool wake_cookie = false;
672 int ret;
673
674 _enter("%p,", cookie);
675
676 ASSERTCMP(cookie->def->type, ==, FSCACHE_COOKIE_TYPE_DATAFILE);
677
678 if (fscache_wait_for_deferred_lookup(cookie) < 0)
679 return -ERESTARTSYS;
680
681 if (hlist_empty(&cookie->backing_objects))
682 return 0;
683
684 op = kzalloc(sizeof(*op), GFP_NOIO | __GFP_NOMEMALLOC | __GFP_NORETRY);
685 if (!op)
686 return -ENOMEM;
687
688 fscache_operation_init(op, NULL, NULL, NULL);
689 op->flags = FSCACHE_OP_MYTHREAD |
690 (1 << FSCACHE_OP_WAITING) |
691 (1 << FSCACHE_OP_UNUSE_COOKIE);
692
693 spin_lock(&cookie->lock);
694
695 if (!fscache_cookie_enabled(cookie) ||
696 hlist_empty(&cookie->backing_objects))
697 goto inconsistent;
698 object = hlist_entry(cookie->backing_objects.first,
699 struct fscache_object, cookie_link);
700 if (test_bit(FSCACHE_IOERROR, &object->cache->flags))
701 goto inconsistent;
702
703 op->debug_id = atomic_inc_return(&fscache_op_debug_id);
704
705 __fscache_use_cookie(cookie);
706 if (fscache_submit_op(object, op) < 0)
707 goto submit_failed;
708
709
710 spin_unlock(&cookie->lock);
711
712 ret = fscache_wait_for_operation_activation(object, op, NULL, NULL);
713 if (ret == 0) {
714
715 ret = object->cache->ops->check_consistency(op);
716 fscache_op_complete(op, false);
717 } else if (ret == -ENOBUFS) {
718 ret = 0;
719 }
720
721 fscache_put_operation(op);
722 _leave(" = %d", ret);
723 return ret;
724
725submit_failed:
726 wake_cookie = __fscache_unuse_cookie(cookie);
727inconsistent:
728 spin_unlock(&cookie->lock);
729 if (wake_cookie)
730 __fscache_wake_unused_cookie(cookie);
731 kfree(op);
732 _leave(" = -ESTALE");
733 return -ESTALE;
734}
735EXPORT_SYMBOL(__fscache_check_consistency);
736