diff options
author | David Howells <dhowells@redhat.com> | 2009-11-19 19:11:41 +0100 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2009-11-19 19:11:41 +0100 |
commit | d461d26dde901b0523c46b0317e7fccf574a3933 (patch) | |
tree | abaac0f4259ec9458fa40be85ed7a3d4f8982cc5 | |
parent | FS-Cache: Add a retirement stat counter (diff) | |
download | linux-d461d26dde901b0523c46b0317e7fccf574a3933.tar.xz linux-d461d26dde901b0523c46b0317e7fccf574a3933.zip |
FS-Cache: Make sure FSCACHE_COOKIE_LOOKING_UP cleared on lookup failure
We must make sure that FSCACHE_COOKIE_LOOKING_UP is cleared on lookup failure
(if an object reaches the LC_DYING state), and we should clear it before
clearing FSCACHE_COOKIE_CREATING.
If this doesn't happen then fscache_wait_for_deferred_lookup() may hold
allocation and retrieval operations indefinitely until they're interrupted by
signals - which in turn pins the dying object until they go away.
Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r-- | fs/fscache/object.c | 17 |
1 files changed, 12 insertions, 5 deletions
diff --git a/fs/fscache/object.c b/fs/fscache/object.c index 1a1afa82f798..74bc562a2cbc 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c @@ -105,6 +105,7 @@ static inline void fscache_done_parent_op(struct fscache_object *object) static void fscache_object_state_machine(struct fscache_object *object) { enum fscache_object_state new_state; + struct fscache_cookie *cookie; ASSERT(object != NULL); @@ -158,11 +159,17 @@ static void fscache_object_state_machine(struct fscache_object *object) spin_lock(&object->lock); object->state = FSCACHE_OBJECT_DYING; - if (object->cookie && - test_and_clear_bit(FSCACHE_COOKIE_CREATING, - &object->cookie->flags)) - wake_up_bit(&object->cookie->flags, - FSCACHE_COOKIE_CREATING); + cookie = object->cookie; + if (cookie) { + if (test_and_clear_bit(FSCACHE_COOKIE_LOOKING_UP, + &cookie->flags)) + wake_up_bit(&cookie->flags, + FSCACHE_COOKIE_LOOKING_UP); + if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, + &cookie->flags)) + wake_up_bit(&cookie->flags, + FSCACHE_COOKIE_CREATING); + } spin_unlock(&object->lock); fscache_done_parent_op(object); |