Skip to content

Commit

Permalink
btrfs: raid56: avoid double freeing for rbio if full_stripe_write() f…
Browse files Browse the repository at this point in the history
…ailed

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: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
  • Loading branch information
adam900710 authored and kdave committed Oct 24, 2022
1 parent f15fb2c commit ab4c54c
Showing 1 changed file with 7 additions and 5 deletions.
12 changes: 7 additions & 5 deletions fs/btrfs/raid56.c
Original file line number Diff line number Diff line change
Expand Up @@ -1632,10 +1632,8 @@ static int full_stripe_write(struct btrfs_raid_bio *rbio)
int ret;

ret = alloc_rbio_parity_pages(rbio);
if (ret) {
__free_raid_bio(rbio);
if (ret)
return ret;
}

ret = lock_stripe_add(rbio);
if (ret == 0)
Expand Down Expand Up @@ -1823,8 +1821,10 @@ void raid56_parity_write(struct bio *bio, struct btrfs_io_context *bioc)
*/
if (rbio_is_full(rbio)) {
ret = full_stripe_write(rbio);
if (ret)
if (ret) {
__free_raid_bio(rbio);
goto fail;
}
return;
}

Expand All @@ -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);
} else {
ret = __raid56_parity_write(rbio);
if (ret)
if (ret) {
__free_raid_bio(rbio);
goto fail;
}
}

return;
Expand Down

0 comments on commit ab4c54c

Please sign in to comment.