dm thin: suspend/resume active thin devices when reloading thin-pool
Before this change it was expected that userspace would first suspend all active thin devices, reload/resize the thin-pool target, then resume all active thin devices. Now the thin-pool suspend/resume will trigger the suspend/resume of all active thins via appropriate calls to dm_internal_suspend and dm_internal_resume. Store the mapped_device for each thin device in struct thin_c to make these calls possible. Signed-off-by: Mike Snitzer <snitzer@redhat.com> Acked-by: Joe Thornber <ejt@redhat.com>
This commit is contained in:
parent
ffcc393641
commit
583024d248
1 changed files with 38 additions and 2 deletions
|
@ -292,6 +292,8 @@ struct thin_c {
|
||||||
|
|
||||||
struct pool *pool;
|
struct pool *pool;
|
||||||
struct dm_thin_device *td;
|
struct dm_thin_device *td;
|
||||||
|
struct mapped_device *thin_md;
|
||||||
|
|
||||||
bool requeue_mode:1;
|
bool requeue_mode:1;
|
||||||
spinlock_t lock;
|
spinlock_t lock;
|
||||||
struct list_head deferred_cells;
|
struct list_head deferred_cells;
|
||||||
|
@ -3113,19 +3115,48 @@ static int pool_preresume(struct dm_target *ti)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pool_suspend_active_thins(struct pool *pool)
|
||||||
|
{
|
||||||
|
struct thin_c *tc;
|
||||||
|
|
||||||
|
/* Suspend all active thin devices */
|
||||||
|
tc = get_first_thin(pool);
|
||||||
|
while (tc) {
|
||||||
|
dm_internal_suspend_noflush(tc->thin_md);
|
||||||
|
tc = get_next_thin(pool, tc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pool_resume_active_thins(struct pool *pool)
|
||||||
|
{
|
||||||
|
struct thin_c *tc;
|
||||||
|
|
||||||
|
/* Resume all active thin devices */
|
||||||
|
tc = get_first_thin(pool);
|
||||||
|
while (tc) {
|
||||||
|
dm_internal_resume(tc->thin_md);
|
||||||
|
tc = get_next_thin(pool, tc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void pool_resume(struct dm_target *ti)
|
static void pool_resume(struct dm_target *ti)
|
||||||
{
|
{
|
||||||
struct pool_c *pt = ti->private;
|
struct pool_c *pt = ti->private;
|
||||||
struct pool *pool = pt->pool;
|
struct pool *pool = pt->pool;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Must requeue active_thins' bios and then resume
|
||||||
|
* active_thins _before_ clearing 'suspend' flag.
|
||||||
|
*/
|
||||||
|
requeue_bios(pool);
|
||||||
|
pool_resume_active_thins(pool);
|
||||||
|
|
||||||
spin_lock_irqsave(&pool->lock, flags);
|
spin_lock_irqsave(&pool->lock, flags);
|
||||||
pool->low_water_triggered = false;
|
pool->low_water_triggered = false;
|
||||||
pool->suspended = false;
|
pool->suspended = false;
|
||||||
spin_unlock_irqrestore(&pool->lock, flags);
|
spin_unlock_irqrestore(&pool->lock, flags);
|
||||||
|
|
||||||
requeue_bios(pool);
|
|
||||||
|
|
||||||
do_waker(&pool->waker.work);
|
do_waker(&pool->waker.work);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3138,6 +3169,8 @@ static void pool_presuspend(struct dm_target *ti)
|
||||||
spin_lock_irqsave(&pool->lock, flags);
|
spin_lock_irqsave(&pool->lock, flags);
|
||||||
pool->suspended = true;
|
pool->suspended = true;
|
||||||
spin_unlock_irqrestore(&pool->lock, flags);
|
spin_unlock_irqrestore(&pool->lock, flags);
|
||||||
|
|
||||||
|
pool_suspend_active_thins(pool);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void pool_presuspend_undo(struct dm_target *ti)
|
static void pool_presuspend_undo(struct dm_target *ti)
|
||||||
|
@ -3146,6 +3179,8 @@ static void pool_presuspend_undo(struct dm_target *ti)
|
||||||
struct pool *pool = pt->pool;
|
struct pool *pool = pt->pool;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
|
pool_resume_active_thins(pool);
|
||||||
|
|
||||||
spin_lock_irqsave(&pool->lock, flags);
|
spin_lock_irqsave(&pool->lock, flags);
|
||||||
pool->suspended = false;
|
pool->suspended = false;
|
||||||
spin_unlock_irqrestore(&pool->lock, flags);
|
spin_unlock_irqrestore(&pool->lock, flags);
|
||||||
|
@ -3703,6 +3738,7 @@ static int thin_ctr(struct dm_target *ti, unsigned argc, char **argv)
|
||||||
r = -ENOMEM;
|
r = -ENOMEM;
|
||||||
goto out_unlock;
|
goto out_unlock;
|
||||||
}
|
}
|
||||||
|
tc->thin_md = dm_table_get_md(ti->table);
|
||||||
spin_lock_init(&tc->lock);
|
spin_lock_init(&tc->lock);
|
||||||
INIT_LIST_HEAD(&tc->deferred_cells);
|
INIT_LIST_HEAD(&tc->deferred_cells);
|
||||||
bio_list_init(&tc->deferred_bio_list);
|
bio_list_init(&tc->deferred_bio_list);
|
||||||
|
|
Loading…
Add table
Reference in a new issue