diff options
author | Jing Zhang <zj.barak@gmail.com> | 2010-05-12 00:00:00 -0400 |
---|---|---|
committer | Theodore Ts'o <tytso@mit.edu> | 2010-05-12 00:00:00 -0400 |
commit | b720303df7352d4a7a1f61e467e0a124913c0d41 (patch) | |
tree | d0c102111ed28ced2d3a0dbfed987f9b8ed5db37 /fs/ext4 | |
parent | c26d0bad3d0e951487e5dee36632dd3817f42b10 (diff) |
ext4: fix memory leaks in error path handling of ext4_ext_zeroout()
When EIO occurs after bio is submitted, there is no memory free
operation for bio, which results in memory leakage. And there is also
no check against bio_alloc() for bio.
Acked-by: Dave Kleikamp <shaggy@linux.vnet.ibm.com>
Signed-off-by: Jing Zhang <zj.barak@gmail.com>
Signed-off-by: "Theodore Ts'o" <tytso@mit.edu>
Diffstat (limited to 'fs/ext4')
-rw-r--r-- | fs/ext4/extents.c | 15 |
1 files changed, 8 insertions, 7 deletions
diff --git a/fs/ext4/extents.c b/fs/ext4/extents.c index 236b834b4ca8..228eeaf2dccf 100644 --- a/fs/ext4/extents.c +++ b/fs/ext4/extents.c | |||
@@ -2544,7 +2544,7 @@ static void bi_complete(struct bio *bio, int error) | |||
2544 | /* FIXME!! we need to try to merge to left or right after zero-out */ | 2544 | /* FIXME!! we need to try to merge to left or right after zero-out */ |
2545 | static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex) | 2545 | static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex) |
2546 | { | 2546 | { |
2547 | int ret = -EIO; | 2547 | int ret; |
2548 | struct bio *bio; | 2548 | struct bio *bio; |
2549 | int blkbits, blocksize; | 2549 | int blkbits, blocksize; |
2550 | sector_t ee_pblock; | 2550 | sector_t ee_pblock; |
@@ -2568,6 +2568,9 @@ static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex) | |||
2568 | len = ee_len; | 2568 | len = ee_len; |
2569 | 2569 | ||
2570 | bio = bio_alloc(GFP_NOIO, len); | 2570 | bio = bio_alloc(GFP_NOIO, len); |
2571 | if (!bio) | ||
2572 | return -ENOMEM; | ||
2573 | |||
2571 | bio->bi_sector = ee_pblock; | 2574 | bio->bi_sector = ee_pblock; |
2572 | bio->bi_bdev = inode->i_sb->s_bdev; | 2575 | bio->bi_bdev = inode->i_sb->s_bdev; |
2573 | 2576 | ||
@@ -2595,17 +2598,15 @@ static int ext4_ext_zeroout(struct inode *inode, struct ext4_extent *ex) | |||
2595 | submit_bio(WRITE, bio); | 2598 | submit_bio(WRITE, bio); |
2596 | wait_for_completion(&event); | 2599 | wait_for_completion(&event); |
2597 | 2600 | ||
2598 | if (test_bit(BIO_UPTODATE, &bio->bi_flags)) | 2601 | if (!test_bit(BIO_UPTODATE, &bio->bi_flags)) { |
2599 | ret = 0; | 2602 | bio_put(bio); |
2600 | else { | 2603 | return -EIO; |
2601 | ret = -EIO; | ||
2602 | break; | ||
2603 | } | 2604 | } |
2604 | bio_put(bio); | 2605 | bio_put(bio); |
2605 | ee_len -= done; | 2606 | ee_len -= done; |
2606 | ee_pblock += done << (blkbits - 9); | 2607 | ee_pblock += done << (blkbits - 9); |
2607 | } | 2608 | } |
2608 | return ret; | 2609 | return 0; |
2609 | } | 2610 | } |
2610 | 2611 | ||
2611 | #define EXT4_EXT_ZERO_LEN 7 | 2612 | #define EXT4_EXT_ZERO_LEN 7 |