diff options
author | David Howells <dhowells@redhat.com> | 2009-11-19 13:11:22 -0500 |
---|---|---|
committer | David Howells <dhowells@redhat.com> | 2009-11-19 13:11:22 -0500 |
commit | 6897e3df8fc37bd4a58bbcdef8306da7fc175584 (patch) | |
tree | e826cd96f0395775d4fea113dc283ae0282f0384 | |
parent | 5753c441889253e4323eee85f791a1d64cf08196 (diff) |
FS-Cache: The object-available state can't rely on the cookie to be available
The object-available state in the object processing state machine (as
processed by fscache_object_available()) can't rely on the cookie to be
available because the FSCACHE_COOKIE_CREATING bit may have been cleared by
fscache_obtained_object() prior to the object being put into the
FSCACHE_OBJECT_AVAILABLE state.
Clearing the FSCACHE_COOKIE_CREATING bit on a cookie permits
__fscache_relinquish_cookie() to proceed and detach the cookie from the
object.
To deal with this, we don't dereference object->cookie in
fscache_object_available() if the object has already been detached.
In addition, a couple of assertions are added into fscache_drop_object() to
make sure the object is unbound from the cookie before it gets there.
Signed-off-by: David Howells <dhowells@redhat.com>
-rw-r--r-- | fs/fscache/object.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/fs/fscache/object.c b/fs/fscache/object.c index 0d65c0c92b46..1a1afa82f798 100644 --- a/fs/fscache/object.c +++ b/fs/fscache/object.c | |||
@@ -158,7 +158,8 @@ static void fscache_object_state_machine(struct fscache_object *object) | |||
158 | 158 | ||
159 | spin_lock(&object->lock); | 159 | spin_lock(&object->lock); |
160 | object->state = FSCACHE_OBJECT_DYING; | 160 | object->state = FSCACHE_OBJECT_DYING; |
161 | if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, | 161 | if (object->cookie && |
162 | test_and_clear_bit(FSCACHE_COOKIE_CREATING, | ||
162 | &object->cookie->flags)) | 163 | &object->cookie->flags)) |
163 | wake_up_bit(&object->cookie->flags, | 164 | wake_up_bit(&object->cookie->flags, |
164 | FSCACHE_COOKIE_CREATING); | 165 | FSCACHE_COOKIE_CREATING); |
@@ -594,7 +595,8 @@ static void fscache_object_available(struct fscache_object *object) | |||
594 | 595 | ||
595 | spin_lock(&object->lock); | 596 | spin_lock(&object->lock); |
596 | 597 | ||
597 | if (test_and_clear_bit(FSCACHE_COOKIE_CREATING, &object->cookie->flags)) | 598 | if (object->cookie && |
599 | test_and_clear_bit(FSCACHE_COOKIE_CREATING, &object->cookie->flags)) | ||
598 | wake_up_bit(&object->cookie->flags, FSCACHE_COOKIE_CREATING); | 600 | wake_up_bit(&object->cookie->flags, FSCACHE_COOKIE_CREATING); |
599 | 601 | ||
600 | fscache_done_parent_op(object); | 602 | fscache_done_parent_op(object); |
@@ -631,6 +633,9 @@ static void fscache_drop_object(struct fscache_object *object) | |||
631 | 633 | ||
632 | _enter("{OBJ%x,%d}", object->debug_id, object->n_children); | 634 | _enter("{OBJ%x,%d}", object->debug_id, object->n_children); |
633 | 635 | ||
636 | ASSERTCMP(object->cookie, ==, NULL); | ||
637 | ASSERT(hlist_unhashed(&object->cookie_link)); | ||
638 | |||
634 | spin_lock(&cache->object_list_lock); | 639 | spin_lock(&cache->object_list_lock); |
635 | list_del_init(&object->cache_link); | 640 | list_del_init(&object->cache_link); |
636 | spin_unlock(&cache->object_list_lock); | 641 | spin_unlock(&cache->object_list_lock); |