diff options
author | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-07-15 11:39:10 +0900 |
---|---|---|
committer | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-07-23 10:02:15 +0900 |
commit | f8e6cc013b896d75d6ce4ec9e168014af1257fd8 (patch) | |
tree | 799258b2cc52207ab98946f3f8ae3466b1b33352 /fs/nilfs2 | |
parent | 7c397a81fe90c0445df2873700d14e82cca5fbc8 (diff) | |
download | op-kernel-dev-f8e6cc013b896d75d6ce4ec9e168014af1257fd8.zip op-kernel-dev-f8e6cc013b896d75d6ce4ec9e168014af1257fd8.tar.gz |
nilfs2: fix buffer head leak in nilfs_btnode_submit_block
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>
Diffstat (limited to 'fs/nilfs2')
-rw-r--r-- | fs/nilfs2/btnode.c | 6 |
1 files changed, 4 insertions, 2 deletions
diff --git a/fs/nilfs2/btnode.c b/fs/nilfs2/btnode.c index 447ce47..0a6834b 100644 --- a/fs/nilfs2/btnode.c +++ b/fs/nilfs2/btnode.c @@ -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; } |