Loading fs/fscache/cookie.c +14 −4 Original line number Diff line number Diff line Loading @@ -442,22 +442,32 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE; try_again: spin_lock(&cookie->lock); /* break links with all the active objects */ while (!hlist_empty(&cookie->backing_objects)) { int n_reads; object = hlist_entry(cookie->backing_objects.first, struct fscache_object, cookie_link); _debug("RELEASE OBJ%x", object->debug_id); if (atomic_read(&object->n_reads)) { set_bit(FSCACHE_COOKIE_WAITING_ON_READS, &cookie->flags); n_reads = atomic_read(&object->n_reads); if (n_reads) { int n_ops = object->n_ops; int n_in_progress = object->n_in_progress; spin_unlock(&cookie->lock); printk(KERN_ERR "FS-Cache:" " Cookie '%s' still has %d outstanding reads\n", cookie->def->name, atomic_read(&object->n_reads)); BUG(); " Cookie '%s' still has %d outstanding reads (%d,%d)\n", cookie->def->name, n_reads, n_ops, n_in_progress); wait_on_bit(&cookie->flags, FSCACHE_COOKIE_WAITING_ON_READS, fscache_wait_bit, TASK_UNINTERRUPTIBLE); printk("Wait finished\n"); goto try_again; } /* detach each cache object from the object cookie */ Loading fs/fscache/operation.c +8 −2 Original line number Diff line number Diff line Loading @@ -340,8 +340,14 @@ void fscache_put_operation(struct fscache_operation *op) object = op->object; if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags)) atomic_dec(&object->n_reads); if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags)) { if (atomic_dec_and_test(&object->n_reads)) { clear_bit(FSCACHE_COOKIE_WAITING_ON_READS, &object->cookie->flags); wake_up_bit(&object->cookie->flags, FSCACHE_COOKIE_WAITING_ON_READS); } } /* now... we may get called with the object spinlock held, so we * complete the cleanup here only if we can immediately acquire the Loading include/linux/fscache-cache.h +1 −0 Original line number Diff line number Diff line Loading @@ -301,6 +301,7 @@ struct fscache_cookie { #define FSCACHE_COOKIE_PENDING_FILL 3 /* T if pending initial fill on object */ #define FSCACHE_COOKIE_FILLING 4 /* T if filling object incrementally */ #define FSCACHE_COOKIE_UNAVAILABLE 5 /* T if cookie is unavailable (error, etc) */ #define FSCACHE_COOKIE_WAITING_ON_READS 6 /* T if cookie is waiting on reads */ }; extern struct fscache_cookie fscache_fsdef_index; Loading Loading
fs/fscache/cookie.c +14 −4 Original line number Diff line number Diff line Loading @@ -442,22 +442,32 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE; try_again: spin_lock(&cookie->lock); /* break links with all the active objects */ while (!hlist_empty(&cookie->backing_objects)) { int n_reads; object = hlist_entry(cookie->backing_objects.first, struct fscache_object, cookie_link); _debug("RELEASE OBJ%x", object->debug_id); if (atomic_read(&object->n_reads)) { set_bit(FSCACHE_COOKIE_WAITING_ON_READS, &cookie->flags); n_reads = atomic_read(&object->n_reads); if (n_reads) { int n_ops = object->n_ops; int n_in_progress = object->n_in_progress; spin_unlock(&cookie->lock); printk(KERN_ERR "FS-Cache:" " Cookie '%s' still has %d outstanding reads\n", cookie->def->name, atomic_read(&object->n_reads)); BUG(); " Cookie '%s' still has %d outstanding reads (%d,%d)\n", cookie->def->name, n_reads, n_ops, n_in_progress); wait_on_bit(&cookie->flags, FSCACHE_COOKIE_WAITING_ON_READS, fscache_wait_bit, TASK_UNINTERRUPTIBLE); printk("Wait finished\n"); goto try_again; } /* detach each cache object from the object cookie */ Loading
fs/fscache/operation.c +8 −2 Original line number Diff line number Diff line Loading @@ -340,8 +340,14 @@ void fscache_put_operation(struct fscache_operation *op) object = op->object; if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags)) atomic_dec(&object->n_reads); if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags)) { if (atomic_dec_and_test(&object->n_reads)) { clear_bit(FSCACHE_COOKIE_WAITING_ON_READS, &object->cookie->flags); wake_up_bit(&object->cookie->flags, FSCACHE_COOKIE_WAITING_ON_READS); } } /* now... we may get called with the object spinlock held, so we * complete the cleanup here only if we can immediately acquire the Loading
include/linux/fscache-cache.h +1 −0 Original line number Diff line number Diff line Loading @@ -301,6 +301,7 @@ struct fscache_cookie { #define FSCACHE_COOKIE_PENDING_FILL 3 /* T if pending initial fill on object */ #define FSCACHE_COOKIE_FILLING 4 /* T if filling object incrementally */ #define FSCACHE_COOKIE_UNAVAILABLE 5 /* T if cookie is unavailable (error, etc) */ #define FSCACHE_COOKIE_WAITING_ON_READS 6 /* T if cookie is waiting on reads */ }; extern struct fscache_cookie fscache_fsdef_index; Loading