aboutsummaryrefslogtreecommitdiffstats
path: root/fs/fscache
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2015-02-25 09:22:40 -0500
committerDavid Howells <dhowells@redhat.com>2015-04-02 09:28:53 -0400
commita39caadf06879017cb9a8c5c5cb4fc4ccb213275 (patch)
treea558a3886da28ae502a271ce8597b1860e65594b /fs/fscache
parent73c04a47bf79770fbe7f3cf515f5831fccab88ee (diff)
FS-Cache: Put an aborted initialised op so that it is accounted correctly
Call fscache_put_operation() or a wrapper on any op that has gone through fscache_operation_init() so that the accounting shown in /proc is done correctly, specifically fscache_n_op_release. fscache_put_operation() therefore now allows an op in the INITIALISED state as well as in the CANCELLED and COMPLETE states. Note that this means that an operation can get put that doesn't have its ->object pointer filled in, so anything that depends on the object needs to be conditional in fscache_put_operation(). Signed-off-by: David Howells <dhowells@redhat.com> Reviewed-by: Steve Dickson <steved@redhat.com> Acked-by: Jeff Layton <jeff.layton@primarydata.com>
Diffstat (limited to 'fs/fscache')
-rw-r--r--fs/fscache/operation.c54
-rw-r--r--fs/fscache/page.c14
2 files changed, 35 insertions, 33 deletions
diff --git a/fs/fscache/operation.c b/fs/fscache/operation.c
index b6bf5f399d70..c76c09730768 100644
--- a/fs/fscache/operation.c
+++ b/fs/fscache/operation.c
@@ -472,7 +472,8 @@ void fscache_put_operation(struct fscache_operation *op)
472 return; 472 return;
473 473
474 _debug("PUT OP"); 474 _debug("PUT OP");
475 ASSERTIFCMP(op->state != FSCACHE_OP_ST_COMPLETE, 475 ASSERTIFCMP(op->state != FSCACHE_OP_ST_INITIALISED &&
476 op->state != FSCACHE_OP_ST_COMPLETE,
476 op->state, ==, FSCACHE_OP_ST_CANCELLED); 477 op->state, ==, FSCACHE_OP_ST_CANCELLED);
477 op->state = FSCACHE_OP_ST_DEAD; 478 op->state = FSCACHE_OP_ST_DEAD;
478 479
@@ -484,35 +485,36 @@ void fscache_put_operation(struct fscache_operation *op)
484 } 485 }
485 486
486 object = op->object; 487 object = op->object;
488 if (likely(object)) {
489 if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags))
490 atomic_dec(&object->n_reads);
491 if (test_bit(FSCACHE_OP_UNUSE_COOKIE, &op->flags))
492 fscache_unuse_cookie(object);
493
494 /* now... we may get called with the object spinlock held, so we
495 * complete the cleanup here only if we can immediately acquire the
496 * lock, and defer it otherwise */
497 if (!spin_trylock(&object->lock)) {
498 _debug("defer put");
499 fscache_stat(&fscache_n_op_deferred_release);
500
501 cache = object->cache;
502 spin_lock(&cache->op_gc_list_lock);
503 list_add_tail(&op->pend_link, &cache->op_gc_list);
504 spin_unlock(&cache->op_gc_list_lock);
505 schedule_work(&cache->op_gc);
506 _leave(" [defer]");
507 return;
508 }
487 509
488 if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags)) 510 ASSERTCMP(object->n_ops, >, 0);
489 atomic_dec(&object->n_reads); 511 object->n_ops--;
490 if (test_bit(FSCACHE_OP_UNUSE_COOKIE, &op->flags)) 512 if (object->n_ops == 0)
491 fscache_unuse_cookie(object); 513 fscache_raise_event(object, FSCACHE_OBJECT_EV_CLEARED);
492
493 /* now... we may get called with the object spinlock held, so we
494 * complete the cleanup here only if we can immediately acquire the
495 * lock, and defer it otherwise */
496 if (!spin_trylock(&object->lock)) {
497 _debug("defer put");
498 fscache_stat(&fscache_n_op_deferred_release);
499 514
500 cache = object->cache; 515 spin_unlock(&object->lock);
501 spin_lock(&cache->op_gc_list_lock);
502 list_add_tail(&op->pend_link, &cache->op_gc_list);
503 spin_unlock(&cache->op_gc_list_lock);
504 schedule_work(&cache->op_gc);
505 _leave(" [defer]");
506 return;
507 } 516 }
508 517
509 ASSERTCMP(object->n_ops, >, 0);
510 object->n_ops--;
511 if (object->n_ops == 0)
512 fscache_raise_event(object, FSCACHE_OBJECT_EV_CLEARED);
513
514 spin_unlock(&object->lock);
515
516 kfree(op); 518 kfree(op);
517 _leave(" [done]"); 519 _leave(" [done]");
518} 520}
diff --git a/fs/fscache/page.c b/fs/fscache/page.c
index 433cae927eca..7db9752252ef 100644
--- a/fs/fscache/page.c
+++ b/fs/fscache/page.c
@@ -239,7 +239,7 @@ nobufs_dec:
239 wake_cookie = __fscache_unuse_cookie(cookie); 239 wake_cookie = __fscache_unuse_cookie(cookie);
240nobufs: 240nobufs:
241 spin_unlock(&cookie->lock); 241 spin_unlock(&cookie->lock);
242 kfree(op); 242 fscache_put_operation(op);
243 if (wake_cookie) 243 if (wake_cookie)
244 __fscache_wake_unused_cookie(cookie); 244 __fscache_wake_unused_cookie(cookie);
245 fscache_stat(&fscache_n_attr_changed_nobufs); 245 fscache_stat(&fscache_n_attr_changed_nobufs);
@@ -505,7 +505,7 @@ nobufs_unlock:
505 spin_unlock(&cookie->lock); 505 spin_unlock(&cookie->lock);
506 if (wake_cookie) 506 if (wake_cookie)
507 __fscache_wake_unused_cookie(cookie); 507 __fscache_wake_unused_cookie(cookie);
508 kfree(op); 508 fscache_put_retrieval(op);
509nobufs: 509nobufs:
510 fscache_stat(&fscache_n_retrievals_nobufs); 510 fscache_stat(&fscache_n_retrievals_nobufs);
511 _leave(" = -ENOBUFS"); 511 _leave(" = -ENOBUFS");
@@ -634,7 +634,7 @@ nobufs_unlock_dec:
634 wake_cookie = __fscache_unuse_cookie(cookie); 634 wake_cookie = __fscache_unuse_cookie(cookie);
635nobufs_unlock: 635nobufs_unlock:
636 spin_unlock(&cookie->lock); 636 spin_unlock(&cookie->lock);
637 kfree(op); 637 fscache_put_retrieval(op);
638 if (wake_cookie) 638 if (wake_cookie)
639 __fscache_wake_unused_cookie(cookie); 639 __fscache_wake_unused_cookie(cookie);
640nobufs: 640nobufs:
@@ -728,7 +728,7 @@ nobufs_unlock_dec:
728 wake_cookie = __fscache_unuse_cookie(cookie); 728 wake_cookie = __fscache_unuse_cookie(cookie);
729nobufs_unlock: 729nobufs_unlock:
730 spin_unlock(&cookie->lock); 730 spin_unlock(&cookie->lock);
731 kfree(op); 731 fscache_put_retrieval(op);
732 if (wake_cookie) 732 if (wake_cookie)
733 __fscache_wake_unused_cookie(cookie); 733 __fscache_wake_unused_cookie(cookie);
734nobufs: 734nobufs:
@@ -1018,7 +1018,7 @@ already_pending:
1018 spin_unlock(&object->lock); 1018 spin_unlock(&object->lock);
1019 spin_unlock(&cookie->lock); 1019 spin_unlock(&cookie->lock);
1020 radix_tree_preload_end(); 1020 radix_tree_preload_end();
1021 kfree(op); 1021 fscache_put_operation(&op->op);
1022 fscache_stat(&fscache_n_stores_ok); 1022 fscache_stat(&fscache_n_stores_ok);
1023 _leave(" = 0"); 1023 _leave(" = 0");
1024 return 0; 1024 return 0;
@@ -1038,7 +1038,7 @@ nobufs_unlock_obj:
1038nobufs: 1038nobufs:
1039 spin_unlock(&cookie->lock); 1039 spin_unlock(&cookie->lock);
1040 radix_tree_preload_end(); 1040 radix_tree_preload_end();
1041 kfree(op); 1041 fscache_put_operation(&op->op);
1042 if (wake_cookie) 1042 if (wake_cookie)
1043 __fscache_wake_unused_cookie(cookie); 1043 __fscache_wake_unused_cookie(cookie);
1044 fscache_stat(&fscache_n_stores_nobufs); 1044 fscache_stat(&fscache_n_stores_nobufs);
@@ -1046,7 +1046,7 @@ nobufs:
1046 return -ENOBUFS; 1046 return -ENOBUFS;
1047 1047
1048nomem_free: 1048nomem_free:
1049 kfree(op); 1049 fscache_put_operation(&op->op);
1050nomem: 1050nomem:
1051 fscache_stat(&fscache_n_stores_oom); 1051 fscache_stat(&fscache_n_stores_oom);
1052 _leave(" = -ENOMEM"); 1052 _leave(" = -ENOMEM");