diff options
author | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-07-14 22:39:10 -0400 |
---|---|---|
committer | Ryusuke Konishi <konishi.ryusuke@lab.ntt.co.jp> | 2010-07-22 21:02:15 -0400 |
commit | f8e6cc013b896d75d6ce4ec9e168014af1257fd8 (patch) | |
tree | 799258b2cc52207ab98946f3f8ae3466b1b33352 /fs/nilfs2/btnode.c | |
parent | 7c397a81fe90c0445df2873700d14e82cca5fbc8 (diff) |
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/btnode.c')
-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 447ce47a3306..0a6834bb278e 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, | |||
100 | { | 100 | { |
101 | struct buffer_head *bh; | 101 | struct buffer_head *bh; |
102 | struct inode *inode = NILFS_BTNC_I(btnc); | 102 | struct inode *inode = NILFS_BTNC_I(btnc); |
103 | struct page *page; | ||
103 | int err; | 104 | int err; |
104 | 105 | ||
105 | bh = nilfs_grab_buffer(inode, btnc, blocknr, 1 << BH_NILFS_Node); | 106 | 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, | |||
107 | return -ENOMEM; | 108 | return -ENOMEM; |
108 | 109 | ||
109 | err = -EEXIST; /* internal code */ | 110 | err = -EEXIST; /* internal code */ |
111 | page = bh->b_page; | ||
110 | 112 | ||
111 | if (buffer_uptodate(bh) || buffer_dirty(bh)) | 113 | if (buffer_uptodate(bh) || buffer_dirty(bh)) |
112 | goto found; | 114 | goto found; |
@@ -143,8 +145,8 @@ found: | |||
143 | *pbh = bh; | 145 | *pbh = bh; |
144 | 146 | ||
145 | out_locked: | 147 | out_locked: |
146 | unlock_page(bh->b_page); | 148 | unlock_page(page); |
147 | page_cache_release(bh->b_page); | 149 | page_cache_release(page); |
148 | return err; | 150 | return err; |
149 | } | 151 | } |
150 | 152 | ||