imsm: Add new metadata update for volume size expansion
Add new meatdata update type imsm_update_size_change, and update metadata for volume size expansion operation. Signed-off-by: Adam Kwolek <adam.kwolek@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
7abc98717c
commit
f3871fdc68
132
super-intel.c
132
super-intel.c
|
@ -419,6 +419,7 @@ enum imsm_update_type {
|
|||
update_reshape_migration,
|
||||
update_takeover,
|
||||
update_general_migration_checkpoint,
|
||||
update_size_change,
|
||||
};
|
||||
|
||||
struct imsm_update_activate_spare {
|
||||
|
@ -471,6 +472,12 @@ struct imsm_update_reshape_migration {
|
|||
int new_disks[1]; /* new_raid_disks - old_raid_disks makedev number */
|
||||
};
|
||||
|
||||
struct imsm_update_size_change {
|
||||
enum imsm_update_type type;
|
||||
int subdev;
|
||||
long long new_size;
|
||||
};
|
||||
|
||||
struct imsm_update_general_migration_checkpoint {
|
||||
enum imsm_update_type type;
|
||||
__u32 curr_migr_unit;
|
||||
|
@ -6974,7 +6981,8 @@ static void handle_missing(struct intel_super *super, struct imsm_dev *dev)
|
|||
super->updates_pending++;
|
||||
}
|
||||
|
||||
static unsigned long long imsm_set_array_size(struct imsm_dev *dev)
|
||||
static unsigned long long imsm_set_array_size(struct imsm_dev *dev,
|
||||
long long new_size)
|
||||
{
|
||||
int used_disks = imsm_num_data_members(dev, MAP_0);
|
||||
unsigned long long array_blocks;
|
||||
|
@ -6993,8 +7001,17 @@ static unsigned long long imsm_set_array_size(struct imsm_dev *dev)
|
|||
|
||||
/* set array size in metadata
|
||||
*/
|
||||
map = get_imsm_map(dev, MAP_0);
|
||||
array_blocks = blocks_per_member(map) * used_disks;
|
||||
if (new_size <= 0) {
|
||||
/* OLCE size change is caused by added disks
|
||||
*/
|
||||
map = get_imsm_map(dev, MAP_0);
|
||||
array_blocks = blocks_per_member(map) * used_disks;
|
||||
} else {
|
||||
/* Online Volume Size Change
|
||||
* Using available free space
|
||||
*/
|
||||
array_blocks = new_size;
|
||||
}
|
||||
|
||||
/* round array size down to closest MB
|
||||
*/
|
||||
|
@ -7051,7 +7068,7 @@ static void imsm_progress_container_reshape(struct intel_super *super)
|
|||
memcpy(map2, map, copy_map_size);
|
||||
map2->num_members = prev_num_members;
|
||||
|
||||
imsm_set_array_size(dev);
|
||||
imsm_set_array_size(dev, -1);
|
||||
super->clean_migration_record_by_mdmon = 1;
|
||||
super->updates_pending++;
|
||||
}
|
||||
|
@ -7941,7 +7958,7 @@ skip_disk_add:
|
|||
*tofree = *space_list;
|
||||
/* calculate new size
|
||||
*/
|
||||
imsm_set_array_size(new_dev);
|
||||
imsm_set_array_size(new_dev, -1);
|
||||
|
||||
ret_val = 1;
|
||||
}
|
||||
|
@ -7956,6 +7973,44 @@ error_disk_add:
|
|||
return ret_val;
|
||||
}
|
||||
|
||||
static int apply_size_change_update(struct imsm_update_size_change *u,
|
||||
struct intel_super *super)
|
||||
{
|
||||
struct intel_dev *id;
|
||||
int ret_val = 0;
|
||||
|
||||
dprintf("apply_size_change_update()\n");
|
||||
if ((u->subdev < 0) ||
|
||||
(u->subdev > 1)) {
|
||||
dprintf("imsm: Error: Wrong subdev: %i\n", u->subdev);
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
for (id = super->devlist ; id; id = id->next) {
|
||||
if (id->index == (unsigned)u->subdev) {
|
||||
struct imsm_dev *dev = get_imsm_dev(super, u->subdev);
|
||||
struct imsm_map *map = get_imsm_map(dev, MAP_0);
|
||||
int used_disks = imsm_num_data_members(dev, MAP_0);
|
||||
unsigned long long blocks_per_member;
|
||||
|
||||
/* calculate new size
|
||||
*/
|
||||
blocks_per_member = u->new_size / used_disks;
|
||||
dprintf("imsm: apply_size_change_update(size: %llu, "
|
||||
"blocks per member: %llu)\n",
|
||||
u->new_size, blocks_per_member);
|
||||
set_blocks_per_member(map, blocks_per_member);
|
||||
imsm_set_array_size(dev, u->new_size);
|
||||
|
||||
ret_val = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ret_val;
|
||||
}
|
||||
|
||||
|
||||
static int apply_update_activate_spare(struct imsm_update_activate_spare *u,
|
||||
struct intel_super *super,
|
||||
struct active_array *active_array)
|
||||
|
@ -8155,7 +8210,7 @@ static int apply_reshape_container_disks_update(struct imsm_update_reshape *u,
|
|||
newmap = get_imsm_map(newdev, MAP_1);
|
||||
memcpy(newmap, oldmap, sizeof_imsm_map(oldmap));
|
||||
|
||||
imsm_set_array_size(newdev);
|
||||
imsm_set_array_size(newdev, -1);
|
||||
}
|
||||
|
||||
sp = (void **)id->dev;
|
||||
|
@ -8363,6 +8418,12 @@ static void imsm_process_update(struct supertype *st,
|
|||
super->updates_pending++;
|
||||
break;
|
||||
}
|
||||
case update_size_change: {
|
||||
struct imsm_update_size_change *u = (void *)update->buf;
|
||||
if (apply_size_change_update(u, super))
|
||||
super->updates_pending++;
|
||||
break;
|
||||
}
|
||||
case update_activate_spare: {
|
||||
struct imsm_update_activate_spare *u = (void *) update->buf;
|
||||
if (apply_update_activate_spare(u, super, st->arrays))
|
||||
|
@ -8757,6 +8818,9 @@ static void imsm_prepare_update(struct supertype *st,
|
|||
dprintf("New anchor length is %llu\n", (unsigned long long)len);
|
||||
break;
|
||||
}
|
||||
case update_size_change: {
|
||||
break;
|
||||
}
|
||||
case update_create_array: {
|
||||
struct imsm_update_create_array *u = (void *) update->buf;
|
||||
struct intel_dev *dv;
|
||||
|
@ -9614,6 +9678,43 @@ abort:
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/******************************************************************************
|
||||
* function: imsm_create_metadata_update_for_size_change()
|
||||
* Creates update for IMSM array for array size change.
|
||||
*
|
||||
******************************************************************************/
|
||||
static int imsm_create_metadata_update_for_size_change(
|
||||
struct supertype *st,
|
||||
struct geo_params *geo,
|
||||
struct imsm_update_size_change **updatep)
|
||||
{
|
||||
struct intel_super *super = st->sb;
|
||||
int update_memory_size = 0;
|
||||
struct imsm_update_size_change *u = NULL;
|
||||
|
||||
dprintf("imsm_create_metadata_update_for_size_change(enter)"
|
||||
" New size = %llu\n", geo->size);
|
||||
|
||||
/* size of all update data without anchor */
|
||||
update_memory_size = sizeof(struct imsm_update_size_change);
|
||||
|
||||
u = calloc(1, update_memory_size);
|
||||
if (u == NULL) {
|
||||
dprintf("error: cannot get memory for "
|
||||
"imsm_create_metadata_update_for_size_change\n");
|
||||
return 0;
|
||||
}
|
||||
u->type = update_size_change;
|
||||
u->subdev = super->current_vol;
|
||||
u->new_size = geo->size;
|
||||
|
||||
dprintf("imsm: reshape update preparation : OK\n");
|
||||
*updatep = u;
|
||||
|
||||
return update_memory_size;
|
||||
}
|
||||
|
||||
/******************************************************************************
|
||||
* function: imsm_create_metadata_update_for_migration()
|
||||
* Creates update for IMSM array.
|
||||
|
@ -10023,8 +10124,23 @@ static int imsm_reshape_super(struct supertype *st, long long size, int level,
|
|||
}
|
||||
break;
|
||||
case CH_ARRAY_SIZE: {
|
||||
/* ToDo: Prepare metadata update here
|
||||
*/
|
||||
struct imsm_update_size_change *u = NULL;
|
||||
int len =
|
||||
imsm_create_metadata_update_for_size_change(
|
||||
st, &geo, &u);
|
||||
if (len < 1) {
|
||||
dprintf("imsm: "
|
||||
"Cannot prepare update\n");
|
||||
break;
|
||||
}
|
||||
ret_val = 0;
|
||||
/* update metadata locally */
|
||||
imsm_update_metadata_locally(st, u, len);
|
||||
/* and possibly remotely */
|
||||
if (st->update_tail)
|
||||
append_metadata_update(st, u, len);
|
||||
else
|
||||
free(u);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
|
|
Loading…
Reference in New Issue