diff options
-rw-r--r-- | drivers/md/dm-thin-metadata.c | 12 | ||||
-rw-r--r-- | drivers/md/dm-thin-metadata.h | 1 | ||||
-rw-r--r-- | drivers/md/dm-thin.c | 54 |
3 files changed, 64 insertions, 3 deletions
diff --git a/drivers/md/dm-thin-metadata.c b/drivers/md/dm-thin-metadata.c index 9452a489ed99..f553ed66603c 100644 --- a/drivers/md/dm-thin-metadata.c +++ b/drivers/md/dm-thin-metadata.c | |||
@@ -1677,6 +1677,18 @@ int dm_pool_resize_data_dev(struct dm_pool_metadata *pmd, dm_block_t new_count) | |||
1677 | return r; | 1677 | return r; |
1678 | } | 1678 | } |
1679 | 1679 | ||
1680 | int dm_pool_resize_metadata_dev(struct dm_pool_metadata *pmd, dm_block_t new_count) | ||
1681 | { | ||
1682 | int r = -EINVAL; | ||
1683 | |||
1684 | down_write(&pmd->root_lock); | ||
1685 | if (!pmd->fail_io) | ||
1686 | r = __resize_space_map(pmd->metadata_sm, new_count); | ||
1687 | up_write(&pmd->root_lock); | ||
1688 | |||
1689 | return r; | ||
1690 | } | ||
1691 | |||
1680 | void dm_pool_metadata_read_only(struct dm_pool_metadata *pmd) | 1692 | void dm_pool_metadata_read_only(struct dm_pool_metadata *pmd) |
1681 | { | 1693 | { |
1682 | down_write(&pmd->root_lock); | 1694 | down_write(&pmd->root_lock); |
diff --git a/drivers/md/dm-thin-metadata.h b/drivers/md/dm-thin-metadata.h index 0cecc3702885..ef8dd709e34e 100644 --- a/drivers/md/dm-thin-metadata.h +++ b/drivers/md/dm-thin-metadata.h | |||
@@ -185,6 +185,7 @@ int dm_pool_get_data_dev_size(struct dm_pool_metadata *pmd, dm_block_t *result); | |||
185 | * blocks would be lost. | 185 | * blocks would be lost. |
186 | */ | 186 | */ |
187 | int dm_pool_resize_data_dev(struct dm_pool_metadata *pmd, dm_block_t new_size); | 187 | int dm_pool_resize_data_dev(struct dm_pool_metadata *pmd, dm_block_t new_size); |
188 | int dm_pool_resize_metadata_dev(struct dm_pool_metadata *pmd, dm_block_t new_size); | ||
188 | 189 | ||
189 | /* | 190 | /* |
190 | * Flicks the underlying block manager into read only mode, so you know | 191 | * Flicks the underlying block manager into read only mode, so you know |
diff --git a/drivers/md/dm-thin.c b/drivers/md/dm-thin.c index ef021b0c8106..f4632f97bd7b 100644 --- a/drivers/md/dm-thin.c +++ b/drivers/md/dm-thin.c | |||
@@ -1923,6 +1923,15 @@ static sector_t get_metadata_dev_size(struct block_device *bdev) | |||
1923 | return metadata_dev_size; | 1923 | return metadata_dev_size; |
1924 | } | 1924 | } |
1925 | 1925 | ||
1926 | static dm_block_t get_metadata_dev_size_in_blocks(struct block_device *bdev) | ||
1927 | { | ||
1928 | sector_t metadata_dev_size = get_metadata_dev_size(bdev); | ||
1929 | |||
1930 | sector_div(metadata_dev_size, THIN_METADATA_BLOCK_SIZE >> SECTOR_SHIFT); | ||
1931 | |||
1932 | return metadata_dev_size; | ||
1933 | } | ||
1934 | |||
1926 | /* | 1935 | /* |
1927 | * thin-pool <metadata dev> <data dev> | 1936 | * thin-pool <metadata dev> <data dev> |
1928 | * <data block size (sectors)> | 1937 | * <data block size (sectors)> |
@@ -2132,6 +2141,41 @@ static int maybe_resize_data_dev(struct dm_target *ti, bool *need_commit) | |||
2132 | return 0; | 2141 | return 0; |
2133 | } | 2142 | } |
2134 | 2143 | ||
2144 | static int maybe_resize_metadata_dev(struct dm_target *ti, bool *need_commit) | ||
2145 | { | ||
2146 | int r; | ||
2147 | struct pool_c *pt = ti->private; | ||
2148 | struct pool *pool = pt->pool; | ||
2149 | dm_block_t metadata_dev_size, sb_metadata_dev_size; | ||
2150 | |||
2151 | *need_commit = false; | ||
2152 | |||
2153 | metadata_dev_size = get_metadata_dev_size(pool->md_dev); | ||
2154 | |||
2155 | r = dm_pool_get_metadata_dev_size(pool->pmd, &sb_metadata_dev_size); | ||
2156 | if (r) { | ||
2157 | DMERR("failed to retrieve data device size"); | ||
2158 | return r; | ||
2159 | } | ||
2160 | |||
2161 | if (metadata_dev_size < sb_metadata_dev_size) { | ||
2162 | DMERR("metadata device (%llu sectors) too small: expected %llu", | ||
2163 | metadata_dev_size, sb_metadata_dev_size); | ||
2164 | return -EINVAL; | ||
2165 | |||
2166 | } else if (metadata_dev_size > sb_metadata_dev_size) { | ||
2167 | r = dm_pool_resize_metadata_dev(pool->pmd, metadata_dev_size); | ||
2168 | if (r) { | ||
2169 | DMERR("failed to resize metadata device"); | ||
2170 | return r; | ||
2171 | } | ||
2172 | |||
2173 | *need_commit = true; | ||
2174 | } | ||
2175 | |||
2176 | return 0; | ||
2177 | } | ||
2178 | |||
2135 | /* | 2179 | /* |
2136 | * Retrieves the number of blocks of the data device from | 2180 | * Retrieves the number of blocks of the data device from |
2137 | * the superblock and compares it to the actual device size, | 2181 | * the superblock and compares it to the actual device size, |
@@ -2146,7 +2190,7 @@ static int maybe_resize_data_dev(struct dm_target *ti, bool *need_commit) | |||
2146 | static int pool_preresume(struct dm_target *ti) | 2190 | static int pool_preresume(struct dm_target *ti) |
2147 | { | 2191 | { |
2148 | int r; | 2192 | int r; |
2149 | bool need_commit1; | 2193 | bool need_commit1, need_commit2; |
2150 | struct pool_c *pt = ti->private; | 2194 | struct pool_c *pt = ti->private; |
2151 | struct pool *pool = pt->pool; | 2195 | struct pool *pool = pt->pool; |
2152 | 2196 | ||
@@ -2161,7 +2205,11 @@ static int pool_preresume(struct dm_target *ti) | |||
2161 | if (r) | 2205 | if (r) |
2162 | return r; | 2206 | return r; |
2163 | 2207 | ||
2164 | if (need_commit1) | 2208 | r = maybe_resize_metadata_dev(ti, &need_commit2); |
2209 | if (r) | ||
2210 | return r; | ||
2211 | |||
2212 | if (need_commit1 || need_commit2) | ||
2165 | (void) commit_or_fallback(pool); | 2213 | (void) commit_or_fallback(pool); |
2166 | 2214 | ||
2167 | return 0; | 2215 | return 0; |
@@ -2583,7 +2631,7 @@ static struct target_type pool_target = { | |||
2583 | .name = "thin-pool", | 2631 | .name = "thin-pool", |
2584 | .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE | | 2632 | .features = DM_TARGET_SINGLETON | DM_TARGET_ALWAYS_WRITEABLE | |
2585 | DM_TARGET_IMMUTABLE, | 2633 | DM_TARGET_IMMUTABLE, |
2586 | .version = {1, 7, 0}, | 2634 | .version = {1, 8, 0}, |
2587 | .module = THIS_MODULE, | 2635 | .module = THIS_MODULE, |
2588 | .ctr = pool_ctr, | 2636 | .ctr = pool_ctr, |
2589 | .dtr = pool_dtr, | 2637 | .dtr = pool_dtr, |