diff options
Diffstat (limited to 'fs/fscache/cookie.c')
-rw-r--r-- | fs/fscache/cookie.c | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index 0e91a3c9fdb2..318e8433527c 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c | |||
@@ -558,3 +558,74 @@ void __fscache_cookie_put(struct fscache_cookie *cookie) | |||
558 | 558 | ||
559 | _leave(""); | 559 | _leave(""); |
560 | } | 560 | } |
561 | |||
562 | /* | ||
563 | * check the consistency between the netfs inode and the backing cache | ||
564 | * | ||
565 | * NOTE: it only serves no-index type | ||
566 | */ | ||
567 | int __fscache_check_consistency(struct fscache_cookie *cookie) | ||
568 | { | ||
569 | struct fscache_operation *op; | ||
570 | struct fscache_object *object; | ||
571 | int ret; | ||
572 | |||
573 | _enter("%p,", cookie); | ||
574 | |||
575 | ASSERTCMP(cookie->def->type, ==, FSCACHE_COOKIE_TYPE_DATAFILE); | ||
576 | |||
577 | if (fscache_wait_for_deferred_lookup(cookie) < 0) | ||
578 | return -ERESTARTSYS; | ||
579 | |||
580 | if (hlist_empty(&cookie->backing_objects)) | ||
581 | return 0; | ||
582 | |||
583 | op = kzalloc(sizeof(*op), GFP_NOIO | __GFP_NOMEMALLOC | __GFP_NORETRY); | ||
584 | if (!op) | ||
585 | return -ENOMEM; | ||
586 | |||
587 | fscache_operation_init(op, NULL, NULL); | ||
588 | op->flags = FSCACHE_OP_MYTHREAD | | ||
589 | (1 << FSCACHE_OP_WAITING); | ||
590 | |||
591 | spin_lock(&cookie->lock); | ||
592 | |||
593 | if (hlist_empty(&cookie->backing_objects)) | ||
594 | goto inconsistent; | ||
595 | object = hlist_entry(cookie->backing_objects.first, | ||
596 | struct fscache_object, cookie_link); | ||
597 | if (test_bit(FSCACHE_IOERROR, &object->cache->flags)) | ||
598 | goto inconsistent; | ||
599 | |||
600 | op->debug_id = atomic_inc_return(&fscache_op_debug_id); | ||
601 | |||
602 | atomic_inc(&cookie->n_active); | ||
603 | if (fscache_submit_op(object, op) < 0) | ||
604 | goto submit_failed; | ||
605 | |||
606 | /* the work queue now carries its own ref on the object */ | ||
607 | spin_unlock(&cookie->lock); | ||
608 | |||
609 | ret = fscache_wait_for_operation_activation(object, op, | ||
610 | NULL, NULL, NULL); | ||
611 | if (ret == 0) { | ||
612 | /* ask the cache to honour the operation */ | ||
613 | ret = object->cache->ops->check_consistency(op); | ||
614 | fscache_op_complete(op, false); | ||
615 | } else if (ret == -ENOBUFS) { | ||
616 | ret = 0; | ||
617 | } | ||
618 | |||
619 | fscache_put_operation(op); | ||
620 | _leave(" = %d", ret); | ||
621 | return ret; | ||
622 | |||
623 | submit_failed: | ||
624 | atomic_dec(&cookie->n_active); | ||
625 | inconsistent: | ||
626 | spin_unlock(&cookie->lock); | ||
627 | kfree(op); | ||
628 | _leave(" = -ESTALE"); | ||
629 | return -ESTALE; | ||
630 | } | ||
631 | EXPORT_SYMBOL(__fscache_check_consistency); | ||