nilfs2: fix buffer head leak in nilfs_btnode_submit_block
authorRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Thu, 15 Jul 2010 02:39:10 +0000 (11:39 +0900)
committerRyusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
Fri, 23 Jul 2010 01:02:15 +0000 (10:02 +0900)
nilfs_btnode_submit_block() refers to buffer head just before
returning from the function, but it releases the buffer head earlier
than that if nilfs_dat_translate() gets an error.

This has potential for oops in the erroneous case.  This fixes the
issue.

Signed-off-by: Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp>
fs/nilfs2/btnode.c

index 447ce47a3306f6635a0512a8e25580ae93c0620b..0a6834bb278e77aeb44de53ee667c9f476c007aa 100644 (file)
@@ -100,6 +100,7 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
 {
        struct buffer_head *bh;
        struct inode *inode = NILFS_BTNC_I(btnc);
+       struct page *page;
        int err;
 
        bh = nilfs_grab_buffer(inode, btnc, blocknr, 1 << BH_NILFS_Node);
@@ -107,6 +108,7 @@ int nilfs_btnode_submit_block(struct address_space *btnc, __u64 blocknr,
                return -ENOMEM;
 
        err = -EEXIST; /* internal code */
+       page = bh->b_page;
 
        if (buffer_uptodate(bh) || buffer_dirty(bh))
                goto found;
@@ -143,8 +145,8 @@ found:
        *pbh = bh;
 
 out_locked:
-       unlock_page(bh->b_page);
-       page_cache_release(bh->b_page);
+       unlock_page(page);
+       page_cache_release(page);
        return err;
 }