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>
This commit is contained in:
parent
3e1a069909
commit
18adc57779
@ -369,14 +369,18 @@ struct dm_thin_endio_hook {
|
|||||||
struct dm_thin_new_mapping *overwrite_mapping;
|
struct dm_thin_new_mapping *overwrite_mapping;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void __requeue_bio_list(struct thin_c *tc, struct bio_list *master)
|
static void requeue_bio_list(struct thin_c *tc, struct bio_list *master)
|
||||||
{
|
{
|
||||||
struct bio *bio;
|
struct bio *bio;
|
||||||
struct bio_list bios;
|
struct bio_list bios;
|
||||||
|
unsigned long flags;
|
||||||
|
|
||||||
bio_list_init(&bios);
|
bio_list_init(&bios);
|
||||||
|
|
||||||
|
spin_lock_irqsave(&tc->pool->lock, flags);
|
||||||
bio_list_merge(&bios, master);
|
bio_list_merge(&bios, master);
|
||||||
bio_list_init(master);
|
bio_list_init(master);
|
||||||
|
spin_unlock_irqrestore(&tc->pool->lock, flags);
|
||||||
|
|
||||||
while ((bio = bio_list_pop(&bios))) {
|
while ((bio = bio_list_pop(&bios))) {
|
||||||
struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook));
|
struct dm_thin_endio_hook *h = dm_per_bio_data(bio, sizeof(struct dm_thin_endio_hook));
|
||||||
@ -391,12 +395,9 @@ static void __requeue_bio_list(struct thin_c *tc, struct bio_list *master)
|
|||||||
static void requeue_io(struct thin_c *tc)
|
static void requeue_io(struct thin_c *tc)
|
||||||
{
|
{
|
||||||
struct pool *pool = tc->pool;
|
struct pool *pool = tc->pool;
|
||||||
unsigned long flags;
|
|
||||||
|
|
||||||
spin_lock_irqsave(&pool->lock, flags);
|
requeue_bio_list(tc, &pool->deferred_bios);
|
||||||
__requeue_bio_list(tc, &pool->deferred_bios);
|
requeue_bio_list(tc, &pool->retry_on_resume_list);
|
||||||
__requeue_bio_list(tc, &pool->retry_on_resume_list);
|
|
||||||
spin_unlock_irqrestore(&pool->lock, flags);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void error_retry_list(struct pool *pool)
|
static void error_retry_list(struct pool *pool)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user