aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fscache/page.c
diff options
context:
space:
mode:
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);