Grow: introduce min_offset_change to struct reshape.
raid10 currently uses the 'backup_blocks' field to store something else: a minimum offset change. This is bad practice, we will shortly need to have both for RAID5/6, so make a separate field. Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
6b2fc3c162
commit
89ecd3cfe4
26
Grow.c
26
Grow.c
|
@ -1128,19 +1128,21 @@ char *analyse_change(struct mdinfo *info, struct reshape *re)
|
||||||
re->before.data_disks = info->array.raid_disks;
|
re->before.data_disks = info->array.raid_disks;
|
||||||
re->after.layout = info->new_layout;
|
re->after.layout = info->new_layout;
|
||||||
re->after.data_disks = new_disks;
|
re->after.data_disks = new_disks;
|
||||||
/* For RAID10 we don't do backup, and there is
|
/* For RAID10 we don't do backup but do allow reshape,
|
||||||
* no need to synchronise stripes on both
|
* so set backup_blocks to INVALID_SECTORS rather than
|
||||||
|
* zero.
|
||||||
|
* And there is no need to synchronise stripes on both
|
||||||
* 'old' and 'new'. So the important
|
* 'old' and 'new'. So the important
|
||||||
* number is the minimum data_offset difference
|
* number is the minimum data_offset difference
|
||||||
* which is the larger of (offset copies * chunk).
|
* which is the larger of (offset copies * chunk).
|
||||||
*/
|
*/
|
||||||
|
re->backup_blocks = INVALID_SECTORS;
|
||||||
re->backup_blocks = max(old_chunk, new_chunk) / 512;
|
re->min_offset_change = max(old_chunk, new_chunk) / 512;
|
||||||
if (new_disks < re->before.data_disks &&
|
if (new_disks < re->before.data_disks &&
|
||||||
info->space_after < re->backup_blocks)
|
info->space_after < re->min_offset_change)
|
||||||
/* Reduce component size by one chunk */
|
/* Reduce component size by one chunk */
|
||||||
re->new_size = (info->component_size -
|
re->new_size = (info->component_size -
|
||||||
re->backup_blocks);
|
re->min_offset_change);
|
||||||
else
|
else
|
||||||
re->new_size = info->component_size;
|
re->new_size = info->component_size;
|
||||||
re->new_size = re->new_size * new_disks / copies;
|
re->new_size = re->new_size * new_disks / copies;
|
||||||
|
@ -2303,15 +2305,15 @@ static int raid10_reshape(char *container, int fd, char *devname,
|
||||||
/* Changing raid_disks, layout, chunksize or possibly
|
/* Changing raid_disks, layout, chunksize or possibly
|
||||||
* just data_offset for a RAID10.
|
* just data_offset for a RAID10.
|
||||||
* We must always change data_offset. We change by at least
|
* We must always change data_offset. We change by at least
|
||||||
* ->backup_blocks which is the largest of the old and new
|
* ->min_offset_change which is the largest of the old and new
|
||||||
* chunk sizes.
|
* chunk sizes.
|
||||||
* If raid_disks is increasing, then data_offset must decrease
|
* If raid_disks is increasing, then data_offset must decrease
|
||||||
* by at least this copy size.
|
* by at least this copy size.
|
||||||
* If raid_disks is unchanged, data_offset must increase or
|
* If raid_disks is unchanged, data_offset must increase or
|
||||||
* decrease by at least backup_blocks but preferably by much more.
|
* decrease by at least min_offset_change but preferably by much more.
|
||||||
* We choose half of the available space.
|
* We choose half of the available space.
|
||||||
* If raid_disks is decreasing, data_offset must increase by
|
* If raid_disks is decreasing, data_offset must increase by
|
||||||
* at least backup_blocks. To allow of this, component_size
|
* at least min_offset_change. To allow of this, component_size
|
||||||
* must be decreased by the same amount.
|
* must be decreased by the same amount.
|
||||||
*
|
*
|
||||||
* So we calculate the required minimum and direction, possibly
|
* So we calculate the required minimum and direction, possibly
|
||||||
|
@ -2332,16 +2334,16 @@ static int raid10_reshape(char *container, int fd, char *devname,
|
||||||
devname);
|
devname);
|
||||||
goto release;
|
goto release;
|
||||||
}
|
}
|
||||||
min = reshape->backup_blocks;
|
min = reshape->min_offset_change;
|
||||||
|
|
||||||
if (info->delta_disks)
|
if (info->delta_disks)
|
||||||
sysfs_set_str(sra, NULL, "reshape_direction",
|
sysfs_set_str(sra, NULL, "reshape_direction",
|
||||||
info->delta_disks < 0 ? "backwards" : "forwards");
|
info->delta_disks < 0 ? "backwards" : "forwards");
|
||||||
if (info->delta_disks < 0 &&
|
if (info->delta_disks < 0 &&
|
||||||
info->space_after < reshape->backup_blocks) {
|
info->space_after < min) {
|
||||||
int rv = sysfs_set_num(sra, NULL, "component_size",
|
int rv = sysfs_set_num(sra, NULL, "component_size",
|
||||||
(sra->component_size -
|
(sra->component_size -
|
||||||
reshape->backup_blocks)/2);
|
min)/2);
|
||||||
if (rv) {
|
if (rv) {
|
||||||
pr_err("cannot reduce component size\n");
|
pr_err("cannot reduce component size\n");
|
||||||
goto release;
|
goto release;
|
||||||
|
|
5
mdadm.h
5
mdadm.h
|
@ -617,6 +617,10 @@ struct metadata_update;
|
||||||
* This will be a multiple of the stripe size in each of the
|
* This will be a multiple of the stripe size in each of the
|
||||||
* 'before' and 'after' geometries.
|
* 'before' and 'after' geometries.
|
||||||
* If 'blocks' is 0, no restriping is necessary.
|
* If 'blocks' is 0, no restriping is necessary.
|
||||||
|
* 'min_offset_change' is the minimum change to data_offset to
|
||||||
|
* allow the reshape to happen. It is at least the larger of
|
||||||
|
* the old and new chunk sizes, and typically the same as 'blocks'
|
||||||
|
* divided by number of data disks.
|
||||||
*/
|
*/
|
||||||
struct reshape {
|
struct reshape {
|
||||||
int level;
|
int level;
|
||||||
|
@ -626,6 +630,7 @@ struct reshape {
|
||||||
int data_disks;
|
int data_disks;
|
||||||
} before, after;
|
} before, after;
|
||||||
unsigned long long backup_blocks;
|
unsigned long long backup_blocks;
|
||||||
|
unsigned long long min_offset_change;
|
||||||
unsigned long long stripes; /* number of old stripes that comprise 'blocks'*/
|
unsigned long long stripes; /* number of old stripes that comprise 'blocks'*/
|
||||||
unsigned long long new_size; /* New size of array in sectors */
|
unsigned long long new_size; /* New size of array in sectors */
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue