aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fscache/cookie.c
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fscache/cookie.c')
-rw-r--r--fs/fscache/cookie.c93
1 files changed, 32 insertions, 61 deletions
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
index e2cba1f60c21..0e91a3c9fdb2 100644
--- a/fs/fscache/cookie.c
+++ b/fs/fscache/cookie.c
@@ -95,6 +95,11 @@ struct fscache_cookie *__fscache_acquire_cookie(
95 atomic_set(&cookie->usage, 1); 95 atomic_set(&cookie->usage, 1);
96 atomic_set(&cookie->n_children, 0); 96 atomic_set(&cookie->n_children, 0);
97 97
98 /* We keep the active count elevated until relinquishment to prevent an
99 * attempt to wake up every time the object operations queue quiesces.
100 */
101 atomic_set(&cookie->n_active, 1);
102
98 atomic_inc(&parent->usage); 103 atomic_inc(&parent->usage);
99 atomic_inc(&parent->n_children); 104 atomic_inc(&parent->n_children);
100 105
@@ -177,7 +182,6 @@ static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie)
177 182
178 cookie->flags = 183 cookie->flags =
179 (1 << FSCACHE_COOKIE_LOOKING_UP) | 184 (1 << FSCACHE_COOKIE_LOOKING_UP) |
180 (1 << FSCACHE_COOKIE_CREATING) |
181 (1 << FSCACHE_COOKIE_NO_DATA_YET); 185 (1 << FSCACHE_COOKIE_NO_DATA_YET);
182 186
183 /* ask the cache to allocate objects for this cookie and its parent 187 /* ask the cache to allocate objects for this cookie and its parent
@@ -205,7 +209,7 @@ static int fscache_acquire_non_index_cookie(struct fscache_cookie *cookie)
205 209
206 /* initiate the process of looking up all the objects in the chain 210 /* initiate the process of looking up all the objects in the chain
207 * (done by fscache_initialise_object()) */ 211 * (done by fscache_initialise_object()) */
208 fscache_enqueue_object(object); 212 fscache_raise_event(object, FSCACHE_OBJECT_EV_NEW_CHILD);
209 213
210 spin_unlock(&cookie->lock); 214 spin_unlock(&cookie->lock);
211 215
@@ -285,7 +289,7 @@ static int fscache_alloc_object(struct fscache_cache *cache,
285 289
286object_already_extant: 290object_already_extant:
287 ret = -ENOBUFS; 291 ret = -ENOBUFS;
288 if (object->state >= FSCACHE_OBJECT_DYING) { 292 if (fscache_object_is_dead(object)) {
289 spin_unlock(&cookie->lock); 293 spin_unlock(&cookie->lock);
290 goto error; 294 goto error;
291 } 295 }
@@ -321,7 +325,7 @@ static int fscache_attach_object(struct fscache_cookie *cookie,
321 ret = -EEXIST; 325 ret = -EEXIST;
322 hlist_for_each_entry(p, &cookie->backing_objects, cookie_link) { 326 hlist_for_each_entry(p, &cookie->backing_objects, cookie_link) {
323 if (p->cache == object->cache) { 327 if (p->cache == object->cache) {
324 if (p->state >= FSCACHE_OBJECT_DYING) 328 if (fscache_object_is_dying(p))
325 ret = -ENOBUFS; 329 ret = -ENOBUFS;
326 goto cant_attach_object; 330 goto cant_attach_object;
327 } 331 }
@@ -332,7 +336,7 @@ static int fscache_attach_object(struct fscache_cookie *cookie,
332 hlist_for_each_entry(p, &cookie->parent->backing_objects, 336 hlist_for_each_entry(p, &cookie->parent->backing_objects,
333 cookie_link) { 337 cookie_link) {
334 if (p->cache == object->cache) { 338 if (p->cache == object->cache) {
335 if (p->state >= FSCACHE_OBJECT_DYING) { 339 if (fscache_object_is_dying(p)) {
336 ret = -ENOBUFS; 340 ret = -ENOBUFS;
337 spin_unlock(&cookie->parent->lock); 341 spin_unlock(&cookie->parent->lock);
338 goto cant_attach_object; 342 goto cant_attach_object;
@@ -400,7 +404,7 @@ void __fscache_invalidate(struct fscache_cookie *cookie)
400 object = hlist_entry(cookie->backing_objects.first, 404 object = hlist_entry(cookie->backing_objects.first,
401 struct fscache_object, 405 struct fscache_object,
402 cookie_link); 406 cookie_link);
403 if (object->state < FSCACHE_OBJECT_DYING) 407 if (fscache_object_is_live(object))
404 fscache_raise_event( 408 fscache_raise_event(
405 object, FSCACHE_OBJECT_EV_INVALIDATE); 409 object, FSCACHE_OBJECT_EV_INVALIDATE);
406 } 410 }
@@ -467,9 +471,7 @@ EXPORT_SYMBOL(__fscache_update_cookie);
467 */ 471 */
468void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) 472void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
469{ 473{
470 struct fscache_cache *cache;
471 struct fscache_object *object; 474 struct fscache_object *object;
472 unsigned long event;
473 475
474 fscache_stat(&fscache_n_relinquishes); 476 fscache_stat(&fscache_n_relinquishes);
475 if (retire) 477 if (retire)
@@ -481,8 +483,11 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
481 return; 483 return;
482 } 484 }
483 485
484 _enter("%p{%s,%p},%d", 486 _enter("%p{%s,%p,%d},%d",
485 cookie, cookie->def->name, cookie->netfs_data, retire); 487 cookie, cookie->def->name, cookie->netfs_data,
488 atomic_read(&cookie->n_active), retire);
489
490 ASSERTCMP(atomic_read(&cookie->n_active), >, 0);
486 491
487 if (atomic_read(&cookie->n_children) != 0) { 492 if (atomic_read(&cookie->n_children) != 0) {
488 printk(KERN_ERR "FS-Cache: Cookie '%s' still has children\n", 493 printk(KERN_ERR "FS-Cache: Cookie '%s' still has children\n",
@@ -490,62 +495,28 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
490 BUG(); 495 BUG();
491 } 496 }
492 497
493 /* wait for the cookie to finish being instantiated (or to fail) */ 498 /* No further netfs-accessing operations on this cookie permitted */
494 if (test_bit(FSCACHE_COOKIE_CREATING, &cookie->flags)) { 499 set_bit(FSCACHE_COOKIE_RELINQUISHED, &cookie->flags);
495 fscache_stat(&fscache_n_relinquishes_waitcrt); 500 if (retire)
496 wait_on_bit(&cookie->flags, FSCACHE_COOKIE_CREATING, 501 set_bit(FSCACHE_COOKIE_RETIRED, &cookie->flags);
497 fscache_wait_bit, TASK_UNINTERRUPTIBLE);
498 }
499
500 event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE;
501 502
502try_again:
503 spin_lock(&cookie->lock); 503 spin_lock(&cookie->lock);
504 504 hlist_for_each_entry(object, &cookie->backing_objects, cookie_link) {
505 /* break links with all the active objects */ 505 fscache_raise_event(object, FSCACHE_OBJECT_EV_KILL);
506 while (!hlist_empty(&cookie->backing_objects)) {
507 int n_reads;
508 object = hlist_entry(cookie->backing_objects.first,
509 struct fscache_object,
510 cookie_link);
511
512 _debug("RELEASE OBJ%x", object->debug_id);
513
514 set_bit(FSCACHE_COOKIE_WAITING_ON_READS, &cookie->flags);
515 n_reads = atomic_read(&object->n_reads);
516 if (n_reads) {
517 int n_ops = object->n_ops;
518 int n_in_progress = object->n_in_progress;
519 spin_unlock(&cookie->lock);
520 printk(KERN_ERR "FS-Cache:"
521 " Cookie '%s' still has %d outstanding reads (%d,%d)\n",
522 cookie->def->name,
523 n_reads, n_ops, n_in_progress);
524 wait_on_bit(&cookie->flags, FSCACHE_COOKIE_WAITING_ON_READS,
525 fscache_wait_bit, TASK_UNINTERRUPTIBLE);
526 printk("Wait finished\n");
527 goto try_again;
528 }
529
530 /* detach each cache object from the object cookie */
531 spin_lock(&object->lock);
532 hlist_del_init(&object->cookie_link);
533
534 cache = object->cache;
535 object->cookie = NULL;
536 fscache_raise_event(object, event);
537 spin_unlock(&object->lock);
538
539 if (atomic_dec_and_test(&cookie->usage))
540 /* the cookie refcount shouldn't be reduced to 0 yet */
541 BUG();
542 } 506 }
507 spin_unlock(&cookie->lock);
543 508
544 /* detach pointers back to the netfs */ 509 /* Wait for cessation of activity requiring access to the netfs (when
510 * n_active reaches 0).
511 */
512 if (!atomic_dec_and_test(&cookie->n_active))
513 wait_on_atomic_t(&cookie->n_active, fscache_wait_atomic_t,
514 TASK_UNINTERRUPTIBLE);
515
516 /* Clear pointers back to the netfs */
545 cookie->netfs_data = NULL; 517 cookie->netfs_data = NULL;
546 cookie->def = NULL; 518 cookie->def = NULL;
547 519 BUG_ON(cookie->stores.rnode);
548 spin_unlock(&cookie->lock);
549 520
550 if (cookie->parent) { 521 if (cookie->parent) {
551 ASSERTCMP(atomic_read(&cookie->parent->usage), >, 0); 522 ASSERTCMP(atomic_read(&cookie->parent->usage), >, 0);
@@ -553,7 +524,7 @@ try_again:
553 atomic_dec(&cookie->parent->n_children); 524 atomic_dec(&cookie->parent->n_children);
554 } 525 }
555 526
556 /* finally dispose of the cookie */ 527 /* Dispose of the netfs's link to the cookie */
557 ASSERTCMP(atomic_read(&cookie->usage), >, 0); 528 ASSERTCMP(atomic_read(&cookie->usage), >, 0);
558 fscache_cookie_put(cookie); 529 fscache_cookie_put(cookie);
559 530