diff options
author | NeilBrown <neilb@suse.de> | 2013-06-27 10:20:34 +1000 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2013-06-27 12:58:16 +1000 |
commit | 6a23fb9d0d21e8fc7cb37f60e988c73ff31458e0 (patch) | |
tree | f57f376e64d7be04f95b2e4caa7ce3f1a2d7983c /Grow.c | |
parent | a73b00811cf8b0c36bcf66c356951857fb37ce77 (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.c | 16 |
1 files changed, 13 insertions, 3 deletions
@@ -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: |