The local bio_list may have pending bios when doing cleanup, it can
end up with memory leak if they don't get free'd.

Signed-off-by: Liu Bo <bo.li....@oracle.com>
---
 fs/btrfs/raid56.c | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/fs/btrfs/raid56.c b/fs/btrfs/raid56.c
index 2cf6ba4..063a2a0 100644
--- a/fs/btrfs/raid56.c
+++ b/fs/btrfs/raid56.c
@@ -1325,6 +1325,9 @@ static noinline void finish_rmw(struct btrfs_raid_bio 
*rbio)
 
 cleanup:
        rbio_orig_end_io(rbio, BLK_STS_IOERR);
+
+       while ((bio = bio_list_pop(&bio_list)))
+               bio_put(bio);
 }
 
 /*
@@ -1580,6 +1583,10 @@ static int raid56_rmw_stripe(struct btrfs_raid_bio *rbio)
 
 cleanup:
        rbio_orig_end_io(rbio, BLK_STS_IOERR);
+
+       while ((bio = bio_list_pop(&bio_list)))
+               bio_put(bio);
+
        return -EIO;
 
 finish:
@@ -2105,6 +2112,10 @@ static int __raid56_parity_recover(struct btrfs_raid_bio 
*rbio)
        if (rbio->operation == BTRFS_RBIO_READ_REBUILD ||
            rbio->operation == BTRFS_RBIO_REBUILD_MISSING)
                rbio_orig_end_io(rbio, BLK_STS_IOERR);
+
+       while ((bio = bio_list_pop(&bio_list)))
+               bio_put(bio);
+
        return -EIO;
 }
 
@@ -2452,6 +2463,9 @@ static noinline void finish_parity_scrub(struct 
btrfs_raid_bio *rbio,
 
 cleanup:
        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)
@@ -2561,12 +2575,12 @@ static void raid56_parity_scrub_stripe(struct 
btrfs_raid_bio *rbio)
        int stripe;
        struct bio *bio;
 
+       bio_list_init(&bio_list);
+
        ret = alloc_rbio_essential_pages(rbio);
        if (ret)
                goto cleanup;
 
-       bio_list_init(&bio_list);
-
        atomic_set(&rbio->error, 0);
        /*
         * build a list of bios to read all the missing parts of this
@@ -2634,6 +2648,10 @@ static void raid56_parity_scrub_stripe(struct 
btrfs_raid_bio *rbio)
 
 cleanup:
        rbio_orig_end_io(rbio, BLK_STS_IOERR);
+
+       while ((bio = bio_list_pop(&bio_list)))
+               bio_put(bio);
+
        return;
 
 finish:
-- 
2.9.4

--
To unsubscribe from this list: send the line "unsubscribe linux-btrfs" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to