imsm: Update metadata for second array
When second array reshape is about to start metadata should be updated by mdmon in imsm_set_array_state(). Signed-off-by: Adam Kwolek <adam.kwolek@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
582496b2c2
commit
0e2d1a4e68
|
@ -4849,6 +4849,73 @@ static void handle_missing(struct intel_super *super, struct imsm_dev *dev)
|
||||||
|
|
||||||
static void imsm_set_disk(struct active_array *a, int n, int state);
|
static void imsm_set_disk(struct active_array *a, int n, int state);
|
||||||
|
|
||||||
|
static void imsm_progress_container_reshape(struct intel_super *super)
|
||||||
|
{
|
||||||
|
/* if no device has a migr_state, but some device has a
|
||||||
|
* different number of members than the previous device, start
|
||||||
|
* changing the number of devices in this device to match
|
||||||
|
* previous.
|
||||||
|
*/
|
||||||
|
struct imsm_super *mpb = super->anchor;
|
||||||
|
int prev_disks = -1;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < mpb->num_raid_devs; i++) {
|
||||||
|
struct imsm_dev *dev = get_imsm_dev(super, i);
|
||||||
|
struct imsm_map *map = get_imsm_map(dev, 0);
|
||||||
|
struct imsm_map *map2;
|
||||||
|
int prev_num_members;
|
||||||
|
int used_disks;
|
||||||
|
|
||||||
|
if (dev->vol.migr_state)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (prev_disks == -1)
|
||||||
|
prev_disks = map->num_members;
|
||||||
|
if (prev_disks == map->num_members)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
/* OK, this array needs to enter reshape mode.
|
||||||
|
* i.e it needs a migr_state
|
||||||
|
*/
|
||||||
|
|
||||||
|
prev_num_members = map->num_members;
|
||||||
|
map->num_members = prev_disks;
|
||||||
|
dev->vol.migr_state = 1;
|
||||||
|
dev->vol.curr_migr_unit = 0;
|
||||||
|
dev->vol.migr_type = MIGR_GEN_MIGR;
|
||||||
|
for (i = prev_num_members;
|
||||||
|
i < map->num_members; i++)
|
||||||
|
set_imsm_ord_tbl_ent(map, i, i);
|
||||||
|
map2 = get_imsm_map(dev, 1);
|
||||||
|
/* Copy the current map */
|
||||||
|
memcpy(map2, map, sizeof_imsm_map(map));
|
||||||
|
map2->num_members = prev_num_members;
|
||||||
|
|
||||||
|
/* calculate new size
|
||||||
|
*/
|
||||||
|
used_disks = imsm_num_data_members(dev, 0);
|
||||||
|
if (used_disks) {
|
||||||
|
unsigned long long array_blocks;
|
||||||
|
|
||||||
|
array_blocks =
|
||||||
|
map->blocks_per_member
|
||||||
|
* used_disks;
|
||||||
|
/* round array size down to closest MB
|
||||||
|
*/
|
||||||
|
array_blocks = (array_blocks
|
||||||
|
>> SECT_PER_MB_SHIFT)
|
||||||
|
<< SECT_PER_MB_SHIFT;
|
||||||
|
dev->size_low =
|
||||||
|
__cpu_to_le32((__u32)array_blocks);
|
||||||
|
dev->size_high =
|
||||||
|
__cpu_to_le32(
|
||||||
|
(__u32)(array_blocks >> 32));
|
||||||
|
}
|
||||||
|
super->updates_pending++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* Handle dirty -> clean transititions, resync and reshape. Degraded and rebuild
|
/* Handle dirty -> clean transititions, resync and reshape. Degraded and rebuild
|
||||||
* states are handled in imsm_set_disk() with one exception, when a
|
* states are handled in imsm_set_disk() with one exception, when a
|
||||||
* resync is stopped due to a new failure this routine will set the
|
* resync is stopped due to a new failure this routine will set the
|
||||||
|
@ -4918,6 +4985,7 @@ static int imsm_set_array_state(struct active_array *a, int consistent)
|
||||||
* array size
|
* array size
|
||||||
*/
|
*/
|
||||||
super->updates_pending++;
|
super->updates_pending++;
|
||||||
|
imsm_progress_container_reshape(super);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue