Add 'restart' arg to various functions used for reshaping.

When we restart an array in the middle of a reshape, we reuse a lot of
the code for starting the reshape, but it needs to know that
circumstances are slightly different.

So add a 'restart' arg which is used:
 - skip checking and adding spares
 - activate the array (rather than start reshape)
 - allow the backup file to already exist

Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
NeilBrown 2011-01-17 09:53:56 +11:00
parent 6d5316f66a
commit a93f87eee6
2 changed files with 26 additions and 11 deletions

34
Grow.c
View File

@ -792,7 +792,8 @@ int reshape_open_backup_file(char *backup_file,
char *devname,
long blocks,
int *fdlist,
unsigned long long *offsets)
unsigned long long *offsets,
int restart)
{
/* Return 1 on success, 0 on any form of failure */
/* need to check backup file is large enough */
@ -801,7 +802,7 @@ int reshape_open_backup_file(char *backup_file,
unsigned int dev;
int i;
*fdlist = open(backup_file, O_RDWR|O_CREAT|O_EXCL,
*fdlist = open(backup_file, O_RDWR|O_CREAT|(restart ? O_TRUNC : O_EXCL),
S_IRUSR | S_IWUSR);
*offsets = 8 * 512;
if (*fdlist < 0) {
@ -1245,7 +1246,8 @@ char *analyse_change(struct mdinfo *info, struct reshape *re)
static int reshape_array(char *container, int fd, char *devname,
struct supertype *st, struct mdinfo *info,
int force, char *backup_file, int quiet, int forked);
int force, char *backup_file, int quiet, int forked,
int restart);
static int reshape_container(char *container, int cfd, char *devname,
struct supertype *st,
struct mdinfo *info,
@ -1564,7 +1566,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
}
sync_metadata(st);
rv = reshape_array(container, fd, devname, st, &info, force,
backup_file, quiet, 0);
backup_file, quiet, 0, 0);
frozen = 0;
}
release:
@ -1576,7 +1578,8 @@ release:
static int reshape_array(char *container, int fd, char *devname,
struct supertype *st, struct mdinfo *info,
int force,
char *backup_file, int quiet, int forked)
char *backup_file, int quiet, int forked,
int restart)
{
struct reshape reshape;
int spares_needed;
@ -1607,6 +1610,13 @@ static int reshape_array(char *container, int fd, char *devname,
dprintf("Canot get array information.\n");
goto release;
}
if (restart) {
/* reshape already started. just skip to monitoring the reshape */
if (reshape.backup_blocks == 0)
return 0;
goto started;
}
spares_needed = max(reshape.before.data_disks,
reshape.after.data_disks)
+ reshape.parity - array.raid_disks;
@ -1752,7 +1762,7 @@ static int reshape_array(char *container, int fd, char *devname,
* - request the shape change.
* - fork to handle backup etc.
*/
started:
/* Check that we can hold all the data */
get_dev_size(fd, NULL, &array_size);
if (reshape.new_size < (array_size/512)) {
@ -1829,7 +1839,7 @@ static int reshape_array(char *container, int fd, char *devname,
} else {
if (!reshape_open_backup_file(backup_file, fd, devname,
(signed)blocks,
fdlist+d, offsets+d)) {
fdlist+d, offsets+d, restart)) {
goto release;
}
d++;
@ -1861,7 +1871,9 @@ static int reshape_array(char *container, int fd, char *devname,
sra->new_chunk = info->new_chunk;
if (info->array.chunk_size == info->new_chunk &&
if (info->reshape_active)
/* nothing needed here */;
else if (info->array.chunk_size == info->new_chunk &&
reshape.before.layout == reshape.after.layout &&
st->ss->external == 0) {
array.raid_disks = reshape.after.data_disks + reshape.parity;
@ -1908,6 +1920,8 @@ static int reshape_array(char *container, int fd, char *devname,
}
start_reshape(sra);
if (restart)
sysfs_set_str(sra, NULL, "array_state", "active");
/* Now we just need to kick off the reshape and watch, while
* handling backups of the data...
@ -2121,7 +2135,7 @@ int reshape_container(char *container, int cfd, char *devname,
rv = reshape_array(container, fd, adev, st,
content, force,
backup_file, quiet, 1);
backup_file, quiet, 1, 0);
close(fd);
if (rv)
break;
@ -3160,7 +3174,7 @@ int Grow_continue(int mdfd, struct supertype *st, struct mdinfo *info,
int err = sysfs_set_str(info, NULL, "array_state", "readonly");
if (err)
return err;
return reshape_array(NULL, mdfd, "array", st, info, 1, backup_file, 0, 0);
return reshape_array(NULL, mdfd, "array", st, info, 1, backup_file, 0, 0, 1);
}

View File

@ -492,7 +492,8 @@ extern int reshape_open_backup_file(char *backup,
char *devname,
long blocks,
int *fdlist,
unsigned long long *offsets);
unsigned long long *offsets,
int restart);
extern unsigned long compute_backup_blocks(int nchunk, int ochunk,
unsigned int ndata, unsigned int odata);