Device-mapper fixes for 3.4.

Fix a couple of serious memory leaks in device-mapper thin provisioning
 and tidy its MODULE_DESCRIPTION.
 
 Mitigate occasional reported hangs associated with multipath scsi_dh
 module loading.
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.11 (GNU/Linux)
 
 iQIcBAABAgAGBQJPrbVzAAoJEK2W1qbAHj1ndO4QAKYKAtAhAOEQ7+26RTz/7vEn
 1Rp7D+1f8PBK3/CkbFhOjknGyRO6MGuWOrP6y2WkHcYR/wq1FKxqtOmut5bIwVuf
 s3jyZ+sg07ev8tgj1s4PKc7HPkWGNET+xHTAlpsjzIMSjSbUaOijgF/yOqMhgVuH
 SucXgfZytDtCACl3GR0PVOe+1xtXRiCi7drzR66zA5/2bIACr/NITfvtfHyQUT6v
 Js8Rm6uTmSjvX4l4rBICz5szgXUFAF7Eqb3msWEovdQkgrt5bQVvLsQAybbmHTCn
 v1hH8xE6FNYJil5e5wr2sG53FqiYLXcMFrRRSm6QUgV2FIGqCpkrF1SdPJHkXPGH
 ndYtfblCEHbBGIFYpmpETlZ94k8Xi8RV6ah/+1am8MqP2nLZb02OSHAkhPziQnTS
 qkthM/Mmo70dZESvBEsbWMpnannoiKOMHfAx5BUwah6BbRIdikNXj2j5Kziy6sl0
 zQ0aOHdlVrYDH1oqc+pV7MUHmd9ftvkCQfswQUxaQz786IXeB5x/TxtVt+AOdmxa
 cTsS/jC88b3sU7QZlx48Zkmwb8ryn4BqHF2rtwok8wYHyViS3OmhyrKL5X9mESro
 hGSNM6qurko7q9VT+UthgeyVb42cHmxjbuouCoLadxYP7SSmeB7tkOk/vCB3Wx86
 1egUWKacy75JTNEemywy
 =jmbP
 -----END PGP SIGNATURE-----

Merge tag 'dm-3.4-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-dm

Pull device-mapper fixes from Alasdair G Kergon:
 "Fix a couple of serious memory leaks in device-mapper thin
  provisioning and tidy its MODULE_DESCRIPTION.

  Mitigate occasional reported hangs associated with multipath scsi_dh
  module loading."

* tag 'dm-3.4-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-dm:
  dm mpath: check if scsi_dh module already loaded before trying to load
  dm thin: correct module description
  dm thin: fix unprotected use of prepared_discards list
  dm thin: reinstate missing mempool_free in cell_release_singleton
This commit is contained in:
Linus Torvalds 2012-05-12 12:56:08 -07:00
commit 2eb429671a
2 changed files with 14 additions and 6 deletions

View File

@ -718,8 +718,8 @@ static int parse_hw_handler(struct dm_arg_set *as, struct multipath *m)
return 0; return 0;
m->hw_handler_name = kstrdup(dm_shift_arg(as), GFP_KERNEL); m->hw_handler_name = kstrdup(dm_shift_arg(as), GFP_KERNEL);
request_module("scsi_dh_%s", m->hw_handler_name); if (!try_then_request_module(scsi_dh_handler_exist(m->hw_handler_name),
if (scsi_dh_handler_exist(m->hw_handler_name) == 0) { "scsi_dh_%s", m->hw_handler_name)) {
ti->error = "unknown hardware handler type"; ti->error = "unknown hardware handler type";
ret = -EINVAL; ret = -EINVAL;
goto fail; goto fail;

View File

@ -279,8 +279,10 @@ static void __cell_release(struct cell *cell, struct bio_list *inmates)
hlist_del(&cell->list); hlist_del(&cell->list);
bio_list_add(inmates, cell->holder); if (inmates) {
bio_list_merge(inmates, &cell->bios); bio_list_add(inmates, cell->holder);
bio_list_merge(inmates, &cell->bios);
}
mempool_free(cell, prison->cell_pool); mempool_free(cell, prison->cell_pool);
} }
@ -303,9 +305,10 @@ static void cell_release(struct cell *cell, struct bio_list *bios)
*/ */
static void __cell_release_singleton(struct cell *cell, struct bio *bio) static void __cell_release_singleton(struct cell *cell, struct bio *bio)
{ {
hlist_del(&cell->list);
BUG_ON(cell->holder != bio); BUG_ON(cell->holder != bio);
BUG_ON(!bio_list_empty(&cell->bios)); BUG_ON(!bio_list_empty(&cell->bios));
__cell_release(cell, NULL);
} }
static void cell_release_singleton(struct cell *cell, struct bio *bio) static void cell_release_singleton(struct cell *cell, struct bio *bio)
@ -1177,6 +1180,7 @@ static void no_space(struct cell *cell)
static void process_discard(struct thin_c *tc, struct bio *bio) static void process_discard(struct thin_c *tc, struct bio *bio)
{ {
int r; int r;
unsigned long flags;
struct pool *pool = tc->pool; struct pool *pool = tc->pool;
struct cell *cell, *cell2; struct cell *cell, *cell2;
struct cell_key key, key2; struct cell_key key, key2;
@ -1218,7 +1222,9 @@ static void process_discard(struct thin_c *tc, struct bio *bio)
m->bio = bio; m->bio = bio;
if (!ds_add_work(&pool->all_io_ds, &m->list)) { if (!ds_add_work(&pool->all_io_ds, &m->list)) {
spin_lock_irqsave(&pool->lock, flags);
list_add(&m->list, &pool->prepared_discards); list_add(&m->list, &pool->prepared_discards);
spin_unlock_irqrestore(&pool->lock, flags);
wake_worker(pool); wake_worker(pool);
} }
} else { } else {
@ -2626,8 +2632,10 @@ static int thin_endio(struct dm_target *ti,
if (h->all_io_entry) { if (h->all_io_entry) {
INIT_LIST_HEAD(&work); INIT_LIST_HEAD(&work);
ds_dec(h->all_io_entry, &work); ds_dec(h->all_io_entry, &work);
spin_lock_irqsave(&pool->lock, flags);
list_for_each_entry_safe(m, tmp, &work, list) list_for_each_entry_safe(m, tmp, &work, list)
list_add(&m->list, &pool->prepared_discards); list_add(&m->list, &pool->prepared_discards);
spin_unlock_irqrestore(&pool->lock, flags);
} }
mempool_free(h, pool->endio_hook_pool); mempool_free(h, pool->endio_hook_pool);
@ -2759,6 +2767,6 @@ static void dm_thin_exit(void)
module_init(dm_thin_init); module_init(dm_thin_init);
module_exit(dm_thin_exit); module_exit(dm_thin_exit);
MODULE_DESCRIPTION(DM_NAME "device-mapper thin provisioning target"); MODULE_DESCRIPTION(DM_NAME " thin provisioning target");
MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>"); MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>");
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");