aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fscache/page.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2009-11-19 13:11:45 -0500
committerDavid Howells <dhowells@redhat.com>2009-11-19 13:11:45 -0500
commit60d543ca724be155c2b6166e36a00c80b21bd810 (patch)
tree90ec6edd77ddb7666dbf7069aa2e001f155cea49 /fs/fscache/page.c
parentd461d26dde901b0523c46b0317e7fccf574a3933 (diff)
FS-Cache: Start processing an object's operations on that object's death
Start processing an object's operations when that object moves into the DYING state as the object cannot be destroyed until all its outstanding operations have completed. Furthermore, make sure that read and allocation operations handle being woken up on a dead object. Such events are recorded in the Allocs.abt and Retrvls.abt statistics as viewable through /proc/fs/fscache/stats. The code for waiting for object activation for the read and allocation operations is also extracted into its own function as it is much the same in all cases, differing only in the stats incremented. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/fscache/page.c')
-rw-r--r--fs/fscache/page.c112
1 files changed, 55 insertions, 57 deletions
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
index fc76798bd968..c598ea4c4e7d 100644
--- a/fs/fscache/page.c
+++ b/fs/fscache/page.c
@@ -314,6 +314,43 @@ static int fscache_wait_for_deferred_lookup(struct fscache_cookie *cookie)
314} 314}
315 315
316/* 316/*
317 * wait for an object to become active (or dead)
318 */
319static int fscache_wait_for_retrieval_activation(struct fscache_object *object,
320 struct fscache_retrieval *op,
321 atomic_t *stat_op_waits,
322 atomic_t *stat_object_dead)
323{
324 int ret;
325
326 if (!test_bit(FSCACHE_OP_WAITING, &op->op.flags))
327 goto check_if_dead;
328
329 _debug(">>> WT");
330 fscache_stat(stat_op_waits);
331 if (wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
332 fscache_wait_bit_interruptible,
333 TASK_INTERRUPTIBLE) < 0) {
334 ret = fscache_cancel_op(&op->op);
335 if (ret == 0)
336 return -ERESTARTSYS;
337
338 /* it's been removed from the pending queue by another party,
339 * so we should get to run shortly */
340 wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
341 fscache_wait_bit, TASK_UNINTERRUPTIBLE);
342 }
343 _debug("<<< GO");
344
345check_if_dead:
346 if (unlikely(fscache_object_is_dead(object))) {
347 fscache_stat(stat_object_dead);
348 return -ENOBUFS;
349 }
350 return 0;
351}
352
353/*
317 * read a page from the cache or allocate a block in which to store it 354 * read a page from the cache or allocate a block in which to store it
318 * - we return: 355 * - we return:
319 * -ENOMEM - out of memory, nothing done 356 * -ENOMEM - out of memory, nothing done
@@ -376,25 +413,12 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
376 413
377 /* we wait for the operation to become active, and then process it 414 /* we wait for the operation to become active, and then process it
378 * *here*, in this thread, and not in the thread pool */ 415 * *here*, in this thread, and not in the thread pool */
379 if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) { 416 ret = fscache_wait_for_retrieval_activation(
380 _debug(">>> WT"); 417 object, op,
381 fscache_stat(&fscache_n_retrieval_op_waits); 418 __fscache_stat(&fscache_n_retrieval_op_waits),
382 if (wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING, 419 __fscache_stat(&fscache_n_retrievals_object_dead));
383 fscache_wait_bit_interruptible, 420 if (ret < 0)
384 TASK_INTERRUPTIBLE) < 0) { 421 goto error;
385 ret = fscache_cancel_op(&op->op);
386 if (ret == 0) {
387 ret = -ERESTARTSYS;
388 goto error;
389 }
390
391 /* it's been removed from the pending queue by another
392 * party, so we should get to run shortly */
393 wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
394 fscache_wait_bit, TASK_UNINTERRUPTIBLE);
395 }
396 _debug("<<< GO");
397 }
398 422
399 /* ask the cache to honour the operation */ 423 /* ask the cache to honour the operation */
400 if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) { 424 if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) {
@@ -506,25 +530,12 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
506 530
507 /* we wait for the operation to become active, and then process it 531 /* we wait for the operation to become active, and then process it
508 * *here*, in this thread, and not in the thread pool */ 532 * *here*, in this thread, and not in the thread pool */
509 if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) { 533 ret = fscache_wait_for_retrieval_activation(
510 _debug(">>> WT"); 534 object, op,
511 fscache_stat(&fscache_n_retrieval_op_waits); 535 __fscache_stat(&fscache_n_retrieval_op_waits),
512 if (wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING, 536 __fscache_stat(&fscache_n_retrievals_object_dead));
513 fscache_wait_bit_interruptible, 537 if (ret < 0)
514 TASK_INTERRUPTIBLE) < 0) { 538 goto error;
515 ret = fscache_cancel_op(&op->op);
516 if (ret == 0) {
517 ret = -ERESTARTSYS;
518 goto error;
519 }
520
521 /* it's been removed from the pending queue by another
522 * party, so we should get to run shortly */
523 wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
524 fscache_wait_bit, TASK_UNINTERRUPTIBLE);
525 }
526 _debug("<<< GO");
527 }
528 539
529 /* ask the cache to honour the operation */ 540 /* ask the cache to honour the operation */
530 if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) { 541 if (test_bit(FSCACHE_COOKIE_NO_DATA_YET, &object->cookie->flags)) {
@@ -612,25 +623,12 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
612 623
613 fscache_stat(&fscache_n_alloc_ops); 624 fscache_stat(&fscache_n_alloc_ops);
614 625
615 if (test_bit(FSCACHE_OP_WAITING, &op->op.flags)) { 626 ret = fscache_wait_for_retrieval_activation(
616 _debug(">>> WT"); 627 object, op,
617 fscache_stat(&fscache_n_alloc_op_waits); 628 __fscache_stat(&fscache_n_alloc_op_waits),
618 if (wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING, 629 __fscache_stat(&fscache_n_allocs_object_dead));
619 fscache_wait_bit_interruptible, 630 if (ret < 0)
620 TASK_INTERRUPTIBLE) < 0) { 631 goto error;
621 ret = fscache_cancel_op(&op->op);
622 if (ret == 0) {
623 ret = -ERESTARTSYS;
624 goto error;
625 }
626
627 /* it's been removed from the pending queue by another
628 * party, so we should get to run shortly */
629 wait_on_bit(&op->op.flags, FSCACHE_OP_WAITING,
630 fscache_wait_bit, TASK_UNINTERRUPTIBLE);
631 }
632 _debug("<<< GO");
633 }
634 632
635 /* ask the cache to honour the operation */ 633 /* ask the cache to honour the operation */
636 fscache_stat(&fscache_n_cop_allocate_page); 634 fscache_stat(&fscache_n_cop_allocate_page);