From: David Howells The attached patch fixes a bug in the in __fscache_acquire_cookie()'s error handling and tidies the code up a bit. What was happening was the dead cookie was being released in the bit governed by the error: label, and then an attempt was made to release the cookie's semaphore when that fell through into the done: bit. Signed-Off-By: David Howells Signed-off-by: Andrew Morton --- 25-akpm/fs/fscache/cookie.c | 49 +++++++++++++++++++++++--------------------- 1 files changed, 26 insertions(+), 23 deletions(-) diff -puN fs/fscache/cookie.c~split-general-cache-manager-from-cachefs-fix fs/fscache/cookie.c --- 25/fs/fscache/cookie.c~split-general-cache-manager-from-cachefs-fix 2005-04-12 18:57:22.991024016 -0700 +++ 25-akpm/fs/fscache/cookie.c 2005-04-12 18:57:22.996023256 -0700 @@ -743,7 +743,7 @@ struct fscache_cookie *__fscache_acquire if (list_empty(&fscache_cache_list)) { up_read(&fscache_addremove_sem); - _leave(" [no caches]"); + _leave(" = %p [no caches]", cookie); return cookie; } @@ -765,38 +765,41 @@ struct fscache_cookie *__fscache_acquire } } - /* if the object is a cookie then we need do nothing more here - we + /* if the object is an index then we need do nothing more here - we * create indexes on disc when we need them as an index may exist in * multiple caches */ - if (cookie->idef) - goto done; + if (!cookie->idef) { + /* the object is a file - we need to select a cache in which to + * store it */ + cache = fscache_select_cache_for_file(); + if (!cache) + goto no_cache; /* couldn't decide on a cache */ + + /* create a file index entry on disc, along with all the + * indexes required to find it again later */ + ret = fscache_instantiate_object(cookie, cache); + if (ret < 0) + goto error; + } - /* the object is a file - we need to select a cache in which to store - * it */ - ret = -ENOMEDIUM; - cache = fscache_select_cache_for_file(); - if (!cache) - goto error; /* couldn't decide on a cache */ - - /* create a file index entry on disc, along with all the indexes - * required to find it again later */ - ret = fscache_instantiate_object(cookie, cache); - if (ret == 0) - goto done; + up_write(&cookie->sem); +out: + up_read(&fscache_addremove_sem); + _leave(" = %p", cookie); + return cookie; - error: - printk("FS-Cache: error from cache fs: %d\n", ret); +no_cache: + ret = -ENOMEDIUM; +error: + printk("FS-Cache: error from cache: %d\n", ret); if (cookie) { + up_write(&cookie->sem); __fscache_cookie_put(cookie); cookie = FSCACHE_NEGATIVE_COOKIE; atomic_dec(&iparent->children); } - done: - up_write(&cookie->sem); - up_read(&fscache_addremove_sem); - _leave(" = %p", cookie); - return cookie; + goto out; } /* end __fscache_acquire_cookie() */ _