diff options
author | Christoph Hellwig <hch@lst.de> | 2021-08-09 09:40:26 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-09-22 12:47:49 +0300 |
commit | 9ff23e9baeab1c3c918b957bb2ef7653d56ded44 (patch) | |
tree | 751e6c5d08ef2fe02fcb3f4d401538de8580ee56 | |
parent | 891ab1769ff1cc40fff0fcea0f4b359f115effde (diff) | |
download | linux-9ff23e9baeab1c3c918b957bb2ef7653d56ded44.tar.xz |
bcache: add proper error unwinding in bcache_device_init
[ Upstream commit 224b0683228c5f332f9cee615d85e75e9a347170 ]
Except for the IDA none of the allocations in bcache_device_init is
unwound on error, fix that.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Coly Li <colyli@suse.de>
Link: https://lore.kernel.org/r/20210809064028.1198327-7-hch@lst.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
-rw-r--r-- | drivers/md/bcache/super.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/drivers/md/bcache/super.c b/drivers/md/bcache/super.c index 7787ec42f81e..2df75db52e91 100644 --- a/drivers/md/bcache/super.c +++ b/drivers/md/bcache/super.c @@ -824,20 +824,20 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size, n = BITS_TO_LONGS(d->nr_stripes) * sizeof(unsigned long); d->full_dirty_stripes = kvzalloc(n, GFP_KERNEL); if (!d->full_dirty_stripes) - return -ENOMEM; + goto out_free_stripe_sectors_dirty; idx = ida_simple_get(&bcache_device_idx, 0, BCACHE_DEVICE_IDX_MAX, GFP_KERNEL); if (idx < 0) - return idx; + goto out_free_full_dirty_stripes; if (bioset_init(&d->bio_split, 4, offsetof(struct bbio, bio), BIOSET_NEED_BVECS|BIOSET_NEED_RESCUER)) - goto err; + goto out_ida_remove; d->disk = alloc_disk(BCACHE_MINORS); if (!d->disk) - goto err; + goto out_bioset_exit; set_capacity(d->disk, sectors); snprintf(d->disk->disk_name, DISK_NAME_LEN, "bcache%i", idx); @@ -872,8 +872,14 @@ static int bcache_device_init(struct bcache_device *d, unsigned int block_size, return 0; -err: +out_bioset_exit: + bioset_exit(&d->bio_split); +out_ida_remove: ida_simple_remove(&bcache_device_idx, idx); +out_free_full_dirty_stripes: + kvfree(d->full_dirty_stripes); +out_free_stripe_sectors_dirty: + kvfree(d->stripe_sectors_dirty); return -ENOMEM; } |