aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fscache
diff options
context:
space:
mode:
Diffstat (limited to 'fs/fscache')
-rw-r--r--fs/fscache/cookie.c1
-rw-r--r--fs/fscache/internal.h4
-rw-r--r--fs/fscache/page.c52
-rw-r--r--fs/fscache/stats.c10
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;
174extern atomic_t fscache_n_stores_oom; 175extern atomic_t fscache_n_stores_oom;
175extern atomic_t fscache_n_store_ops; 176extern atomic_t fscache_n_store_ops;
176extern atomic_t fscache_n_store_calls; 177extern atomic_t fscache_n_store_calls;
178extern atomic_t fscache_n_store_pages;
179extern atomic_t fscache_n_store_radix_deletes;
180extern atomic_t fscache_n_store_pages_over_limit;
177 181
178extern atomic_t fscache_n_marks; 182extern atomic_t fscache_n_marks;
179extern atomic_t fscache_n_uncaches; 183extern 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 */
48static void fscache_end_page_write(struct fscache_cookie *cookie, struct page *page) 48static 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,
772already_queued: 787already_queued:
773 fscache_stat(&fscache_n_stores_again); 788 fscache_stat(&fscache_n_stores_again);
774already_pending: 789already_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
783submit_failed: 799submit_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;
58atomic_t fscache_n_stores_oom; 58atomic_t fscache_n_stores_oom;
59atomic_t fscache_n_store_ops; 59atomic_t fscache_n_store_ops;
60atomic_t fscache_n_store_calls; 60atomic_t fscache_n_store_calls;
61atomic_t fscache_n_store_pages;
62atomic_t fscache_n_store_radix_deletes;
63atomic_t fscache_n_store_pages_over_limit;
61 64
62atomic_t fscache_n_marks; 65atomic_t fscache_n_marks;
63atomic_t fscache_n_uncaches; 66atomic_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),