mirror of
https://github.com/adulau/aha.git
synced 2025-01-01 13:46:24 +00:00
dm raid1: fix leakage
Add missing 'dm_io_client_destroy' to alloc_context error path. Reorganize mirror constructor error path in order to prevent workqueue leakage. Signed-off-by: Dmitry Monakhov <dmonakhov@openvz.org> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
This commit is contained in:
parent
815f9e3270
commit
a72cf737e0
1 changed files with 15 additions and 13 deletions
|
@ -974,6 +974,7 @@ static struct mirror_set *alloc_context(unsigned int nr_mirrors,
|
||||||
|
|
||||||
if (rh_init(&ms->rh, ms, dl, region_size, ms->nr_regions)) {
|
if (rh_init(&ms->rh, ms, dl, region_size, ms->nr_regions)) {
|
||||||
ti->error = "Error creating dirty region hash";
|
ti->error = "Error creating dirty region hash";
|
||||||
|
dm_io_client_destroy(ms->io_client);
|
||||||
kfree(ms);
|
kfree(ms);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
@ -1163,16 +1164,14 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
||||||
ms->kmirrord_wq = create_singlethread_workqueue("kmirrord");
|
ms->kmirrord_wq = create_singlethread_workqueue("kmirrord");
|
||||||
if (!ms->kmirrord_wq) {
|
if (!ms->kmirrord_wq) {
|
||||||
DMERR("couldn't start kmirrord");
|
DMERR("couldn't start kmirrord");
|
||||||
free_context(ms, ti, m);
|
r = -ENOMEM;
|
||||||
return -ENOMEM;
|
goto err_free_context;
|
||||||
}
|
}
|
||||||
INIT_WORK(&ms->kmirrord_work, do_mirror);
|
INIT_WORK(&ms->kmirrord_work, do_mirror);
|
||||||
|
|
||||||
r = parse_features(ms, argc, argv, &args_used);
|
r = parse_features(ms, argc, argv, &args_used);
|
||||||
if (r) {
|
if (r)
|
||||||
free_context(ms, ti, ms->nr_mirrors);
|
goto err_destroy_wq;
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
argv += args_used;
|
argv += args_used;
|
||||||
argc -= args_used;
|
argc -= args_used;
|
||||||
|
@ -1188,19 +1187,22 @@ static int mirror_ctr(struct dm_target *ti, unsigned int argc, char **argv)
|
||||||
|
|
||||||
if (argc) {
|
if (argc) {
|
||||||
ti->error = "Too many mirror arguments";
|
ti->error = "Too many mirror arguments";
|
||||||
free_context(ms, ti, ms->nr_mirrors);
|
r = -EINVAL;
|
||||||
return -EINVAL;
|
goto err_destroy_wq;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = kcopyd_client_create(DM_IO_PAGES, &ms->kcopyd_client);
|
r = kcopyd_client_create(DM_IO_PAGES, &ms->kcopyd_client);
|
||||||
if (r) {
|
if (r)
|
||||||
destroy_workqueue(ms->kmirrord_wq);
|
goto err_destroy_wq;
|
||||||
free_context(ms, ti, ms->nr_mirrors);
|
|
||||||
return r;
|
|
||||||
}
|
|
||||||
|
|
||||||
wake(ms);
|
wake(ms);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
err_destroy_wq:
|
||||||
|
destroy_workqueue(ms->kmirrord_wq);
|
||||||
|
err_free_context:
|
||||||
|
free_context(ms, ti, ms->nr_mirrors);
|
||||||
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mirror_dtr(struct dm_target *ti)
|
static void mirror_dtr(struct dm_target *ti)
|
||||||
|
|
Loading…
Reference in a new issue