aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/dm-thin.c
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2013-12-04 16:58:19 -0500
committerMike Snitzer <snitzer@redhat.com>2013-12-10 16:35:13 -0500
commit9b7aaa64f96f7ca280d75326fca42f42017b89ef (patch)
treea0028aeb56bc229e9bc7b1dfcecbb3f03d213131 /drivers/md/dm-thin.c
parent5383ef3a929a1366e2ced45cd6d74be7aa2a2281 (diff)
dm thin: allow pool in read-only mode to transition to read-write mode
A thin-pool may be in read-only mode because the pool's data or metadata space was exhausted. To allow for recovery, by adding more space to the pool, we must allow a pool to transition from PM_READ_ONLY to PM_WRITE mode. Otherwise, running out of space will render the pool permanently read-only. Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Cc: stable@vger.kernel.org
Diffstat (limited to 'drivers/md/dm-thin.c')
-rw-r--r--drivers/md/dm-thin.c12
1 files changed, 10 insertions, 2 deletions
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c
index 0d7852e2b275..ee29037ffc2e 100644
--- a/drivers/md/dm-thin.c
+++ b/drivers/md/dm-thin.c
@@ -1425,6 +1425,7 @@ static void set_pool_mode(struct pool *pool, enum pool_mode mode)
1425 break; 1425 break;
1426 1426
1427 case PM_WRITE: 1427 case PM_WRITE:
1428 dm_pool_metadata_read_write(pool->pmd);
1428 pool->process_bio = process_bio; 1429 pool->process_bio = process_bio;
1429 pool->process_discard = process_discard; 1430 pool->process_discard = process_discard;
1430 pool->process_prepared_mapping = process_prepared_mapping; 1431 pool->process_prepared_mapping = process_prepared_mapping;
@@ -1641,12 +1642,19 @@ static int bind_control_target(struct pool *pool, struct dm_target *ti)
1641 struct pool_c *pt = ti->private; 1642 struct pool_c *pt = ti->private;
1642 1643
1643 /* 1644 /*
1644 * We want to make sure that degraded pools are never upgraded. 1645 * We want to make sure that a pool in PM_FAIL mode is never upgraded.
1645 */ 1646 */
1646 enum pool_mode old_mode = pool->pf.mode; 1647 enum pool_mode old_mode = pool->pf.mode;
1647 enum pool_mode new_mode = pt->adjusted_pf.mode; 1648 enum pool_mode new_mode = pt->adjusted_pf.mode;
1648 1649
1649 if (old_mode > new_mode) 1650 /*
1651 * If we were in PM_FAIL mode, rollback of metadata failed. We're
1652 * not going to recover without a thin_repair. So we never let the
1653 * pool move out of the old mode. On the other hand a PM_READ_ONLY
1654 * may have been due to a lack of metadata or data space, and may
1655 * now work (ie. if the underlying devices have been resized).
1656 */
1657 if (old_mode == PM_FAIL)
1650 new_mode = old_mode; 1658 new_mode = old_mode;
1651 1659
1652 pool->ti = ti; 1660 pool->ti = ti;