Move the part of thin_preresume that requeues bios and starts the worker thread into thin_resume. (As the target's a singleton, it can't fail between preresume and resume so works the same with or without the patch.) Remove superfluous irqsave. --- drivers/md/dm-thin.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) Index: linux-3.1-rc9/drivers/md/dm-thin.c =================================================================== --- linux-3.1-rc9.orig/drivers/md/dm-thin.c +++ linux-3.1-rc9/drivers/md/dm-thin.c @@ -1774,16 +1774,12 @@ static void __requeue_bios(struct pool * * calling the resume method individually after userspace has * grown the data device in reaction to a table event. */ -/* - * FIXME Part of this ought to be moved to pool_resume. - */ static int pool_preresume(struct dm_target *ti) { int r; struct pool_c *pt = ti->private; struct pool *pool = pt->pool; dm_block_t data_size, sb_data_size; - unsigned long flags; /* * Take control of the pool object. @@ -1819,15 +1815,21 @@ static int pool_preresume(struct dm_targ } } - spin_lock_irqsave(&pool->lock, flags); + return 0; +} + +static void pool_resume(struct dm_target *ti) +{ + struct pool_c *pt = ti->private; + struct pool *pool = pt->pool; + + spin_lock_irq(&pool->lock); pool->low_water_triggered = 0; pool->no_free_space = 0; __requeue_bios(pool); - spin_unlock_irqrestore(&pool->lock, flags); + spin_unlock_irq(&pool->lock); wake_worker(pool); - - return 0; } static void pool_postsuspend(struct dm_target *ti) @@ -2148,6 +2150,7 @@ static struct target_type pool_target = .map = pool_map, .postsuspend = pool_postsuspend, .preresume = pool_preresume, + .resume = pool_resume, .message = pool_message, .status = pool_status, .merge = pool_merge, @@ -2342,6 +2345,7 @@ static int thin_status(struct dm_target (unsigned long) tc->dev_id); break; } + } return 0; }