| From a3b3756ab5968074429c05ce891a297a25f79d8e Mon Sep 17 00:00:00 2001 |
| From: Theodore Ts'o <tytso@mit.edu> |
| Date: Sat, 14 Nov 2009 08:19:05 -0500 |
| Subject: [PATCH 62/85] ext4: plug a buffer_head leak in an error path of ext4_iget() |
| |
| (cherry picked from commit 567f3e9a70d71e5c9be03701b8578be77857293b) |
| |
| One of the invalid error paths in ext4_iget() forgot to brelse() the |
| inode buffer head. Fix it by adding a brelse() in the common error |
| return path, which also simplifies function. |
| |
| Thanks to Andi Kleen <ak@linux.intel.com> reporting the problem. |
| |
| Signed-off-by: "Theodore Ts'o" <tytso@mit.edu> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de> |
| --- |
| fs/ext4/inode.c | 11 +++-------- |
| 1 file changed, 3 insertions(+), 8 deletions(-) |
| |
| --- a/fs/ext4/inode.c |
| +++ b/fs/ext4/inode.c |
| @@ -4771,7 +4771,6 @@ struct inode *ext4_iget(struct super_blo |
| struct ext4_iloc iloc; |
| struct ext4_inode *raw_inode; |
| struct ext4_inode_info *ei; |
| - struct buffer_head *bh; |
| struct inode *inode; |
| long ret; |
| int block; |
| @@ -4783,11 +4782,11 @@ struct inode *ext4_iget(struct super_blo |
| return inode; |
| |
| ei = EXT4_I(inode); |
| + iloc.bh = 0; |
| |
| ret = __ext4_get_inode_loc(inode, &iloc, 0); |
| if (ret < 0) |
| goto bad_inode; |
| - bh = iloc.bh; |
| raw_inode = ext4_raw_inode(&iloc); |
| inode->i_mode = le16_to_cpu(raw_inode->i_mode); |
| inode->i_uid = (uid_t)le16_to_cpu(raw_inode->i_uid_low); |
| @@ -4810,7 +4809,6 @@ struct inode *ext4_iget(struct super_blo |
| if (inode->i_mode == 0 || |
| !(EXT4_SB(inode->i_sb)->s_mount_state & EXT4_ORPHAN_FS)) { |
| /* this inode is deleted */ |
| - brelse(bh); |
| ret = -ESTALE; |
| goto bad_inode; |
| } |
| @@ -4842,7 +4840,6 @@ struct inode *ext4_iget(struct super_blo |
| ei->i_extra_isize = le16_to_cpu(raw_inode->i_extra_isize); |
| if (EXT4_GOOD_OLD_INODE_SIZE + ei->i_extra_isize > |
| EXT4_INODE_SIZE(inode->i_sb)) { |
| - brelse(bh); |
| ret = -EIO; |
| goto bad_inode; |
| } |
| @@ -4895,10 +4892,8 @@ struct inode *ext4_iget(struct super_blo |
| /* Validate block references which are part of inode */ |
| ret = ext4_check_inode_blockref(inode); |
| } |
| - if (ret) { |
| - brelse(bh); |
| + if (ret) |
| goto bad_inode; |
| - } |
| |
| if (S_ISREG(inode->i_mode)) { |
| inode->i_op = &ext4_file_inode_operations; |
| @@ -4926,7 +4921,6 @@ struct inode *ext4_iget(struct super_blo |
| init_special_inode(inode, inode->i_mode, |
| new_decode_dev(le32_to_cpu(raw_inode->i_block[1]))); |
| } else { |
| - brelse(bh); |
| ret = -EIO; |
| ext4_error(inode->i_sb, __func__, |
| "bogus i_mode (%o) for inode=%lu", |
| @@ -4939,6 +4933,7 @@ struct inode *ext4_iget(struct super_blo |
| return inode; |
| |
| bad_inode: |
| + brelse(iloc.bh); |
| iget_failed(inode); |
| return ERR_PTR(ret); |
| } |