Commit 583024d2 authored by Mike Snitzer's avatar Mike Snitzer

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: default avatarMike Snitzer <snitzer@redhat.com>
Acked-by: default avatarJoe Thornber <ejt@redhat.com>
parent ffcc3936
...@@ -292,6 +292,8 @@ struct thin_c { ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment