Skip to content

Commit

Permalink
dm persistent data: support space map resizing
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Joe Thornber authored and Alasdair G Kergon committed May 10, 2013
1 parent 5d0db96 commit 1921c56
Showing 1 changed file with 32 additions and 6 deletions.
38 changes: 32 additions & 6 deletions drivers/md/persistent-data/dm-space-map-metadata.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,12 +144,6 @@ static void sm_metadata_destroy(struct dm_space_map *sm)
kfree(smm);
}

static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
{
DMERR("doesn't support extend");
return -EINVAL;
}

static int sm_metadata_get_nr_blocks(struct dm_space_map *sm, dm_block_t *count)
{
struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
Expand Down Expand Up @@ -382,6 +376,8 @@ static int sm_metadata_copy_root(struct dm_space_map *sm, void *where_le, size_t
return 0;
}

static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks);

static struct dm_space_map ops = {
.destroy = sm_metadata_destroy,
.extend = sm_metadata_extend,
Expand Down Expand Up @@ -522,6 +518,36 @@ static struct dm_space_map bootstrap_ops = {

/*----------------------------------------------------------------*/

static int sm_metadata_extend(struct dm_space_map *sm, dm_block_t extra_blocks)
{
int r, i;
enum allocation_event ev;
struct sm_metadata *smm = container_of(sm, struct sm_metadata, sm);
dm_block_t old_len = smm->ll.nr_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));

/*
* Extend.
*/
r = sm_ll_extend(&smm->ll, extra_blocks);

/*
* 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);

return r;
}

/*----------------------------------------------------------------*/

struct dm_space_map *dm_sm_metadata_init(void)
{
struct sm_metadata *smm;
Expand Down

0 comments on commit 1921c56

Please sign in to comment.