diff options
author | Joe Thornber <ejt@redhat.com> | 2013-12-04 16:58:19 -0500 |
---|---|---|
committer | Mike Snitzer <snitzer@redhat.com> | 2013-12-10 16:35:13 -0500 |
commit | 9b7aaa64f96f7ca280d75326fca42f42017b89ef (patch) | |
tree | a0028aeb56bc229e9bc7b1dfcecbb3f03d213131 /drivers/md/dm-thin.c | |
parent | 5383ef3a929a1366e2ced45cd6d74be7aa2a2281 (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.c | 12 |
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; |