aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fscache
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2013-09-20 19:09:31 -0400
committerDavid Howells <dhowells@redhat.com>2013-09-27 13:40:25 -0400
commit8fb883f3e30065529e4f35d4b4f355193dcdb7a2 (patch)
tree2a1096b66c9465539fb6e13daa16137d730f3ea3 /fs/fscache
parent2457aaf73a97a97c8596ed3903bd09601976f3bc (diff)
FS-Cache: Add use/unuse/wake cookie wrappers
Add wrapper functions for dealing with cookie->n_active: (*) __fscache_use_cookie() to increment it. (*) __fscache_unuse_cookie() to decrement and test against zero. (*) __fscache_wake_unused_cookie() to wake up anyone waiting for it to reach zero. The second and third are split so that the third can be done after cookie->lock has been released in case the waiter wakes up whilst we're still holding it and tries to get it. We will need to wake-on-zero once the cookie disablement patch is applied because it will then be possible to see n_active become zero without the cookie being relinquished. Also move the cookie usement out of fscache_attr_changed_op() and into fscache_attr_changed() and the operation struct so that cookie disablement will be able to track it. Whilst we're at it, only increment n_active if we're about to do fscache_submit_op() so that we don't have to deal with undoing it if anything earlier fails. Possibly this should be moved into fscache_submit_op() which could look at FSCACHE_OP_UNUSE_COOKIE. Signed-off-by: David Howells <dhowells@redhat.com>
Diffstat (limited to 'fs/fscache')
-rw-r--r--fs/fscache/cookie.c7
-rw-r--r--fs/fscache/page.c42
2 files changed, 36 insertions, 13 deletions
diff --git a/fs/fscache/cookie.c b/fs/fscache/cookie.c
index b2a86e324aac..d851aa555d28 100644
--- a/fs/fscache/cookie.c
+++ b/fs/fscache/cookie.c
@@ -568,6 +568,7 @@ int __fscache_check_consistency(struct fscache_cookie *cookie)
568{ 568{
569 struct fscache_operation *op; 569 struct fscache_operation *op;
570 struct fscache_object *object; 570 struct fscache_object *object;
571 bool wake_cookie = false;
571 int ret; 572 int ret;
572 573
573 _enter("%p,", cookie); 574 _enter("%p,", cookie);
@@ -600,7 +601,7 @@ int __fscache_check_consistency(struct fscache_cookie *cookie)
600 601
601 op->debug_id = atomic_inc_return(&fscache_op_debug_id); 602 op->debug_id = atomic_inc_return(&fscache_op_debug_id);
602 603
603 atomic_inc(&cookie->n_active); 604 __fscache_use_cookie(cookie);
604 if (fscache_submit_op(object, op) < 0) 605 if (fscache_submit_op(object, op) < 0)
605 goto submit_failed; 606 goto submit_failed;
606 607
@@ -622,9 +623,11 @@ int __fscache_check_consistency(struct fscache_cookie *cookie)
622 return ret; 623 return ret;
623 624
624submit_failed: 625submit_failed:
625 atomic_dec(&cookie->n_active); 626 wake_cookie = __fscache_unuse_cookie(cookie);
626inconsistent: 627inconsistent:
627 spin_unlock(&cookie->lock); 628 spin_unlock(&cookie->lock);
629 if (wake_cookie)
630 __fscache_wake_unused_cookie(cookie);
628 kfree(op); 631 kfree(op);
629 _leave(" = -ESTALE"); 632 _leave(" = -ESTALE");
630 return -ESTALE; 633 return -ESTALE;
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
index 73899c1c3449..0fe42a6d0e9c 100644
--- a/fs/fscache/page.c
+++ b/fs/fscache/page.c
@@ -163,12 +163,10 @@ static void fscache_attr_changed_op(struct fscache_operation *op)
163 163
164 fscache_stat(&fscache_n_attr_changed_calls); 164 fscache_stat(&fscache_n_attr_changed_calls);
165 165
166 if (fscache_object_is_active(object) && 166 if (fscache_object_is_active(object)) {
167 fscache_use_cookie(object)) {
168 fscache_stat(&fscache_n_cop_attr_changed); 167 fscache_stat(&fscache_n_cop_attr_changed);
169 ret = object->cache->ops->attr_changed(object); 168 ret = object->cache->ops->attr_changed(object);
170 fscache_stat_d(&fscache_n_cop_attr_changed); 169 fscache_stat_d(&fscache_n_cop_attr_changed);
171 fscache_unuse_cookie(object);
172 if (ret < 0) 170 if (ret < 0)
173 fscache_abort_object(object); 171 fscache_abort_object(object);
174 } 172 }
@@ -184,6 +182,7 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
184{ 182{
185 struct fscache_operation *op; 183 struct fscache_operation *op;
186 struct fscache_object *object; 184 struct fscache_object *object;
185 bool wake_cookie;
187 186
188 _enter("%p", cookie); 187 _enter("%p", cookie);
189 188
@@ -199,7 +198,9 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
199 } 198 }
200 199
201 fscache_operation_init(op, fscache_attr_changed_op, NULL); 200 fscache_operation_init(op, fscache_attr_changed_op, NULL);
202 op->flags = FSCACHE_OP_ASYNC | (1 << FSCACHE_OP_EXCLUSIVE); 201 op->flags = FSCACHE_OP_ASYNC |
202 (1 << FSCACHE_OP_EXCLUSIVE) |
203 (1 << FSCACHE_OP_UNUSE_COOKIE);
203 204
204 spin_lock(&cookie->lock); 205 spin_lock(&cookie->lock);
205 206
@@ -208,6 +209,7 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
208 object = hlist_entry(cookie->backing_objects.first, 209 object = hlist_entry(cookie->backing_objects.first,
209 struct fscache_object, cookie_link); 210 struct fscache_object, cookie_link);
210 211
212 __fscache_use_cookie(cookie);
211 if (fscache_submit_exclusive_op(object, op) < 0) 213 if (fscache_submit_exclusive_op(object, op) < 0)
212 goto nobufs; 214 goto nobufs;
213 spin_unlock(&cookie->lock); 215 spin_unlock(&cookie->lock);
@@ -217,8 +219,11 @@ int __fscache_attr_changed(struct fscache_cookie *cookie)
217 return 0; 219 return 0;
218 220
219nobufs: 221nobufs:
222 wake_cookie = __fscache_unuse_cookie(cookie);
220 spin_unlock(&cookie->lock); 223 spin_unlock(&cookie->lock);
221 kfree(op); 224 kfree(op);
225 if (wake_cookie)
226 __fscache_wake_unused_cookie(cookie);
222 fscache_stat(&fscache_n_attr_changed_nobufs); 227 fscache_stat(&fscache_n_attr_changed_nobufs);
223 _leave(" = %d", -ENOBUFS); 228 _leave(" = %d", -ENOBUFS);
224 return -ENOBUFS; 229 return -ENOBUFS;
@@ -263,7 +268,6 @@ static struct fscache_retrieval *fscache_alloc_retrieval(
263 } 268 }
264 269
265 fscache_operation_init(&op->op, NULL, fscache_release_retrieval_op); 270 fscache_operation_init(&op->op, NULL, fscache_release_retrieval_op);
266 atomic_inc(&cookie->n_active);
267 op->op.flags = FSCACHE_OP_MYTHREAD | 271 op->op.flags = FSCACHE_OP_MYTHREAD |
268 (1UL << FSCACHE_OP_WAITING) | 272 (1UL << FSCACHE_OP_WAITING) |
269 (1UL << FSCACHE_OP_UNUSE_COOKIE); 273 (1UL << FSCACHE_OP_UNUSE_COOKIE);
@@ -384,6 +388,7 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
384{ 388{
385 struct fscache_retrieval *op; 389 struct fscache_retrieval *op;
386 struct fscache_object *object; 390 struct fscache_object *object;
391 bool wake_cookie = false;
387 int ret; 392 int ret;
388 393
389 _enter("%p,%p,,,", cookie, page); 394 _enter("%p,%p,,,", cookie, page);
@@ -421,6 +426,7 @@ int __fscache_read_or_alloc_page(struct fscache_cookie *cookie,
421 426
422 ASSERT(test_bit(FSCACHE_OBJECT_IS_LOOKED_UP, &object->flags)); 427 ASSERT(test_bit(FSCACHE_OBJECT_IS_LOOKED_UP, &object->flags));
423 428
429 __fscache_use_cookie(cookie);
424 atomic_inc(&object->n_reads); 430 atomic_inc(&object->n_reads);
425 __set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags); 431 __set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags);
426 432
@@ -475,9 +481,11 @@ error:
475 481
476nobufs_unlock_dec: 482nobufs_unlock_dec:
477 atomic_dec(&object->n_reads); 483 atomic_dec(&object->n_reads);
484 wake_cookie = __fscache_unuse_cookie(cookie);
478nobufs_unlock: 485nobufs_unlock:
479 spin_unlock(&cookie->lock); 486 spin_unlock(&cookie->lock);
480 atomic_dec(&cookie->n_active); 487 if (wake_cookie)
488 __fscache_wake_unused_cookie(cookie);
481 kfree(op); 489 kfree(op);
482nobufs: 490nobufs:
483 fscache_stat(&fscache_n_retrievals_nobufs); 491 fscache_stat(&fscache_n_retrievals_nobufs);
@@ -514,6 +522,7 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
514{ 522{
515 struct fscache_retrieval *op; 523 struct fscache_retrieval *op;
516 struct fscache_object *object; 524 struct fscache_object *object;
525 bool wake_cookie = false;
517 int ret; 526 int ret;
518 527
519 _enter("%p,,%d,,,", cookie, *nr_pages); 528 _enter("%p,,%d,,,", cookie, *nr_pages);
@@ -547,6 +556,7 @@ int __fscache_read_or_alloc_pages(struct fscache_cookie *cookie,
547 object = hlist_entry(cookie->backing_objects.first, 556 object = hlist_entry(cookie->backing_objects.first,
548 struct fscache_object, cookie_link); 557 struct fscache_object, cookie_link);
549 558
559 __fscache_use_cookie(cookie);
550 atomic_inc(&object->n_reads); 560 atomic_inc(&object->n_reads);
551 __set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags); 561 __set_bit(FSCACHE_OP_DEC_READ_CNT, &op->op.flags);
552 562
@@ -601,10 +611,12 @@ error:
601 611
602nobufs_unlock_dec: 612nobufs_unlock_dec:
603 atomic_dec(&object->n_reads); 613 atomic_dec(&object->n_reads);
614 wake_cookie = __fscache_unuse_cookie(cookie);
604nobufs_unlock: 615nobufs_unlock:
605 spin_unlock(&cookie->lock); 616 spin_unlock(&cookie->lock);
606 atomic_dec(&cookie->n_active);
607 kfree(op); 617 kfree(op);
618 if (wake_cookie)
619 __fscache_wake_unused_cookie(cookie);
608nobufs: 620nobufs:
609 fscache_stat(&fscache_n_retrievals_nobufs); 621 fscache_stat(&fscache_n_retrievals_nobufs);
610 _leave(" = -ENOBUFS"); 622 _leave(" = -ENOBUFS");
@@ -626,6 +638,7 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
626{ 638{
627 struct fscache_retrieval *op; 639 struct fscache_retrieval *op;
628 struct fscache_object *object; 640 struct fscache_object *object;
641 bool wake_cookie = false;
629 int ret; 642 int ret;
630 643
631 _enter("%p,%p,,,", cookie, page); 644 _enter("%p,%p,,,", cookie, page);
@@ -658,8 +671,9 @@ int __fscache_alloc_page(struct fscache_cookie *cookie,
658 object = hlist_entry(cookie->backing_objects.first, 671 object = hlist_entry(cookie->backing_objects.first,
659 struct fscache_object, cookie_link); 672 struct fscache_object, cookie_link);
660 673
674 __fscache_use_cookie(cookie);
661 if (fscache_submit_op(object, &op->op) < 0) 675 if (fscache_submit_op(object, &op->op) < 0)
662 goto nobufs_unlock; 676 goto nobufs_unlock_dec;
663 spin_unlock(&cookie->lock); 677 spin_unlock(&cookie->lock);
664 678
665 fscache_stat(&fscache_n_alloc_ops); 679 fscache_stat(&fscache_n_alloc_ops);
@@ -689,10 +703,13 @@ error:
689 _leave(" = %d", ret); 703 _leave(" = %d", ret);
690 return ret; 704 return ret;
691 705
706nobufs_unlock_dec:
707 wake_cookie = __fscache_unuse_cookie(cookie);
692nobufs_unlock: 708nobufs_unlock:
693 spin_unlock(&cookie->lock); 709 spin_unlock(&cookie->lock);
694 atomic_dec(&cookie->n_active);
695 kfree(op); 710 kfree(op);
711 if (wake_cookie)
712 __fscache_wake_unused_cookie(cookie);
696nobufs: 713nobufs:
697 fscache_stat(&fscache_n_allocs_nobufs); 714 fscache_stat(&fscache_n_allocs_nobufs);
698 _leave(" = -ENOBUFS"); 715 _leave(" = -ENOBUFS");
@@ -889,6 +906,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
889{ 906{
890 struct fscache_storage *op; 907 struct fscache_storage *op;
891 struct fscache_object *object; 908 struct fscache_object *object;
909 bool wake_cookie = false;
892 int ret; 910 int ret;
893 911
894 _enter("%p,%x,", cookie, (u32) page->flags); 912 _enter("%p,%x,", cookie, (u32) page->flags);
@@ -957,7 +975,7 @@ int __fscache_write_page(struct fscache_cookie *cookie,
957 op->op.debug_id = atomic_inc_return(&fscache_op_debug_id); 975 op->op.debug_id = atomic_inc_return(&fscache_op_debug_id);
958 op->store_limit = object->store_limit; 976 op->store_limit = object->store_limit;
959 977
960 atomic_inc(&cookie->n_active); 978 __fscache_use_cookie(cookie);
961 if (fscache_submit_op(object, &op->op) < 0) 979 if (fscache_submit_op(object, &op->op) < 0)
962 goto submit_failed; 980 goto submit_failed;
963 981
@@ -984,10 +1002,10 @@ already_pending:
984 return 0; 1002 return 0;
985 1003
986submit_failed: 1004submit_failed:
987 atomic_dec(&cookie->n_active);
988 spin_lock(&cookie->stores_lock); 1005 spin_lock(&cookie->stores_lock);
989 radix_tree_delete(&cookie->stores, page->index); 1006 radix_tree_delete(&cookie->stores, page->index);
990 spin_unlock(&cookie->stores_lock); 1007 spin_unlock(&cookie->stores_lock);
1008 wake_cookie = __fscache_unuse_cookie(cookie);
991 page_cache_release(page); 1009 page_cache_release(page);
992 ret = -ENOBUFS; 1010 ret = -ENOBUFS;
993 goto nobufs; 1011 goto nobufs;
@@ -999,6 +1017,8 @@ nobufs:
999 spin_unlock(&cookie->lock); 1017 spin_unlock(&cookie->lock);
1000 radix_tree_preload_end(); 1018 radix_tree_preload_end();
1001 kfree(op); 1019 kfree(op);
1020 if (wake_cookie)
1021 __fscache_wake_unused_cookie(cookie);
1002 fscache_stat(&fscache_n_stores_nobufs); 1022 fscache_stat(&fscache_n_stores_nobufs);
1003 _leave(" = -ENOBUFS"); 1023 _leave(" = -ENOBUFS");
1004 return -ENOBUFS; 1024 return -ENOBUFS;