Commit ef46ed88 authored by David Howells's avatar David Howells

FS-Cache: Make cookie relinquishment wait for outstanding reads

Make fscache_relinquish_cookie() log a warning and wait if there are any
outstanding reads left on the cookie it was given.
Signed-off-by: default avatarDavid Howells <dhowells@redhat.com>
parent 37491a13
...@@ -442,22 +442,32 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire) ...@@ -442,22 +442,32 @@ void __fscache_relinquish_cookie(struct fscache_cookie *cookie, int retire)
event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE; event = retire ? FSCACHE_OBJECT_EV_RETIRE : FSCACHE_OBJECT_EV_RELEASE;
try_again:
spin_lock(&cookie->lock); spin_lock(&cookie->lock);
/* break links with all the active objects */ /* break links with all the active objects */
while (!hlist_empty(&cookie->backing_objects)) { while (!hlist_empty(&cookie->backing_objects)) {
int n_reads;
object = hlist_entry(cookie->backing_objects.first, object = hlist_entry(cookie->backing_objects.first,
struct fscache_object, struct fscache_object,
cookie_link); cookie_link);
_debug("RELEASE OBJ%x", object->debug_id); _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); spin_unlock(&cookie->lock);
printk(KERN_ERR "FS-Cache:" printk(KERN_ERR "FS-Cache:"
" Cookie '%s' still has %d outstanding reads\n", " Cookie '%s' still has %d outstanding reads (%d,%d)\n",
cookie->def->name, atomic_read(&object->n_reads)); cookie->def->name,
BUG(); 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 */ /* detach each cache object from the object cookie */
......
...@@ -340,8 +340,14 @@ void fscache_put_operation(struct fscache_operation *op) ...@@ -340,8 +340,14 @@ void fscache_put_operation(struct fscache_operation *op)
object = op->object; object = op->object;
if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags)) if (test_bit(FSCACHE_OP_DEC_READ_CNT, &op->flags)) {
atomic_dec(&object->n_reads); 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 /* now... we may get called with the object spinlock held, so we
* complete the cleanup here only if we can immediately acquire the * complete the cleanup here only if we can immediately acquire the
......
...@@ -301,6 +301,7 @@ struct fscache_cookie { ...@@ -301,6 +301,7 @@ struct fscache_cookie {
#define FSCACHE_COOKIE_PENDING_FILL 3 /* T if pending initial fill on object */ #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_FILLING 4 /* T if filling object incrementally */
#define FSCACHE_COOKIE_UNAVAILABLE 5 /* T if cookie is unavailable (error, etc) */ #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; extern struct fscache_cookie fscache_fsdef_index;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment