aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-thin.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/dm-thin.c')
-rw-r--r--drivers/md/dm-thin.c16
1 files changed, 12 insertions, 4 deletions
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 213ae32a0fc4..2fd87b544a93 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -279,8 +279,10 @@ static void __cell_release(struct cell *cell, struct bio_list *inmates)
279 279
280 hlist_del(&cell->list); 280 hlist_del(&cell->list);
281 281
282 bio_list_add(inmates, cell->holder); 282 if (inmates) {
283 bio_list_merge(inmates, &cell->bios); 283 bio_list_add(inmates, cell->holder);
284 bio_list_merge(inmates, &cell->bios);
285 }
284 286
285 mempool_free(cell, prison->cell_pool); 287 mempool_free(cell, prison->cell_pool);
286} 288}
@@ -303,9 +305,10 @@ static void cell_release(struct cell *cell, struct bio_list *bios)
303 */ 305 */
304static void __cell_release_singleton(struct cell *cell, struct bio *bio) 306static void __cell_release_singleton(struct cell *cell, struct bio *bio)
305{ 307{
306 hlist_del(&cell->list);
307 BUG_ON(cell->holder != bio); 308 BUG_ON(cell->holder != bio);
308 BUG_ON(!bio_list_empty(&cell->bios)); 309 BUG_ON(!bio_list_empty(&cell->bios));
310
311 __cell_release(cell, NULL);
309} 312}
310 313
311static void cell_release_singleton(struct cell *cell, struct bio *bio) 314static void cell_release_singleton(struct cell *cell, struct bio *bio)
@@ -1177,6 +1180,7 @@ static void no_space(struct cell *cell)
1177static void process_discard(struct thin_c *tc, struct bio *bio) 1180static void process_discard(struct thin_c *tc, struct bio *bio)
1178{ 1181{
1179 int r; 1182 int r;
1183 unsigned long flags;
1180 struct pool *pool = tc->pool; 1184 struct pool *pool = tc->pool;
1181 struct cell *cell, *cell2; 1185 struct cell *cell, *cell2;
1182 struct cell_key key, key2; 1186 struct cell_key key, key2;
@@ -1218,7 +1222,9 @@ static void process_discard(struct thin_c *tc, struct bio *bio)
1218 m->bio = bio; 1222 m->bio = bio;
1219 1223
1220 if (!ds_add_work(&pool->all_io_ds, &m->list)) { 1224 if (!ds_add_work(&pool->all_io_ds, &m->list)) {
1225 spin_lock_irqsave(&pool->lock, flags);
1221 list_add(&m->list, &pool->prepared_discards); 1226 list_add(&m->list, &pool->prepared_discards);
1227 spin_unlock_irqrestore(&pool->lock, flags);
1222 wake_worker(pool); 1228 wake_worker(pool);
1223 } 1229 }
1224 } else { 1230 } else {
@@ -2626,8 +2632,10 @@ static int thin_endio(struct dm_target *ti,
2626 if (h->all_io_entry) { 2632 if (h->all_io_entry) {
2627 INIT_LIST_HEAD(&work); 2633 INIT_LIST_HEAD(&work);
2628 ds_dec(h->all_io_entry, &work); 2634 ds_dec(h->all_io_entry, &work);
2635 spin_lock_irqsave(&pool->lock, flags);
2629 list_for_each_entry_safe(m, tmp, &work, list) 2636 list_for_each_entry_safe(m, tmp, &work, list)
2630 list_add(&m->list, &pool->prepared_discards); 2637 list_add(&m->list, &pool->prepared_discards);
2638 spin_unlock_irqrestore(&pool->lock, flags);
2631 } 2639 }
2632 2640
2633 mempool_free(h, pool->endio_hook_pool); 2641 mempool_free(h, pool->endio_hook_pool);
@@ -2759,6 +2767,6 @@ static void dm_thin_exit(void)
2759module_init(dm_thin_init); 2767module_init(dm_thin_init);
2760module_exit(dm_thin_exit); 2768module_exit(dm_thin_exit);
2761 2769
2762MODULE_DESCRIPTION(DM_NAME "device-mapper thin provisioning target"); 2770MODULE_DESCRIPTION(DM_NAME " thin provisioning target");
2763MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>"); 2771MODULE_AUTHOR("Joe Thornber <dm-devel@redhat.com>");
2764MODULE_LICENSE("GPL"); 2772MODULE_LICENSE("GPL");