summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>2009-09-28 01:46:11 +0900
committerGreg Kroah-Hartman <gregkh@suse.de>2009-10-05 08:27:48 -0700
commitb268e3922e96d65d69934636442d89cf553d36c2 (patch)
treeb8abb5fc5478b1a95f98ba7567016f45ad4bf3ab
parent439933709a0ef6f9ab8cf66a99c0967883e0c4b4 (diff)
nilfs2: fix missing zero-fill initialization of btree node cache
commit 1f28fcd925b2b3157411bbd08f0024b55b70d8dd upstream. This will fix file system corruption which infrequently happens after mount. The problem was reported from users with the title "[NILFS users] Fail to mount NILFS." (Message-ID: <200908211918.34720.yuri@itinteg.net>), and so forth. I've also experienced the corruption multiple times on kernel 2.6.30 and 2.6.31. The problem turned out to be caused due to discordance between mapping->nrpages of a btree node cache and the actual number of pages hung on the cache; if the mapping->nrpages becomes zero even as it has pages, truncate_inode_pages() returns without doing anything. Usually this is harmless except it may cause page leak, but garbage collection fairly infrequently sees a stale page remained in the btree node cache of DAT (i.e. disk address translation file of nilfs), and induces the corruption. I identified a missing initialization in btree node caches was the root cause. This corrects the bug. I've tested this for kernel 2.6.30 and 2.6.31. Reported-by: Yuri Chislov <yuri@itinteg.net> Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
-rw-r--r--fs/nilfs2/btnode.c1
1 files changed, 1 insertions, 0 deletions
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c
index b55f31c0056c..8344005ea00b 100644
--- a/fs/nilfs2/btnode.c
+++ b/fs/nilfs2/btnode.c
@@ -36,6 +36,7 @@
void nilfs_btnode_cache_init_once(struct address_space *btnc)
{
+ memset(btnc, 0, sizeof(*btnc));
INIT_RADIX_TREE(&btnc->page_tree, GFP_ATOMIC);
spin_lock_init(&btnc->tree_lock);
INIT_LIST_HEAD(&btnc->private_list);