aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2013-05-10 09:37:19 -0400
committerAlasdair G Kergon <agk@redhat.com>2013-05-10 09:37:19 -0400
commit1921c56d95c4ac92b359ad44ffbc1e9a36060b29 (patch)
tree86d0e844addb338759bf9bae0c8253c7dcb34921
parent5d0db96d13a4e2cd22b52494fb19ce5a9c8b8d90 (diff)
dm persistent data: support space map resizing
Support extending a dm persistent data metadata space map. The extend itself is implemented by switching back to the boostrap allocator and pointing to the new space. The extra bitmap indexes are then allocated from the new space, and finally we switch back to the proper space map ops and tweak the reference counts. Signed-off-by: Joe Thornber <ejt@redhat.com> Signed-off-by: Alasdair G Kergon <agk@redhat.com>
-rw-r--r--drivers/md/persistent-data/dm-space-map-metadata.c38
1 files changed, 32 insertions, 6 deletions
diff --git a/drivers/md/persistent-data/dm-space-map-metadata.c b/drivers/md/persistent-data/dm-space-map-metadata.c
index d87a30a243db..51ca9edef444 100644
--- a/drivers/md/persistent-data/dm-space-map-metadata.c
+++ b/drivers/md/persistent-data/dm-space-map-metadata.c
@@ -144,12 +144,6 @@ static void sm_metadata_destroy(struct dm_space_map *sm)
144 kfree(smm); 144 kfree(smm);
145} 145}
146 146
147static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
148{
149 DMERR("doesn't support extend");
150 return -EINVAL;
151}
152
153static int sm_metadata_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count) 147static int sm_metadata_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count)
154{ 148{
155 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm); 149 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
@@ -382,6 +376,8 @@ static int sm_metadata_copy_root(struct dm_space_map *sm, void *where_le, size_t
382 return 0; 376 return 0;
383} 377}
384 378
379static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks);
380
385static struct dm_space_map ops = { 381static struct dm_space_map ops = {
386 .destroy = sm_metadata_destroy, 382 .destroy = sm_metadata_destroy,
387 .extend = sm_metadata_extend, 383 .extend = sm_metadata_extend,
@@ -522,6 +518,36 @@ static struct dm_space_map bootstrap_ops = {
522 518
523/*----------------------------------------------------------------*/ 519/*----------------------------------------------------------------*/
524 520
521static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
522{
523 int r, i;
524 enum allocation_event ev;
525 struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
526 dm_block_t old_len = smm->ll.nr_blocks;
527
528 /*
529 * Flick into a mode where all blocks get allocated in the new area.
530 */
531 smm->begin = old_len;
532 memcpy(&smm->sm, &bootstrap_ops, sizeof(smm->sm));
533
534 /*
535 * Extend.
536 */
537 r = sm_ll_extend(&smm->ll, extra_blocks);
538
539 /*
540 * Switch back to normal behaviour.
541 */
542 memcpy(&smm->sm, &ops, sizeof(smm->sm));
543 for (i = old_len; !r && i < smm->begin; i++)
544 r = sm_ll_inc(&smm->ll, i, &ev);
545
546 return r;
547}
548
549/*----------------------------------------------------------------*/
550
525struct dm_space_map *dm_sm_metadata_init(void) 551struct dm_space_map *dm_sm_metadata_init(void)
526{ 552{
527 struct sm_metadata *smm; 553 struct sm_metadata *smm;