mirror of
https://github.com/torvalds/linux.git
synced 2024-11-11 06:31:49 +00:00
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: Qu Wenruo <wqu@suse.com> Signed-off-by: David Sterba <dsterba@suse.com>
This commit is contained in:
parent
f15fb2cd97
commit
ab4c54c643
@ -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)
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user