summaryrefslogtreecommitdiff
path: root/Grow.c
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-06-27 10:20:34 +1000
committerNeilBrown <neilb@suse.de>2013-06-27 12:58:16 +1000
commit6a23fb9d0d21e8fc7cb37f60e988c73ff31458e0 (patch)
treef57f376e64d7be04f95b2e4caa7ce3f1a2d7983c /Grow.c
parenta73b00811cf8b0c36bcf66c356951857fb37ce77 (diff)
Grow: lack of head/tail space not fatal for RAID5 etc.
For RAID10, we must have head/tail space for reshape. For RAID4/5/6 we can use a spare or a backup file. So make that distinction. Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'Grow.c')
-rw-r--r--Grow.c16
1 files changed, 13 insertions, 3 deletions
diff --git a/Grow.c b/Grow.c
index d939850c..8e4594d6 100644
--- a/Grow.c
+++ b/Grow.c
@@ -2202,7 +2202,8 @@ static unsigned long long choose_offset(unsigned long long lo,
static int set_new_data_offset(struct mdinfo *sra, struct supertype *st,
char *devname, int delta_disks,
unsigned long long data_offset,
- unsigned long long min)
+ unsigned long long min,
+ int can_fallback)
{
struct mdinfo *sd;
int dir = 0;
@@ -2298,6 +2299,8 @@ static int set_new_data_offset(struct mdinfo *sra, struct supertype *st,
} else if (delta_disks > 0) {
/* need space before */
if (before < min) {
+ if (can_fallback)
+ goto fallback;
pr_err("Insufficient head-space for reshape on %s\n",
dn);
goto release;
@@ -2328,6 +2331,8 @@ static int set_new_data_offset(struct mdinfo *sra, struct supertype *st,
if (dir > 0) {
/* Increase data offset */
if (after < min) {
+ if (can_fallback)
+ goto fallback;
pr_err("Insufficient tail-space for reshape on %s\n",
dn);
goto release;
@@ -2348,6 +2353,8 @@ static int set_new_data_offset(struct mdinfo *sra, struct supertype *st,
} else {
/* Decrease data offset */
if (before < min) {
+ if (can_fallback)
+ goto fallback;
pr_err("insufficient head-room on %s\n",
dn);
goto release;
@@ -2402,6 +2409,9 @@ static int set_new_data_offset(struct mdinfo *sra, struct supertype *st,
return err;
release:
return -1;
+fallback:
+ /* Just use a backup file */
+ return 1;
}
static int raid10_reshape(char *container, int fd, char *devname,
@@ -2458,7 +2468,7 @@ static int raid10_reshape(char *container, int fd, char *devname,
}
}
err = set_new_data_offset(sra, st, devname, info->delta_disks, data_offset,
- min);
+ min, 0);
if (err == 1) {
pr_err("Cannot set new_data_offset: RAID10 reshape not\n");
cont_err("supported on this kernel\n");
@@ -3048,7 +3058,7 @@ static int reshape_array(char *container, int fd, char *devname,
switch(set_new_data_offset(sra, st, devname,
reshape.after.data_disks - reshape.before.data_disks,
data_offset,
- reshape.min_offset_change)) {
+ reshape.min_offset_change, 1)) {
case -1:
goto release;
case 0: