diff options
Diffstat (limited to 'fs/fscache')
-rw-r--r-- | fs/fscache/cookie.c | 1 | ||||
-rw-r--r-- | fs/fscache/internal.h | 4 | ||||
-rw-r--r-- | fs/fscache/page.c | 52 | ||||
-rw-r--r-- | fs/fscache/stats.c | 10 |
4 files changed, 48 insertions, 19 deletions
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c index e6854f5222f5..f979659c1b3f 100644 --- a/fs/fscache/cookie.c +++ b/fs/fscache/cookie.c | |||
@@ -36,6 +36,7 @@ void fscache_cookie_init_once(void *_cookie) | |||
36 | 36 | ||
37 | memset(cookie, 0, sizeof(*cookie)); | 37 | memset(cookie, 0, sizeof(*cookie)); |
38 | spin_lock_init(&cookie->lock); | 38 | spin_lock_init(&cookie->lock); |
39 | spin_lock_init(&cookie->stores_lock); | ||
39 | INIT_HLIST_HEAD(&cookie->backing_objects); | 40 | INIT_HLIST_HEAD(&cookie->backing_objects); |
40 | } | 41 | } |
41 | 42 | ||
diff --git a/fs/fscache/internal.h b/fs/fscache/internal.h index 50324ad2b194..ba1853fa1ff9 100644 --- a/fs/fscache/internal.h +++ b/fs/fscache/internal.h | |||
@@ -17,6 +17,7 @@ | |||
17 | * - cache->object_list_lock | 17 | * - cache->object_list_lock |
18 | * - object->lock | 18 | * - object->lock |
19 | * - object->parent->lock | 19 | * - object->parent->lock |
20 | * - cookie->stores_lock | ||
20 | * - fscache_thread_lock | 21 | * - fscache_thread_lock |
21 | * | 22 | * |
22 | */ | 23 | */ |
@@ -174,6 +175,9 @@ extern atomic_t fscache_n_stores_nobufs; | |||
174 | extern atomic_t fscache_n_stores_oom; | 175 | extern atomic_t fscache_n_stores_oom; |
175 | extern atomic_t fscache_n_store_ops; | 176 | extern atomic_t fscache_n_store_ops; |
176 | extern atomic_t fscache_n_store_calls; | 177 | extern atomic_t fscache_n_store_calls; |
178 | extern atomic_t fscache_n_store_pages; | ||
179 | extern atomic_t fscache_n_store_radix_deletes; | ||
180 | extern atomic_t fscache_n_store_pages_over_limit; | ||
177 | 181 | ||
178 | extern atomic_t fscache_n_marks; | 182 | extern atomic_t fscache_n_marks; |
179 | extern atomic_t fscache_n_uncaches; | 183 | extern atomic_t fscache_n_uncaches; |
diff --git a/fs/fscache/page.c b/fs/fscache/page.c index e6f2e61133a1..3ea8897bc217 100644 --- a/fs/fscache/page.c +++ b/fs/fscache/page.c | |||
@@ -45,16 +45,26 @@ EXPORT_SYMBOL(__fscache_wait_on_page_write); | |||
45 | /* | 45 | /* |
46 | * note that a page has finished being written to the cache | 46 | * note that a page has finished being written to the cache |
47 | */ | 47 | */ |
48 | static void fscache_end_page_write(struct fscache_cookie *cookie, struct page *page) | 48 | static void fscache_end_page_write(struct fscache_object *object, |
49 | struct page *page) | ||
49 | { | 50 | { |
50 | struct page *xpage; | 51 | struct fscache_cookie *cookie; |
52 | struct page *xpage = NULL; | ||
51 | 53 | ||
52 | spin_lock(&cookie->lock); | 54 | spin_lock(&object->lock); |
53 | xpage = radix_tree_delete(&cookie->stores, page->index); | 55 | cookie = object->cookie; |
54 | spin_unlock(&cookie->lock); | 56 | if (cookie) { |
55 | ASSERT(xpage != NULL); | 57 | /* delete the page from the tree if it is now no longer |
56 | 58 | * pending */ | |
57 | wake_up_bit(&cookie->flags, 0); | 59 | spin_lock(&cookie->stores_lock); |
60 | fscache_stat(&fscache_n_store_radix_deletes); | ||
61 | xpage = radix_tree_delete(&cookie->stores, page->index); | ||
62 | spin_unlock(&cookie->stores_lock); | ||
63 | wake_up_bit(&cookie->flags, 0); | ||
64 | } | ||
65 | spin_unlock(&object->lock); | ||
66 | if (xpage) | ||
67 | page_cache_release(xpage); | ||
58 | } | 68 | } |
59 | 69 | ||
60 | /* | 70 | /* |
@@ -591,7 +601,7 @@ static void fscache_write_op(struct fscache_operation *_op) | |||
591 | struct fscache_storage *op = | 601 | struct fscache_storage *op = |
592 | container_of(_op, struct fscache_storage, op); | 602 | container_of(_op, struct fscache_storage, op); |
593 | struct fscache_object *object = op->op.object; | 603 | struct fscache_object *object = op->op.object; |
594 | struct fscache_cookie *cookie = object->cookie; | 604 | struct fscache_cookie *cookie; |
595 | struct page *page; | 605 | struct page *page; |
596 | unsigned n; | 606 | unsigned n; |
597 | void *results[1]; | 607 | void *results[1]; |
@@ -601,16 +611,17 @@ static void fscache_write_op(struct fscache_operation *_op) | |||
601 | 611 | ||
602 | fscache_set_op_state(&op->op, "GetPage"); | 612 | fscache_set_op_state(&op->op, "GetPage"); |
603 | 613 | ||
604 | spin_lock(&cookie->lock); | ||
605 | spin_lock(&object->lock); | 614 | spin_lock(&object->lock); |
615 | cookie = object->cookie; | ||
606 | 616 | ||
607 | if (!fscache_object_is_active(object)) { | 617 | if (!fscache_object_is_active(object) || !cookie) { |
608 | spin_unlock(&object->lock); | 618 | spin_unlock(&object->lock); |
609 | spin_unlock(&cookie->lock); | ||
610 | _leave(""); | 619 | _leave(""); |
611 | return; | 620 | return; |
612 | } | 621 | } |
613 | 622 | ||
623 | spin_lock(&cookie->stores_lock); | ||
624 | |||
614 | fscache_stat(&fscache_n_store_calls); | 625 | fscache_stat(&fscache_n_store_calls); |
615 | 626 | ||
616 | /* find a page to store */ | 627 | /* find a page to store */ |
@@ -621,23 +632,25 @@ static void fscache_write_op(struct fscache_operation *_op) | |||
621 | goto superseded; | 632 | goto superseded; |
622 | page = results[0]; | 633 | page = results[0]; |
623 | _debug("gang %d [%lx]", n, page->index); | 634 | _debug("gang %d [%lx]", n, page->index); |
624 | if (page->index > op->store_limit) | 635 | if (page->index > op->store_limit) { |
636 | fscache_stat(&fscache_n_store_pages_over_limit); | ||
625 | goto superseded; | 637 | goto superseded; |
638 | } | ||
626 | 639 | ||
627 | radix_tree_tag_clear(&cookie->stores, page->index, | 640 | radix_tree_tag_clear(&cookie->stores, page->index, |
628 | FSCACHE_COOKIE_PENDING_TAG); | 641 | FSCACHE_COOKIE_PENDING_TAG); |
629 | 642 | ||
643 | spin_unlock(&cookie->stores_lock); | ||
630 | spin_unlock(&object->lock); | 644 | spin_unlock(&object->lock); |
631 | spin_unlock(&cookie->lock); | ||
632 | 645 | ||
633 | if (page) { | 646 | if (page) { |
634 | fscache_set_op_state(&op->op, "Store"); | 647 | fscache_set_op_state(&op->op, "Store"); |
648 | fscache_stat(&fscache_n_store_pages); | ||
635 | fscache_stat(&fscache_n_cop_write_page); | 649 | fscache_stat(&fscache_n_cop_write_page); |
636 | ret = object->cache->ops->write_page(op, page); | 650 | ret = object->cache->ops->write_page(op, page); |
637 | fscache_stat_d(&fscache_n_cop_write_page); | 651 | fscache_stat_d(&fscache_n_cop_write_page); |
638 | fscache_set_op_state(&op->op, "EndWrite"); | 652 | fscache_set_op_state(&op->op, "EndWrite"); |
639 | fscache_end_page_write(cookie, page); | 653 | fscache_end_page_write(object, page); |
640 | page_cache_release(page); | ||
641 | if (ret < 0) { | 654 | if (ret < 0) { |
642 | fscache_set_op_state(&op->op, "Abort"); | 655 | fscache_set_op_state(&op->op, "Abort"); |
643 | fscache_abort_object(object); | 656 | fscache_abort_object(object); |
@@ -653,9 +666,9 @@ superseded: | |||
653 | /* this writer is going away and there aren't any more things to | 666 | /* this writer is going away and there aren't any more things to |
654 | * write */ | 667 | * write */ |
655 | _debug("cease"); | 668 | _debug("cease"); |
669 | spin_unlock(&cookie->stores_lock); | ||
656 | clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags); | 670 | clear_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags); |
657 | spin_unlock(&object->lock); | 671 | spin_unlock(&object->lock); |
658 | spin_unlock(&cookie->lock); | ||
659 | _leave(""); | 672 | _leave(""); |
660 | } | 673 | } |
661 | 674 | ||
@@ -731,6 +744,7 @@ int __fscache_write_page(struct fscache_cookie *cookie, | |||
731 | /* add the page to the pending-storage radix tree on the backing | 744 | /* add the page to the pending-storage radix tree on the backing |
732 | * object */ | 745 | * object */ |
733 | spin_lock(&object->lock); | 746 | spin_lock(&object->lock); |
747 | spin_lock(&cookie->stores_lock); | ||
734 | 748 | ||
735 | _debug("store limit %llx", (unsigned long long) object->store_limit); | 749 | _debug("store limit %llx", (unsigned long long) object->store_limit); |
736 | 750 | ||
@@ -751,6 +765,7 @@ int __fscache_write_page(struct fscache_cookie *cookie, | |||
751 | if (test_and_set_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags)) | 765 | if (test_and_set_bit(FSCACHE_OBJECT_PENDING_WRITE, &object->flags)) |
752 | goto already_pending; | 766 | goto already_pending; |
753 | 767 | ||
768 | spin_unlock(&cookie->stores_lock); | ||
754 | spin_unlock(&object->lock); | 769 | spin_unlock(&object->lock); |
755 | 770 | ||
756 | op->op.debug_id = atomic_inc_return(&fscache_op_debug_id); | 771 | op->op.debug_id = atomic_inc_return(&fscache_op_debug_id); |
@@ -772,6 +787,7 @@ int __fscache_write_page(struct fscache_cookie *cookie, | |||
772 | already_queued: | 787 | already_queued: |
773 | fscache_stat(&fscache_n_stores_again); | 788 | fscache_stat(&fscache_n_stores_again); |
774 | already_pending: | 789 | already_pending: |
790 | spin_unlock(&cookie->stores_lock); | ||
775 | spin_unlock(&object->lock); | 791 | spin_unlock(&object->lock); |
776 | spin_unlock(&cookie->lock); | 792 | spin_unlock(&cookie->lock); |
777 | radix_tree_preload_end(); | 793 | radix_tree_preload_end(); |
@@ -781,7 +797,9 @@ already_pending: | |||
781 | return 0; | 797 | return 0; |
782 | 798 | ||
783 | submit_failed: | 799 | submit_failed: |
800 | spin_lock(&cookie->stores_lock); | ||
784 | radix_tree_delete(&cookie->stores, page->index); | 801 | radix_tree_delete(&cookie->stores, page->index); |
802 | spin_unlock(&cookie->stores_lock); | ||
785 | page_cache_release(page); | 803 | page_cache_release(page); |
786 | ret = -ENOBUFS; | 804 | ret = -ENOBUFS; |
787 | goto nobufs; | 805 | goto nobufs; |
diff --git a/fs/fscache/stats.c b/fs/fscache/stats.c index 4c07439d1307..1d53ea68409e 100644 --- a/fs/fscache/stats.c +++ b/fs/fscache/stats.c | |||
@@ -58,6 +58,9 @@ atomic_t fscache_n_stores_nobufs; | |||
58 | atomic_t fscache_n_stores_oom; | 58 | atomic_t fscache_n_stores_oom; |
59 | atomic_t fscache_n_store_ops; | 59 | atomic_t fscache_n_store_ops; |
60 | atomic_t fscache_n_store_calls; | 60 | atomic_t fscache_n_store_calls; |
61 | atomic_t fscache_n_store_pages; | ||
62 | atomic_t fscache_n_store_radix_deletes; | ||
63 | atomic_t fscache_n_store_pages_over_limit; | ||
61 | 64 | ||
62 | atomic_t fscache_n_marks; | 65 | atomic_t fscache_n_marks; |
63 | atomic_t fscache_n_uncaches; | 66 | atomic_t fscache_n_uncaches; |
@@ -200,9 +203,12 @@ static int fscache_stats_show(struct seq_file *m, void *v) | |||
200 | atomic_read(&fscache_n_stores_again), | 203 | atomic_read(&fscache_n_stores_again), |
201 | atomic_read(&fscache_n_stores_nobufs), | 204 | atomic_read(&fscache_n_stores_nobufs), |
202 | atomic_read(&fscache_n_stores_oom)); | 205 | atomic_read(&fscache_n_stores_oom)); |
203 | seq_printf(m, "Stores : ops=%u run=%u\n", | 206 | seq_printf(m, "Stores : ops=%u run=%u pgs=%u rxd=%u olm=%u\n", |
204 | atomic_read(&fscache_n_store_ops), | 207 | atomic_read(&fscache_n_store_ops), |
205 | atomic_read(&fscache_n_store_calls)); | 208 | atomic_read(&fscache_n_store_calls), |
209 | atomic_read(&fscache_n_store_pages), | ||
210 | atomic_read(&fscache_n_store_radix_deletes), | ||
211 | atomic_read(&fscache_n_store_pages_over_limit)); | ||
206 | 212 | ||
207 | seq_printf(m, "Ops : pend=%u run=%u enq=%u can=%u\n", | 213 | seq_printf(m, "Ops : pend=%u run=%u enq=%u can=%u\n", |
208 | atomic_read(&fscache_n_op_pend), | 214 | atomic_read(&fscache_n_op_pend), |