Commit 785884fc authored by Liu Bo's avatar Liu Bo Committed by David Sterba

Btrfs: fix memory leak in raid56

The local bio_list may have pending bios when doing cleanup, it can
end up with memory leak if they don't get freed.
Signed-off-by: default avatarLiu Bo <bo.li.liu@oracle.com>
Reviewed-by: default avatarDavid Sterba <dsterba@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent 315d8e98
...@@ -1326,6 +1326,9 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio) ...@@ -1326,6 +1326,9 @@ static noinline void finish_rmw(struct btrfs_raid_bio *rbio)
cleanup: cleanup:
rbio_orig_end_io(rbio, BLK_STS_IOERR); rbio_orig_end_io(rbio, BLK_STS_IOERR);
while ((bio = bio_list_pop(&bio_list)))
bio_put(bio);
} }
/* /*
...@@ -1582,6 +1585,10 @@ static int raid56_rmw_stripe(struct btrfs_raid_bio *rbio) ...@@ -1582,6 +1585,10 @@ static int raid56_rmw_stripe(struct btrfs_raid_bio *rbio)
cleanup: cleanup:
rbio_orig_end_io(rbio, BLK_STS_IOERR); rbio_orig_end_io(rbio, BLK_STS_IOERR);
while ((bio = bio_list_pop(&bio_list)))
bio_put(bio);
return -EIO; return -EIO;
finish: finish:
...@@ -2107,6 +2114,10 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio) ...@@ -2107,6 +2114,10 @@ static int __raid56_parity_recover(struct btrfs_raid_bio *rbio)
if (rbio->operation == BTRFS_RBIO_READ_REBUILD || if (rbio->operation == BTRFS_RBIO_READ_REBUILD ||
rbio->operation == BTRFS_RBIO_REBUILD_MISSING) rbio->operation == BTRFS_RBIO_REBUILD_MISSING)
rbio_orig_end_io(rbio, BLK_STS_IOERR); rbio_orig_end_io(rbio, BLK_STS_IOERR);
while ((bio = bio_list_pop(&bio_list)))
bio_put(bio);
return -EIO; return -EIO;
} }
...@@ -2460,6 +2471,9 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio, ...@@ -2460,6 +2471,9 @@ static noinline void finish_parity_scrub(struct btrfs_raid_bio *rbio,
cleanup: cleanup:
rbio_orig_end_io(rbio, BLK_STS_IOERR); rbio_orig_end_io(rbio, BLK_STS_IOERR);
while ((bio = bio_list_pop(&bio_list)))
bio_put(bio);
} }
static inline int is_data_stripe(struct btrfs_raid_bio *rbio, int stripe) static inline int is_data_stripe(struct btrfs_raid_bio *rbio, int stripe)
...@@ -2569,12 +2583,12 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio) ...@@ -2569,12 +2583,12 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio)
int stripe; int stripe;
struct bio *bio; struct bio *bio;
bio_list_init(&bio_list);
ret = alloc_rbio_essential_pages(rbio); ret = alloc_rbio_essential_pages(rbio);
if (ret) if (ret)
goto cleanup; goto cleanup;
bio_list_init(&bio_list);
atomic_set(&rbio->error, 0); atomic_set(&rbio->error, 0);
/* /*
* build a list of bios to read all the missing parts of this * build a list of bios to read all the missing parts of this
...@@ -2642,6 +2656,10 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio) ...@@ -2642,6 +2656,10 @@ static void raid56_parity_scrub_stripe(struct btrfs_raid_bio *rbio)
cleanup: cleanup:
rbio_orig_end_io(rbio, BLK_STS_IOERR); rbio_orig_end_io(rbio, BLK_STS_IOERR);
while ((bio = bio_list_pop(&bio_list)))
bio_put(bio);
return; return;
finish: finish:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment