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.c71
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 */
567int __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
623submit_failed:
624 atomic_dec(&cookie->n_active);
625inconsistent:
626 spin_unlock(&cookie->lock);
627 kfree(op);
628 _leave(" = -ESTALE");
629 return -ESTALE;
630}
631EXPORT_SYMBOL(__fscache_check_consistency);