aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Thornber2014-01-07 15:49:02 +0000
committerMike Snitzer2014-01-07 21:05:18 -0500
commit7e664b3dec431eebf0c5df5ff704d6197634cf35 (patch)
tree2537389343636ffa174729b3a75f41080777711f
parent12c91a5c2d2a8e8cc40a9552313e1e7b0a2d9ee3 (diff)
dm space map metadata: fix extending the space map
When extending a metadata space map we should do the first commit whilst still in bootstrap mode -- a mode where all blocks get allocated in the new area. That way the commit overhead is allocated from the newly added space. Otherwise we risk running out of space. With this fix, and the previous commit "dm space map common: make sure new space is used during extend", the following device mapper testsuite test passes: dmtest run --suite thin-provisioning -n /resize_metadata_no_io/ Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com> Cc: stable@vger.kernel.org
-rw-r--r--drivers/md/persistent-data/dm-space-map-metadata.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c
index e93084419068..bfbfe03228c1 100644
--- a/drivers/md/persistent-data/dm-space-map-metadata.c
+++ b/drivers/md/persistent-data/dm-space-map-metadata.c
@@ -608,20 +608,28 @@ static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
* Flick into a mode where all blocks get allocated in the new area.
*/
smm->begin = old_len;
- memcpy(&smm->sm, &bootstrap_ops, sizeof(smm->sm));
+ memcpy(sm, &bootstrap_ops, sizeof(*sm));
/*
* Extend.
*/
r = sm_ll_extend(&smm->ll, extra_blocks);
+ if (r)
+ goto out;
+
+ for (i = old_len; !r && i < smm->begin; i++) {
+ r = sm_ll_inc(&smm->ll, i, &ev);
+ if (r)
+ goto out;
+ }
+ r = sm_metadata_commit(sm);
+
+out:
/*
* Switch back to normal behaviour.
*/
- memcpy(&smm->sm, &ops, sizeof(smm->sm));
- for (i = old_len; !r && i < smm->begin; i++)
- r = sm_ll_inc(&smm->ll, i, &ev);
-
+ memcpy(sm, &ops, sizeof(*sm));
return r;
}