nilfs2: add sanity check in nilfs_btree_add_dirty_buffer
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Wed, 7 Jul 2010 08:19:54 +0000 (17:19 +0900)
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Fri, 23 Jul 2010 01:02:12 +0000 (10:02 +0900)
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>
fs/nilfs2/btree.c

index b27a342c5af681efb28154f0109111a6843a7ab6..386356707f90b10f827a3db3c7effae86c55f637 100644 (file)
@@ -1920,6 +1920,18 @@ static void nilfs_btree_add_dirty_buffer(struct nilfs_btree *btree,
        node = (struct nilfs_btree_node *)bh->b_data;
        key = nilfs_btree_node_get_key(node, 0);
        level = nilfs_btree_node_get_level(node);
+       if (level < NILFS_BTREE_LEVEL_NODE_MIN ||
+           level >= NILFS_BTREE_LEVEL_MAX) {
+               dump_stack();
+               printk(KERN_WARNING
+                      "%s: invalid btree level: %d (key=%llu, ino=%lu, "
+                      "blocknr=%llu)\n",
+                      __func__, level, (unsigned long long)key,
+                      NILFS_BMAP_I(&btree->bt_bmap)->vfs_inode.i_ino,
+                      (unsigned long long)bh->b_blocknr);
+               return;
+       }
+
        list_for_each(head, &lists[level]) {
                cbh = list_entry(head, struct buffer_head, b_assoc_buffers);
                cnode = (struct nilfs_btree_node *)cbh->b_data;