| From 7e664b3dec431eebf0c5df5ff704d6197634cf35 Mon Sep 17 00:00:00 2001 |
| From: Joe Thornber <ejt@redhat.com> |
| Date: Tue, 7 Jan 2014 15:49:02 +0000 |
| Subject: dm space map metadata: fix extending the space map |
| |
| From: Joe Thornber <ejt@redhat.com> |
| |
| commit 7e664b3dec431eebf0c5df5ff704d6197634cf35 upstream. |
| |
| 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> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| drivers/md/persistent-data/dm-space-map-metadata.c | 18 +++++++++++++----- |
| 1 file changed, 13 insertions(+), 5 deletions(-) |
| |
| --- 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_ |
| * 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; |
| } |
| |