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.c79
1 files changed, 77 insertions, 2 deletions
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
index 022a5da8e130..fc76798bd968 100644
--- a/fs/fscache/page.c
+++ b/fs/fscache/page.c
@@ -43,6 +43,75 @@ void __fscache_wait_on_page_write(struct fscache_cookie *cookie, struct page *pa
43EXPORT_SYMBOL(__fscache_wait_on_page_write); 43EXPORT_SYMBOL(__fscache_wait_on_page_write);
44 44
45/* 45/*
46 * decide whether a page can be released, possibly by cancelling a store to it
47 * - we're allowed to sleep if __GFP_WAIT is flagged
48 */
49bool __fscache_maybe_release_page(struct fscache_cookie *cookie,
50 struct page *page,
51 gfp_t gfp)
52{
53 struct page *xpage;
54 void *val;
55
56 _enter("%p,%p,%x", cookie, page, gfp);
57
58 rcu_read_lock();
59 val = radix_tree_lookup(&cookie->stores, page->index);
60 if (!val) {
61 rcu_read_unlock();
62 fscache_stat(&fscache_n_store_vmscan_not_storing);
63 __fscache_uncache_page(cookie, page);
64 return true;
65 }
66
67 /* see if the page is actually undergoing storage - if so we can't get
68 * rid of it till the cache has finished with it */
69 if (radix_tree_tag_get(&cookie->stores, page->index,
70 FSCACHE_COOKIE_STORING_TAG)) {
71 rcu_read_unlock();
72 goto page_busy;
73 }
74
75 /* the page is pending storage, so we attempt to cancel the store and
76 * discard the store request so that the page can be reclaimed */
77 spin_lock(&cookie->stores_lock);
78 rcu_read_unlock();
79
80 if (radix_tree_tag_get(&cookie->stores, page->index,
81 FSCACHE_COOKIE_STORING_TAG)) {
82 /* the page started to undergo storage whilst we were looking,
83 * so now we can only wait or return */
84 spin_unlock(&cookie->stores_lock);
85 goto page_busy;
86 }
87
88 xpage = radix_tree_delete(&cookie->stores, page->index);
89 spin_unlock(&cookie->stores_lock);
90
91 if (xpage) {
92 fscache_stat(&fscache_n_store_vmscan_cancelled);
93 fscache_stat(&fscache_n_store_radix_deletes);
94 ASSERTCMP(xpage, ==, page);
95 } else {
96 fscache_stat(&fscache_n_store_vmscan_gone);
97 }
98
99 wake_up_bit(&cookie->flags, 0);
100 if (xpage)
101 page_cache_release(xpage);
102 __fscache_uncache_page(cookie, page);
103 return true;
104
105page_busy:
106 /* we might want to wait here, but that could deadlock the allocator as
107 * the slow-work threads writing to the cache may all end up sleeping
108 * on memory allocation */
109 fscache_stat(&fscache_n_store_vmscan_busy);
110 return false;
111}
112EXPORT_SYMBOL(__fscache_maybe_release_page);
113
114/*
46 * note that a page has finished being written to the cache 115 * note that a page has finished being written to the cache
47 */ 116 */
48static void fscache_end_page_write(struct fscache_object *object, 117static void fscache_end_page_write(struct fscache_object *object,
@@ -57,6 +126,8 @@ static void fscache_end_page_write(struct fscache_object *object,
57 /* delete the page from the tree if it is now no longer 126 /* delete the page from the tree if it is now no longer
58 * pending */ 127 * pending */
59 spin_lock(&cookie->stores_lock); 128 spin_lock(&cookie->stores_lock);
129 radix_tree_tag_clear(&cookie->stores, page->index,
130 FSCACHE_COOKIE_STORING_TAG);
60 if (!radix_tree_tag_get(&cookie->stores, page->index, 131 if (!radix_tree_tag_get(&cookie->stores, page->index,
61 FSCACHE_COOKIE_PENDING_TAG)) { 132 FSCACHE_COOKIE_PENDING_TAG)) {
62 fscache_stat(&fscache_n_store_radix_deletes); 133 fscache_stat(&fscache_n_store_radix_deletes);
@@ -640,8 +711,12 @@ static void fscache_write_op(struct fscache_operation *_op)
640 goto superseded; 711 goto superseded;
641 } 712 }
642 713
643 radix_tree_tag_clear(&cookie->stores, page->index, 714 if (page) {
644 FSCACHE_COOKIE_PENDING_TAG); 715 radix_tree_tag_set(&cookie->stores, page->index,
716 FSCACHE_COOKIE_STORING_TAG);
717 radix_tree_tag_clear(&cookie->stores, page->index,
718 FSCACHE_COOKIE_PENDING_TAG);
719 }
645 720
646 spin_unlock(&cookie->stores_lock); 721 spin_unlock(&cookie->stores_lock);
647 spin_unlock(&object->lock); 722 spin_unlock(&object->lock);