1
0
Fork 0

Merging upstream version 4.2+20230223.

Signed-off-by: Daniel Baumann <daniel@debian.org>
This commit is contained in:
Daniel Baumann 2025-02-14 06:01:59 +01:00
parent 866376462c
commit 30ed170f74
Signed by: daniel
GPG key ID: FBB4F0E80A80222F
76 changed files with 2282 additions and 1386 deletions

View file

@ -366,6 +366,18 @@ struct migr_record {
};
ASSERT_SIZE(migr_record, 128)
/**
* enum imsm_status - internal IMSM return values representation.
* @STATUS_OK: function succeeded.
* @STATUS_ERROR: General error ocurred (not specified).
*
* Typedefed to imsm_status_t.
*/
typedef enum imsm_status {
IMSM_STATUS_ERROR = -1,
IMSM_STATUS_OK = 0,
} imsm_status_t;
struct md_list {
/* usage marker:
* 1: load metadata
@ -851,6 +863,21 @@ static struct disk_info *get_disk_info(struct imsm_update_create_array *update)
return inf;
}
/**
* __get_imsm_dev() - Get device with index from imsm_super.
* @mpb: &imsm_super pointer, not NULL.
* @index: Device index.
*
* Function works as non-NULL, aborting in such a case,
* when NULL would be returned.
*
* Device index should be in range 0 up to num_raid_devs.
* Function assumes the index was already verified.
* Index must be valid, otherwise abort() is called.
*
* Return: Pointer to corresponding imsm_dev.
*
*/
static struct imsm_dev *__get_imsm_dev(struct imsm_super *mpb, __u8 index)
{
int offset;
@ -858,30 +885,47 @@ static struct imsm_dev *__get_imsm_dev(struct imsm_super *mpb, __u8 index)
void *_mpb = mpb;
if (index >= mpb->num_raid_devs)
return NULL;
goto error;
/* devices start after all disks */
offset = ((void *) &mpb->disk[mpb->num_disks]) - _mpb;
for (i = 0; i <= index; i++)
for (i = 0; i <= index; i++, offset += sizeof_imsm_dev(_mpb + offset, 0))
if (i == index)
return _mpb + offset;
else
offset += sizeof_imsm_dev(_mpb + offset, 0);
return NULL;
error:
pr_err("cannot find imsm_dev with index %u in imsm_super\n", index);
abort();
}
/**
* get_imsm_dev() - Get device with index from intel_super.
* @super: &intel_super pointer, not NULL.
* @index: Device index.
*
* Function works as non-NULL, aborting in such a case,
* when NULL would be returned.
*
* Device index should be in range 0 up to num_raid_devs.
* Function assumes the index was already verified.
* Index must be valid, otherwise abort() is called.
*
* Return: Pointer to corresponding imsm_dev.
*
*/
static struct imsm_dev *get_imsm_dev(struct intel_super *super, __u8 index)
{
struct intel_dev *dv;
if (index >= super->anchor->num_raid_devs)
return NULL;
goto error;
for (dv = super->devlist; dv; dv = dv->next)
if (dv->index == index)
return dv->dev;
return NULL;
error:
pr_err("cannot find imsm_dev with index %u in intel_super\n", index);
abort();
}
static inline unsigned long long __le48_to_cpu(const struct bbm_log_block_addr
@ -1151,7 +1195,7 @@ static void set_imsm_ord_tbl_ent(struct imsm_map *map, int slot, __u32 ord)
map->disk_ord_tbl[slot] = __cpu_to_le32(ord);
}
static int get_imsm_disk_slot(struct imsm_map *map, unsigned idx)
static int get_imsm_disk_slot(struct imsm_map *map, const unsigned int idx)
{
int slot;
__u32 ord;
@ -1162,7 +1206,7 @@ static int get_imsm_disk_slot(struct imsm_map *map, unsigned idx)
return slot;
}
return -1;
return IMSM_STATUS_ERROR;
}
static int get_imsm_raid_level(struct imsm_map *map)
@ -1177,6 +1221,23 @@ static int get_imsm_raid_level(struct imsm_map *map)
return map->raid_level;
}
/**
* get_disk_slot_in_dev() - retrieve disk slot from &imsm_dev.
* @super: &intel_super pointer, not NULL.
* @dev_idx: imsm device index.
* @idx: disk index.
*
* Return: Slot on success, IMSM_STATUS_ERROR otherwise.
*/
static int get_disk_slot_in_dev(struct intel_super *super, const __u8 dev_idx,
const unsigned int idx)
{
struct imsm_dev *dev = get_imsm_dev(super, dev_idx);
struct imsm_map *map = get_imsm_map(dev, MAP_0);
return get_imsm_disk_slot(map, idx);
}
static int cmp_extent(const void *av, const void *bv)
{
const struct extent *a = av;
@ -1193,13 +1254,9 @@ static int count_memberships(struct dl *dl, struct intel_super *super)
int memberships = 0;
int i;
for (i = 0; i < super->anchor->num_raid_devs; i++) {
struct imsm_dev *dev = get_imsm_dev(super, i);
struct imsm_map *map = get_imsm_map(dev, MAP_0);
if (get_imsm_disk_slot(map, dl->index) >= 0)
for (i = 0; i < super->anchor->num_raid_devs; i++)
if (get_disk_slot_in_dev(super, i, dl->index) >= 0)
memberships++;
}
return memberships;
}
@ -1909,6 +1966,7 @@ void examine_migr_rec_imsm(struct intel_super *super)
/* first map under migration */
map = get_imsm_map(dev, MAP_0);
if (map)
slot = get_imsm_disk_slot(map, super->disks->index);
if (map == NULL || slot > 1 || slot < 0) {
@ -3835,8 +3893,8 @@ struct mdinfo *getinfo_super_disks_imsm(struct supertype *st)
}
static int update_super_imsm(struct supertype *st, struct mdinfo *info,
char *update, char *devname, int verbose,
int uuid_set, char *homehost)
enum update_opt update, char *devname,
int verbose, int uuid_set, char *homehost)
{
/* For 'assemble' and 'force' we need to return non-zero if any
* change was made. For others, the return value is ignored.
@ -3872,7 +3930,8 @@ static int update_super_imsm(struct supertype *st, struct mdinfo *info,
mpb = super->anchor;
if (strcmp(update, "uuid") == 0) {
switch (update) {
case UOPT_UUID:
/* We take this to mean that the family_num should be updated.
* However that is much smaller than the uuid so we cannot really
* allow an explicit uuid to be given. And it is hard to reliably
@ -3896,10 +3955,14 @@ static int update_super_imsm(struct supertype *st, struct mdinfo *info,
}
if (rv == 0)
mpb->orig_family_num = info->uuid[0];
} else if (strcmp(update, "assemble") == 0)
break;
case UOPT_SPEC_ASSEMBLE:
rv = 0;
else
break;
default:
rv = -1;
break;
}
/* successful update? recompute checksum */
if (rv == 0)
@ -4364,8 +4427,7 @@ int check_mpb_migr_compatibility(struct intel_super *super)
for (i = 0; i < super->anchor->num_raid_devs; i++) {
struct imsm_dev *dev_iter = __get_imsm_dev(super->anchor, i);
if (dev_iter &&
dev_iter->vol.migr_state == 1 &&
if (dev_iter->vol.migr_state == 1 &&
dev_iter->vol.migr_type == MIGR_GEN_MIGR) {
/* This device is migrating */
map0 = get_imsm_map(dev_iter, MAP_0);
@ -4514,8 +4576,6 @@ static void clear_hi(struct intel_super *super)
}
for (i = 0; i < mpb->num_raid_devs; ++i) {
struct imsm_dev *dev = get_imsm_dev(super, i);
if (!dev)
return;
for (n = 0; n < 2; ++n) {
struct imsm_map *map = get_imsm_map(dev, n);
if (!map)
@ -5220,7 +5280,7 @@ static int get_super_block(struct intel_super **super_list, char *devnm, char *d
/* retry the load if we might have raced against mdmon */
if (err == 3 && devnm && mdmon_running(devnm))
for (retry = 0; retry < 3; retry++) {
usleep(3000);
sleep_for(0, MSEC_TO_NSEC(3), true);
err = load_and_parse_mpb(dfd, s, NULL, keep_fd);
if (err != 3)
break;
@ -5322,7 +5382,7 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname)
if (mdstat && mdmon_running(mdstat->devnm) && getpid() != mdmon_pid(mdstat->devnm)) {
for (retry = 0; retry < 3; retry++) {
usleep(3000);
sleep_for(0, MSEC_TO_NSEC(3), true);
rv = load_and_parse_mpb(fd, super, devname, 0);
if (rv != 3)
break;
@ -5625,7 +5685,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
free(dev);
free(dv);
pr_err("imsm does not support consistency policy %s\n",
map_num(consistency_policies, s->consistency_policy));
map_num_s(consistency_policies, s->consistency_policy));
return 0;
}
@ -5734,6 +5794,10 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
struct imsm_map *map;
struct dl *dl, *df;
int slot;
int autolayout = 0;
if (!is_fd_valid(fd))
autolayout = 1;
dev = get_imsm_dev(super, super->current_vol);
map = get_imsm_map(dev, MAP_0);
@ -5744,25 +5808,32 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
return 1;
}
if (!is_fd_valid(fd)) {
/* we're doing autolayout so grab the pre-marked (in
* validate_geometry) raid_disk
*/
for (dl = super->disks; dl; dl = dl->next)
for (dl = super->disks; dl ; dl = dl->next) {
if (autolayout) {
if (dl->raiddisk == dk->raid_disk)
break;
} else {
for (dl = super->disks; dl ; dl = dl->next)
if (dl->major == dk->major &&
dl->minor == dk->minor)
break;
} else if (dl->major == dk->major && dl->minor == dk->minor)
break;
}
if (!dl) {
pr_err("%s is not a member of the same container\n", devname);
if (!autolayout)
pr_err("%s is not a member of the same container.\n",
devname);
return 1;
}
if (!autolayout && super->current_vol > 0) {
int _slot = get_disk_slot_in_dev(super, 0, dl->index);
if (_slot != dk->raid_disk) {
pr_err("Member %s is in %d slot for the first volume, but is in %d slot for a new volume.\n",
dl->devname, _slot, dk->raid_disk);
pr_err("Raid members are in different order than for the first volume, aborting.\n");
return 1;
}
}
if (mpb->num_disks == 0)
if (!get_dev_sector_size(dl->fd, dl->devname,
&super->sector_size))
@ -5836,7 +5907,7 @@ static int add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
struct imsm_dev *_dev = __get_imsm_dev(mpb, 0);
_disk = __get_imsm_disk(mpb, dl->index);
if (!_dev || !_disk) {
if (!_disk) {
pr_err("BUG mpb setup error\n");
return 1;
}
@ -6171,10 +6242,10 @@ static int write_super_imsm(struct supertype *st, int doclose)
for (i = 0; i < mpb->num_raid_devs; i++) {
struct imsm_dev *dev = __get_imsm_dev(mpb, i);
struct imsm_dev *dev2 = get_imsm_dev(super, i);
if (dev && dev2) {
imsm_copy_dev(dev, dev2);
mpb_size += sizeof_imsm_dev(dev, 0);
}
imsm_copy_dev(dev, dev2);
mpb_size += sizeof_imsm_dev(dev, 0);
if (is_gen_migration(dev2))
clear_migration_record = 0;
}
@ -6467,7 +6538,7 @@ static int validate_ppl_imsm(struct supertype *st, struct mdinfo *info,
if (mdmon_running(st->container_devnm))
st->update_tail = &st->updates;
if (st->ss->update_subarray(st, subarray, "ppl", NULL)) {
if (st->ss->update_subarray(st, subarray, UOPT_PPL, NULL)) {
pr_err("Failed to update subarray %s\n",
subarray);
} else {
@ -6661,7 +6732,7 @@ static int validate_geometry_imsm_container(struct supertype *st, int level,
struct intel_super *super = NULL;
int rv = 0;
if (level != LEVEL_CONTAINER)
if (!is_container(level))
return 0;
if (!dev)
return 1;
@ -7467,11 +7538,27 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
return 1;
}
static int imsm_get_free_size(struct supertype *st, int raiddisks,
unsigned long long size, int chunk,
unsigned long long *freesize)
/**
* imsm_get_free_size() - get the biggest, common free space from members.
* @super: &intel_super pointer, not NULL.
* @raiddisks: number of raid disks.
* @size: requested size, could be 0 (means max size).
* @chunk: requested chunk.
* @freesize: pointer for returned size value.
*
* Return: &IMSM_STATUS_OK or &IMSM_STATUS_ERROR.
*
* @freesize is set to meaningful value, this can be @size, or calculated
* max free size.
* super->create_offset value is modified and set appropriately in
* merge_extends() for further creation.
*/
static imsm_status_t imsm_get_free_size(struct intel_super *super,
const int raiddisks,
unsigned long long size,
const int chunk,
unsigned long long *freesize)
{
struct intel_super *super = st->sb;
struct imsm_super *mpb = super->anchor;
struct dl *dl;
int i;
@ -7515,12 +7602,10 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks,
/* chunk is in K */
minsize = chunk * 2;
if (cnt < raiddisks ||
(super->orom && used && used != raiddisks) ||
maxsize < minsize ||
maxsize == 0) {
if (cnt < raiddisks || (super->orom && used && used != raiddisks) ||
maxsize < minsize || maxsize == 0) {
pr_err("not enough devices with space to create array.\n");
return 0; /* No enough free spaces large enough */
return IMSM_STATUS_ERROR;
}
if (size == 0) {
@ -7533,37 +7618,69 @@ static int imsm_get_free_size(struct supertype *st, int raiddisks,
}
if (mpb->num_raid_devs > 0 && size && size != maxsize)
pr_err("attempting to create a second volume with size less then remaining space.\n");
cnt = 0;
for (dl = super->disks; dl; dl = dl->next)
if (dl->e)
dl->raiddisk = cnt++;
*freesize = size;
dprintf("imsm: imsm_get_free_size() returns : %llu\n", size);
return 1;
return IMSM_STATUS_OK;
}
static int reserve_space(struct supertype *st, int raiddisks,
unsigned long long size, int chunk,
unsigned long long *freesize)
/**
* autolayout_imsm() - automatically layout a new volume.
* @super: &intel_super pointer, not NULL.
* @raiddisks: number of raid disks.
* @size: requested size, could be 0 (means max size).
* @chunk: requested chunk.
* @freesize: pointer for returned size value.
*
* We are being asked to automatically layout a new volume based on the current
* contents of the container. If the parameters can be satisfied autolayout_imsm
* will record the disks, start offset, and will return size of the volume to
* be created. See imsm_get_free_size() for details.
* add_to_super() and getinfo_super() detect when autolayout is in progress.
* If first volume exists, slots are set consistently to it.
*
* Return: &IMSM_STATUS_OK on success, &IMSM_STATUS_ERROR otherwise.
*
* Disks are marked for creation via dl->raiddisk.
*/
static imsm_status_t autolayout_imsm(struct intel_super *super,
const int raiddisks,
unsigned long long size, const int chunk,
unsigned long long *freesize)
{
struct intel_super *super = st->sb;
struct dl *dl;
int cnt;
int rv = 0;
int curr_slot = 0;
struct dl *disk;
int vol_cnt = super->anchor->num_raid_devs;
imsm_status_t rv;
rv = imsm_get_free_size(st, raiddisks, size, chunk, freesize);
if (rv) {
cnt = 0;
for (dl = super->disks; dl; dl = dl->next)
if (dl->e)
dl->raiddisk = cnt++;
rv = 1;
rv = imsm_get_free_size(super, raiddisks, size, chunk, freesize);
if (rv != IMSM_STATUS_OK)
return IMSM_STATUS_ERROR;
for (disk = super->disks; disk; disk = disk->next) {
if (!disk->e)
continue;
if (curr_slot == raiddisks)
break;
if (vol_cnt == 0) {
disk->raiddisk = curr_slot;
} else {
int _slot = get_disk_slot_in_dev(super, 0, disk->index);
if (_slot == -1) {
pr_err("Disk %s is not used in first volume, aborting\n",
disk->devname);
return IMSM_STATUS_ERROR;
}
disk->raiddisk = _slot;
}
curr_slot++;
}
return rv;
return IMSM_STATUS_OK;
}
static int validate_geometry_imsm(struct supertype *st, int level, int layout,
@ -7580,7 +7697,7 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
* if given unused devices create a container
* if given given devices in a container create a member volume
*/
if (level == LEVEL_CONTAINER)
if (is_container(level))
/* Must be a fresh device to add to a container */
return validate_geometry_imsm_container(st, level, raiddisks,
data_offset, dev,
@ -7599,35 +7716,35 @@ static int validate_geometry_imsm(struct supertype *st, int level, int layout,
}
if (!dev) {
if (st->sb) {
struct intel_super *super = st->sb;
if (!validate_geometry_imsm_orom(st->sb, level, layout,
raiddisks, chunk, size,
verbose))
struct intel_super *super = st->sb;
/*
* Autolayout mode, st->sb must be set.
*/
if (!super) {
pr_vrb("superblock must be set for autolayout, aborting\n");
return 0;
}
if (!validate_geometry_imsm_orom(st->sb, level, layout,
raiddisks, chunk, size,
verbose))
return 0;
if (super->orom && freesize) {
imsm_status_t rv;
int count = count_volumes(super->hba, super->orom->dpa,
verbose);
if (super->orom->vphba <= count) {
pr_vrb("platform does not support more than %d raid volumes.\n",
super->orom->vphba);
return 0;
/* we are being asked to automatically layout a
* new volume based on the current contents of
* the container. If the the parameters can be
* satisfied reserve_space will record the disks,
* start offset, and size of the volume to be
* created. add_to_super and getinfo_super
* detect when autolayout is in progress.
*/
/* assuming that freesize is always given when array is
created */
if (super->orom && freesize) {
int count;
count = count_volumes(super->hba,
super->orom->dpa, verbose);
if (super->orom->vphba <= count) {
pr_vrb("platform does not support more than %d raid volumes.\n",
super->orom->vphba);
return 0;
}
}
if (freesize)
return reserve_space(st, raiddisks, size,
*chunk, freesize);
rv = autolayout_imsm(super, raiddisks, size, *chunk,
freesize);
if (rv != IMSM_STATUS_OK)
return 0;
}
return 1;
}
@ -7777,36 +7894,39 @@ static int kill_subarray_imsm(struct supertype *st, char *subarray_id)
return 0;
}
static int get_rwh_policy_from_update(char *update)
/**
* get_rwh_policy_from_update() - Get the rwh policy for update option.
* @update: Update option.
*/
static int get_rwh_policy_from_update(enum update_opt update)
{
if (strcmp(update, "ppl") == 0)
switch (update) {
case UOPT_PPL:
return RWH_MULTIPLE_DISTRIBUTED;
else if (strcmp(update, "no-ppl") == 0)
case UOPT_NO_PPL:
return RWH_MULTIPLE_OFF;
else if (strcmp(update, "bitmap") == 0)
case UOPT_BITMAP:
return RWH_BITMAP;
else if (strcmp(update, "no-bitmap") == 0)
case UOPT_NO_BITMAP:
return RWH_OFF;
return -1;
default:
break;
}
return UOPT_UNDEFINED;
}
static int update_subarray_imsm(struct supertype *st, char *subarray,
char *update, struct mddev_ident *ident)
enum update_opt update, struct mddev_ident *ident)
{
/* update the subarray currently referenced by ->current_vol */
struct intel_super *super = st->sb;
struct imsm_super *mpb = super->anchor;
if (strcmp(update, "name") == 0) {
if (update == UOPT_NAME) {
char *name = ident->name;
char *ep;
int vol;
if (is_subarray_active(subarray, st->devnm)) {
pr_err("Unable to update name of active subarray\n");
return 2;
}
if (!check_name(super, name, 0))
return 2;
@ -7836,7 +7956,7 @@ static int update_subarray_imsm(struct supertype *st, char *subarray,
}
super->updates_pending++;
}
} else if (get_rwh_policy_from_update(update) != -1) {
} else if (get_rwh_policy_from_update(update) != UOPT_UNDEFINED) {
int new_policy;
char *ep;
int vol = strtoul(subarray, &ep, 10);
@ -9033,29 +9153,26 @@ static int imsm_rebuild_allowed(struct supertype *cont, int dev_idx, int failed)
__u8 state;
dev2 = get_imsm_dev(cont->sb, dev_idx);
if (dev2) {
state = imsm_check_degraded(cont->sb, dev2, failed, MAP_0);
if (state == IMSM_T_STATE_FAILED) {
map = get_imsm_map(dev2, MAP_0);
if (!map)
return 1;
for (slot = 0; slot < map->num_members; slot++) {
/*
* Check if failed disks are deleted from intel
* disk list or are marked to be deleted
*/
idx = get_imsm_disk_idx(dev2, slot, MAP_X);
idisk = get_imsm_dl_disk(cont->sb, idx);
/*
* Do not rebuild the array if failed disks
* from failed sub-array are not removed from
* container.
*/
if (idisk &&
is_failed(&idisk->disk) &&
(idisk->action != DISK_REMOVE))
return 0;
}
state = imsm_check_degraded(cont->sb, dev2, failed, MAP_0);
if (state == IMSM_T_STATE_FAILED) {
map = get_imsm_map(dev2, MAP_0);
for (slot = 0; slot < map->num_members; slot++) {
/*
* Check if failed disks are deleted from intel
* disk list or are marked to be deleted
*/
idx = get_imsm_disk_idx(dev2, slot, MAP_X);
idisk = get_imsm_dl_disk(cont->sb, idx);
/*
* Do not rebuild the array if failed disks
* from failed sub-array are not removed from
* container.
*/
if (idisk &&
is_failed(&idisk->disk) &&
(idisk->action != DISK_REMOVE))
return 0;
}
}
return 1;
@ -9629,10 +9746,9 @@ static int apply_update_activate_spare(struct imsm_update_activate_spare *u,
/* count arrays using the victim in the metadata */
found = 0;
for (a = active_array; a ; a = a->next) {
dev = get_imsm_dev(super, a->info.container_member);
map = get_imsm_map(dev, MAP_0);
int dev_idx = a->info.container_member;
if (get_imsm_disk_slot(map, victim) >= 0)
if (get_disk_slot_in_dev(super, dev_idx, victim) >= 0)
found++;
}
@ -10089,7 +10205,6 @@ static void imsm_process_update(struct supertype *st,
int victim = u->dev_idx;
struct active_array *a;
struct intel_dev **dp;
struct imsm_dev *dev;
/* sanity check that we are not affecting the uuid of
* active arrays, or deleting an active array
@ -10105,8 +10220,7 @@ static void imsm_process_update(struct supertype *st,
* is active in the container, so checking
* mpb->num_raid_devs is just extra paranoia
*/
dev = get_imsm_dev(super, victim);
if (a || !dev || mpb->num_raid_devs == 1) {
if (a || mpb->num_raid_devs == 1 || victim >= super->anchor->num_raid_devs) {
dprintf("failed to delete subarray-%d\n", victim);
break;
}
@ -10140,7 +10254,7 @@ static void imsm_process_update(struct supertype *st,
if (a->info.container_member == target)
break;
dev = get_imsm_dev(super, u->dev_idx);
if (a || !dev || !check_name(super, name, 1)) {
if (a || !check_name(super, name, 1)) {
dprintf("failed to rename subarray-%d\n", target);
break;
}
@ -10169,10 +10283,6 @@ static void imsm_process_update(struct supertype *st,
struct imsm_update_rwh_policy *u = (void *)update->buf;
int target = u->dev_idx;
struct imsm_dev *dev = get_imsm_dev(super, target);
if (!dev) {
dprintf("could not find subarray-%d\n", target);
break;
}
if (dev->rwh_policy != u->new_policy) {
dev->rwh_policy = u->new_policy;
@ -11397,8 +11507,10 @@ static int imsm_create_metadata_update_for_migration(
{
struct intel_super *super = st->sb;
int update_memory_size;
int current_chunk_size;
struct imsm_update_reshape_migration *u;
struct imsm_dev *dev;
struct imsm_dev *dev = get_imsm_dev(super, super->current_vol);
struct imsm_map *map = get_imsm_map(dev, MAP_0);
int previous_level = -1;
dprintf("(enter) New Level = %i\n", geo->level);
@ -11415,23 +11527,15 @@ static int imsm_create_metadata_update_for_migration(
u->new_disks[0] = -1;
u->new_chunksize = -1;
dev = get_imsm_dev(super, u->subdev);
if (dev) {
struct imsm_map *map;
current_chunk_size = __le16_to_cpu(map->blocks_per_strip) / 2;
map = get_imsm_map(dev, MAP_0);
if (map) {
int current_chunk_size =
__le16_to_cpu(map->blocks_per_strip) / 2;
if (geo->chunksize != current_chunk_size) {
u->new_chunksize = geo->chunksize / 1024;
dprintf("imsm: chunk size change from %i to %i\n",
current_chunk_size, u->new_chunksize);
}
previous_level = map->raid_level;
}
if (geo->chunksize != current_chunk_size) {
u->new_chunksize = geo->chunksize / 1024;
dprintf("imsm: chunk size change from %i to %i\n",
current_chunk_size, u->new_chunksize);
}
previous_level = map->raid_level;
if (geo->level == 5 && previous_level == 0) {
struct mdinfo *spares = NULL;
@ -11499,7 +11603,7 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
unsigned long long current_size;
unsigned long long free_size;
unsigned long long max_size;
int rv;
imsm_status_t rv;
getinfo_super_imsm_volume(st, &info, NULL);
if (geo->level != info.array.level && geo->level >= 0 &&
@ -11618,9 +11722,10 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
}
/* check the maximum available size
*/
rv = imsm_get_free_size(st, dev->vol.map->num_members,
0, chunk, &free_size);
if (rv == 0)
rv = imsm_get_free_size(super, dev->vol.map->num_members,
0, chunk, &free_size);
if (rv != IMSM_STATUS_OK)
/* Cannot find maximum available space
*/
max_size = 0;
@ -11683,8 +11788,8 @@ enum imsm_reshape_type imsm_analyze_change(struct supertype *st,
struct imsm_super *mpb = super->anchor;
if (mpb->num_raid_devs > 1) {
pr_err("Error. Cannot perform operation on %s- for this operation it MUST be single array in container\n",
geo->dev_name);
pr_err("Error. Cannot perform operation on %s- for this operation "
"it MUST be single array in container\n", geo->dev_name);
change = -1;
}
}
@ -11757,7 +11862,7 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index)
unsigned long long d_size = imsm_dev_size(dev);
int u_size;
if (calc_size == d_size || dev->vol.migr_type == MIGR_GEN_MIGR)
if (calc_size == d_size)
continue;
/* There is a difference, confirm that imsm_dev_size is
@ -11772,10 +11877,6 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index)
geo.size = d_size;
u_size = imsm_create_metadata_update_for_size_change(st, &geo,
&update);
if (u_size < 1) {
dprintf("imsm: Cannot prepare size change update\n");
goto exit;
}
imsm_update_metadata_locally(st, update, u_size);
if (st->update_tail) {
append_metadata_update(st, update, u_size);
@ -11783,9 +11884,8 @@ static int imsm_fix_size_mismatch(struct supertype *st, int subarray_index)
st->update_tail = &st->updates;
} else {
imsm_sync_metadata(st);
free(update);
}
free(update);
}
ret_val = 0;
exit:
@ -11992,7 +12092,7 @@ int wait_for_reshape_imsm(struct mdinfo *sra, int ndata)
close(fd);
return 1;
}
usleep(30000);
sleep_for(0, MSEC_TO_NSEC(30), true);
} else
break;
} while (retry--);
@ -12520,9 +12620,6 @@ static int validate_internal_bitmap_imsm(struct supertype *st)
unsigned long long offset;
struct dl *d;
if (!dev)
return -1;
if (dev->rwh_policy != RWH_BITMAP)
return 0;
@ -12568,16 +12665,8 @@ static int add_internal_bitmap_imsm(struct supertype *st, int *chunkp,
return -1;
dev = get_imsm_dev(super, vol_idx);
if (!dev) {
dprintf("cannot find the device for volume index %d\n",
vol_idx);
return -1;
}
dev->rwh_policy = RWH_BITMAP;
*chunkp = calculate_bitmap_chunksize(st, dev);
return 0;
}