From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S269175AbUI3LQ3 (ORCPT ); Thu, 30 Sep 2004 07:16:29 -0400 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S269184AbUI3LQ3 (ORCPT ); Thu, 30 Sep 2004 07:16:29 -0400 Received: from mx1.redhat.com ([66.187.233.31]:15813 "EHLO mx1.redhat.com") by vger.kernel.org with ESMTP id S269175AbUI3LQY (ORCPT ); Thu, 30 Sep 2004 07:16:24 -0400 From: David Howells To: akpm@osdl.org cc: linux-kernel@vger.kernel.org, cachefs@lists.infradead.org Subject: [PATCH] Release CacheFS search records lest they return to haunt us User-Agent: EMH/1.14.1 SEMI/1.14.5 (Awara-Onsen) FLIM/1.14.5 (Demachiyanagi) APEL/10.6 Emacs/21.3 (i386-redhat-linux-gnu) MULE/5.0 (SAKAKI) MIME-Version: 1.0 (generated by SEMI 1.14.5 - "Awara-Onsen") Content-Type: text/plain; charset=US-ASCII Date: Thu, 30 Sep 2004 12:16:07 +0100 Message-ID: <26133.1096542967@redhat.com> Sender: linux-kernel-owner@vger.kernel.org X-Mailing-List: linux-kernel@vger.kernel.org The attached patch causes CacheFS to free cached search records when it destroys a cookie. These were coming back to haunt us because the list isn't re-initialised when the cookie is re-allocated (the slab allocator func initialises it in the first place). Signed-Off-By: David Howells --- interface.c | 34 ++++++++++++++++++++++++++-------- 1 files changed, 26 insertions(+), 8 deletions(-) --- linux-2.6.9-rc2-mm4/fs/cachefs/interface.c 2004-09-27 11:23:55.000000000 +0100 +++ linux-2.6.9-rc2-mm4-afskey/fs/cachefs/interface.c 2004-09-29 20:06:25.416144902 +0100 @@ -114,7 +114,8 @@ up_write(&cachefs_addremove_sem); if (ret < 0) { - kmem_cache_free(cachefs_cookie_jar, netfs->primary_index); + netfs->primary_index->iparent = NULL; + __cachefs_cookie_put(netfs->primary_index); netfs->primary_index = NULL; } @@ -275,8 +276,9 @@ struct cachefs_search_result *srch; struct cachefs_cookie *cookie, *xcookie = NULL; - _enter("{ino=%lu cnt=%u}", - inode->vfs_inode.i_ino, atomic_read(&inode->vfs_inode.i_count)); + _enter("{ino=%lu cnt=%u ck=%p}", + inode->vfs_inode.i_ino, atomic_read(&inode->vfs_inode.i_count), + inode->cookie); /* first of all we have to break the links between the inode and the * cookie @@ -305,9 +307,11 @@ * cookie's list */ list_for_each_entry(srch, &cookie->search_results, link) { if (srch->super == inode->vfs_inode.i_sb->s_fs_info) - break; + goto found_record; } + BUG(); + found_record: list_del(&srch->link); dbgfree(srch); kfree(srch); @@ -773,9 +777,8 @@ error: printk("CacheFS: error from cache fs: %d\n", ret); if (cookie) { - kmem_cache_free(cachefs_cookie_jar, cookie); + __cachefs_cookie_put(cookie); cookie = CACHEFS_NEGATIVE_COOKIE; - atomic_dec(&iparent->usage); atomic_dec(&iparent->children); } @@ -800,7 +803,8 @@ { struct cachefs_inode *inode; - _enter("{%s},%d", + _enter("%p{%s},%d", + cookie, cookie && cookie->idef ? (char *) cookie->idef->name : "", retire); @@ -955,11 +959,25 @@ */ static void __cachefs_cookie_put(struct cachefs_cookie *cookie) { - _enter(""); + struct cachefs_search_result *srch; + + _enter("%p", cookie); if (cookie->iparent) cachefs_cookie_put(cookie->iparent); + /* dispose of any cached search results */ + while (!list_empty(&cookie->search_results)) { + srch = list_entry(cookie->search_results.next, + struct cachefs_search_result, + link); + + list_del(&srch->link); + kfree(srch); + } + + BUG_ON(!list_empty(&cookie->search_results)); + BUG_ON(!list_empty(&cookie->backing_inodes)); kmem_cache_free(cachefs_cookie_jar, cookie); _leave("");