Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b7aaa64 authored by Joe Thornber's avatar Joe Thornber Committed by Mike Snitzer
Browse files

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: default avatarJoe Thornber <ejt@redhat.com>
Signed-off-by: default avatarMike Snitzer <snitzer@redhat.com>
Cc: stable@vger.kernel.org
parent 5383ef3a
Loading
Loading
Loading
Loading
+8 −0
Original line number Diff line number Diff line
@@ -1697,6 +1697,14 @@ void dm_pool_metadata_read_only(struct dm_pool_metadata *pmd)
	up_write(&pmd->root_lock);
}

void dm_pool_metadata_read_write(struct dm_pool_metadata *pmd)
{
	down_write(&pmd->root_lock);
	pmd->read_only = false;
	dm_bm_set_read_write(pmd->bm);
	up_write(&pmd->root_lock);
}

int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd,
					dm_block_t threshold,
					dm_sm_threshold_fn fn,
+1 −0
Original line number Diff line number Diff line
@@ -193,6 +193,7 @@ int dm_pool_resize_metadata_dev(struct dm_pool_metadata *pmd, dm_block_t new_siz
 * that nothing is changing.
 */
void dm_pool_metadata_read_only(struct dm_pool_metadata *pmd);
void dm_pool_metadata_read_write(struct dm_pool_metadata *pmd);

int dm_pool_register_metadata_threshold(struct dm_pool_metadata *pmd,
					dm_block_t threshold,
+10 −2
Original line number Diff line number Diff line
@@ -1425,6 +1425,7 @@ static void set_pool_mode(struct pool *pool, enum pool_mode mode)
		break;

	case PM_WRITE:
		dm_pool_metadata_read_write(pool->pmd);
		pool->process_bio = process_bio;
		pool->process_discard = process_discard;
		pool->process_prepared_mapping = process_prepared_mapping;
@@ -1641,12 +1642,19 @@ static int bind_control_target(struct pool *pool, struct dm_target *ti)
	struct pool_c *pt = ti->private;

	/*
	 * We want to make sure that degraded pools are never upgraded.
	 * We want to make sure that a pool in PM_FAIL mode is never upgraded.
	 */
	enum pool_mode old_mode = pool->pf.mode;
	enum pool_mode new_mode = pt->adjusted_pf.mode;

	if (old_mode > new_mode)
	/*
	 * If we were in PM_FAIL mode, rollback of metadata failed.  We're
	 * not going to recover without a thin_repair.  So we never let the
	 * pool move out of the old mode.  On the other hand a PM_READ_ONLY
	 * may have been due to a lack of metadata or data space, and may
	 * now work (ie. if the underlying devices have been resized).
	 */
	if (old_mode == PM_FAIL)
		new_mode = old_mode;

	pool->ti = ti;
+6 −0
Original line number Diff line number Diff line
@@ -626,6 +626,12 @@ void dm_bm_set_read_only(struct dm_block_manager *bm)
}
EXPORT_SYMBOL_GPL(dm_bm_set_read_only);

void dm_bm_set_read_write(struct dm_block_manager *bm)
{
	bm->read_only = false;
}
EXPORT_SYMBOL_GPL(dm_bm_set_read_write);

u32 dm_bm_checksum(const void *data, size_t len, u32 init_xor)
{
	return crc32c(~(u32) 0, data, len) ^ init_xor;
+4 −3
Original line number Diff line number Diff line
@@ -109,7 +109,7 @@ int dm_bm_flush_and_unlock(struct dm_block_manager *bm,
			   struct dm_block *superblock);

/*
  * Request data be prefetched into the cache.
 * Request data is prefetched into the cache.
 */
void dm_bm_prefetch(struct dm_block_manager *bm, dm_block_t b);

@@ -125,6 +125,7 @@ void dm_bm_prefetch(struct dm_block_manager *bm, dm_block_t b);
 * be returned if you do.
 */
void dm_bm_set_read_only(struct dm_block_manager *bm);
void dm_bm_set_read_write(struct dm_block_manager *bm);

u32 dm_bm_checksum(const void *data, size_t len, u32 init_xor);