From 6a23fb9d0d21e8fc7cb37f60e988c73ff31458e0 Mon Sep 17 00:00:00 2001 From: NeilBrown Date: Thu, 27 Jun 2013 10:20:34 +1000 Subject: [PATCH] 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 --- Grow.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/Grow.c b/Grow.c index d939850..8e4594d 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: