Commit 2eb42967 authored by Linus Torvalds's avatar Linus Torvalds

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
parents a6c072c7 510193a2
...@@ -718,8 +718,8 @@ static int parse_hw_handler(struct dm_arg_set *as, struct multipath *m) ...@@ -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;
......
...@@ -279,8 +279,10 @@ static void __cell_release(struct cell *cell, struct bio_list *inmates) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment