dm thin: fix deadlock in __requeue_bio_list

The spin lock in requeue_io() was held for too long, allowing deadlock.
Don't worry, due to other issues addressed in the following "dm thin:
fix noflush suspend IO queueing" commit, this code was never called.

Fix this by taking the spin lock for a much shorter period of time.

Signed-off-by: Joe Thornber <ejt@redhat.com>
Signed-off-by: Mike Snitzer <snitzer@redhat.com>

authored by

Joe Thornber and committed by
Mike Snitzer
18adc577 3e1a0699

+7 -6
+7 -6
drivers/md/dm-thin.c
··· 369 369 struct dm_thin_new_mapping *overwrite_mapping; 370 370 }; 371 371 372 - static void __requeue_bio_list(struct thin_c *tc, struct bio_list *master) 372 + static void requeue_bio_list(struct thin_c *tc, struct bio_list *master) 373 373 { 374 374 struct bio *bio; 375 375 struct bio_list bios; 376 + unsigned long flags; 376 377 377 378 bio_list_init(&bios); 379 + 380 + spin_lock_irqsave(&tc->pool->lock, flags); 378 381 bio_list_merge(&bios, master); 379 382 bio_list_init(master); 383 + spin_unlock_irqrestore(&tc->pool->lock, flags); 380 384 381 385 while ((bio = bio_list_pop(&bios))) { 382 386 struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook)); ··· 395 391 static void requeue_io(struct thin_c *tc) 396 392 { 397 393 struct pool *pool = tc->pool; 398 - unsigned long flags; 399 394 400 - spin_lock_irqsave(&pool->lock, flags); 401 - __requeue_bio_list(tc, &pool->deferred_bios); 402 - __requeue_bio_list(tc, &pool->retry_on_resume_list); 403 - spin_unlock_irqrestore(&pool->lock, flags); 395 + requeue_bio_list(tc, &pool->deferred_bios); 396 + requeue_bio_list(tc, &pool->retry_on_resume_list); 404 397 } 405 398 406 399 static void error_retry_list(struct pool *pool)