Commit ab4c54c6 authored by Qu Wenruo's avatar Qu Wenruo Committed by David Sterba

btrfs: raid56: avoid double freeing for rbio if full_stripe_write() failed

Currently if full_stripe_write() failed to allocate the pages for
parity, it will call __free_raid_bio() first, then return -ENOMEM.

But some caller of full_stripe_write() will also call __free_raid_bio()
again, this would cause double freeing.

And it's not a logically sound either, normally we should either free
the memory at the same level where we allocated it, or let endio to
handle everything.

So this patch will solve the double freeing by make
raid56_parity_write() to handle the error and free the rbio.

Just like what we do in raid56_parity_recover().
Signed-off-by: default avatarQu Wenruo <wqu@suse.com>
Signed-off-by: default avatarDavid Sterba <dsterba@suse.com>
parent f15fb2cd
...@@ -1632,10 +1632,8 @@ static int full_stripe_write(struct btrfs_raid_bio *rbio) ...@@ -1632,10 +1632,8 @@ static int full_stripe_write(struct btrfs_raid_bio *rbio)
int ret; int ret;
ret = alloc_rbio_parity_pages(rbio); ret = alloc_rbio_parity_pages(rbio);
if (ret) { if (ret)
__free_raid_bio(rbio);
return ret; return ret;
}
ret = lock_stripe_add(rbio); ret = lock_stripe_add(rbio);
if (ret == 0) if (ret == 0)
...@@ -1823,8 +1821,10 @@ void raid56_parity_write(struct bio *bio, struct btrfs_io_context *bioc) ...@@ -1823,8 +1821,10 @@ void raid56_parity_write(struct bio *bio, struct btrfs_io_context *bioc)
*/ */
if (rbio_is_full(rbio)) { if (rbio_is_full(rbio)) {
ret = full_stripe_write(rbio); ret = full_stripe_write(rbio);
if (ret) if (ret) {
__free_raid_bio(rbio);
goto fail; goto fail;
}
return; return;
} }
...@@ -1838,8 +1838,10 @@ void raid56_parity_write(struct bio *bio, struct btrfs_io_context *bioc) ...@@ -1838,8 +1838,10 @@ void raid56_parity_write(struct bio *bio, struct btrfs_io_context *bioc)
list_add_tail(&rbio->plug_list, &plug->rbio_list); list_add_tail(&rbio->plug_list, &plug->rbio_list);
} else { } else {
ret = __raid56_parity_write(rbio); ret = __raid56_parity_write(rbio);
if (ret) if (ret) {
__free_raid_bio(rbio);
goto fail; goto fail;
}
} }
return; return;
......
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