diff options
author | David Howells <dhowells@redhat.com> | 2009-11-19 13:11:41 -0500 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2009-11-19 13:11:41 -0500 |
commit | d461d26dde901b0523c46b0317e7fccf574a3933 (patch) | |
tree | abaac0f4259ec9458fa40be85ed7a3d4f8982cc5 /fs/fscache/object.c | |
parent | 2175bb06dc6cf2af9c098a1770561f9e63edae4e (diff) |
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>
Diffstat (limited to 'fs/fscache/object.c')
-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) | |||
105 | static void fscache_object_state_machine(struct fscache_object *object) | 105 | static void fscache_object_state_machine(struct fscache_object *object) |
106 | { | 106 | { |
107 | enum fscache_object_state new_state; | 107 | enum fscache_object_state new_state; |
108 | struct fscache_cookie *cookie; | ||
108 | 109 | ||
109 | ASSERT(object != NULL); | 110 | ASSERT(object != NULL); |
110 | 111 | ||
@@ -158,11 +159,17 @@ static void fscache_object_state_machine(struct fscache_object *object) | |||
158 | 159 | ||
159 | spin_lock(&object->lock); | 160 | spin_lock(&object->lock); |
160 | object->state = FSCACHE_OBJECT_DYING; | 161 | object->state = FSCACHE_OBJECT_DYING; |
161 | if (object->cookie && | 162 | cookie = object->cookie; |
162 | test_and_clear_bit(FSCACHE_COOKIE_CREATING, | 163 | if (cookie) { |
163 | &object->cookie->flags)) | 164 | if (test_and_clear_bit(FSCACHE_COOKIE_LOOKING_UP, |
164 | wake_up_bit(&object->cookie->flags, | 165 | &cookie->flags)) |
165 | FSCACHE_COOKIE_CREATING); | 166 | wake_up_bit(&cookie->flags, |
167 | FSCACHE_COOKIE_LOOKING_UP); | ||
168 | if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, | ||
169 | &cookie->flags)) | ||
170 | wake_up_bit(&cookie->flags, | ||
171 | FSCACHE_COOKIE_CREATING); | ||
172 | } | ||
166 | spin_unlock(&object->lock); | 173 | spin_unlock(&object->lock); |
167 | 174 | ||
168 | fscache_done_parent_op(object); | 175 | fscache_done_parent_op(object); |