diff options
author | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-07-07 04:19:54 -0400 |
---|---|---|
committer | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-07-22 21:02:12 -0400 |
commit | cfa913a5077f7619869b2b4d1bf23ccb4f8b3d7b (patch) | |
tree | f4d8e4e8d8ee220b448566a08e75bccfb0ca966f /fs/nilfs2 | |
parent | 7c01745781177795e39f78b2c2c42c470a13833a (diff) |
nilfs2: add sanity check in nilfs_btree_add_dirty_buffer
According to the report titled "problem with nilfs_cleanerd" from
Łukasz Wójcicki, nilfs_btree_lookup_dirty_buffers or
nilfs_btree_add_dirty_buffer got memory violation during garbage
collection.
This could happen if a level field of given btree node buffer is
incorrect, which is a crucial internal bug.
This inserts a sanity check to figure out the problem.
Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Diffstat (limited to 'fs/nilfs2')
-rw-r--r-- | fs/nilfs2/btree.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/fs/nilfs2/btree.c b/fs/nilfs2/btree.c index b27a342c5af6..386356707f90 100644 --- a/fs/nilfs2/btree.c +++ b/fs/nilfs2/btree.c | |||
@@ -1920,6 +1920,18 @@ static void nilfs_btree_add_dirty_buffer(struct nilfs_btree *btree, | |||
1920 | node = (struct nilfs_btree_node *)bh->b_data; | 1920 | node = (struct nilfs_btree_node *)bh->b_data; |
1921 | key = nilfs_btree_node_get_key(node, 0); | 1921 | key = nilfs_btree_node_get_key(node, 0); |
1922 | level = nilfs_btree_node_get_level(node); | 1922 | level = nilfs_btree_node_get_level(node); |
1923 | if (level < NILFS_BTREE_LEVEL_NODE_MIN || | ||
1924 | level >= NILFS_BTREE_LEVEL_MAX) { | ||
1925 | dump_stack(); | ||
1926 | printk(KERN_WARNING | ||
1927 | "%s: invalid btree level: %d (key=%llu, ino=%lu, " | ||
1928 | "blocknr=%llu)\n", | ||
1929 | __func__, level, (unsigned long long)key, | ||
1930 | NILFS_BMAP_I(&btree->bt_bmap)->vfs_inode.i_ino, | ||
1931 | (unsigned long long)bh->b_blocknr); | ||
1932 | return; | ||
1933 | } | ||
1934 | |||
1923 | list_for_each(head, &lists[level]) { | 1935 | list_for_each(head, &lists[level]) { |
1924 | cbh = list_entry(head, struct buffer_head, b_assoc_buffers); | 1936 | cbh = list_entry(head, struct buffer_head, b_assoc_buffers); |
1925 | cnode = (struct nilfs_btree_node *)cbh->b_data; | 1937 | cnode = (struct nilfs_btree_node *)cbh->b_data; |