From: Adam Kwolek Date: Wed, 8 Jun 2011 07:09:09 +0000 (+1000) Subject: imsm: Check if array degradation has been changed X-Git-Tag: mdadm-3.2.2~58 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=b915c95fd3c37698b7e240b00830dbc0d576c16c;p=thirdparty%2Fmdadm.git imsm: Check if array degradation has been changed Before reshaping every "migration unit", check if array is still usable. In failed disks number is greater than allowed degradation level, reshape has to be aborted. Signed-off-by: Maciej Trela Signed-off-by: Adam Kwolek Signed-off-by: Krzysztof Wojcik Signed-off-by: NeilBrown --- diff --git a/super-intel.c b/super-intel.c index ca97bcc1..4b300244 100644 --- a/super-intel.c +++ b/super-intel.c @@ -8304,6 +8304,53 @@ int wait_for_reshape_imsm(struct mdinfo *sra, unsigned long long to_complete, } +/******************************************************************************* + * Function: check_degradation_change + * Description: Check that array hasn't become failed. + * Parameters: + * info : for sysfs access + * sources : source disks descriptors + * degraded: previous degradation level + * Returns: + * degradation level + ******************************************************************************/ +int check_degradation_change(struct mdinfo *info, + int *sources, + int degraded) +{ + unsigned long long new_degraded; + sysfs_get_ll(info, NULL, "degraded", &new_degraded); + if (new_degraded != (unsigned long long)degraded) { + /* check each device to ensure it is still working */ + struct mdinfo *sd; + new_degraded = 0; + for (sd = info->devs ; sd ; sd = sd->next) { + if (sd->disk.state & (1<disk.state & (1<disk.state = (1<disk.raid_disk >= 0 && + sources[sd->disk.raid_disk] >= 0) { + close(sources[ + sd->disk.raid_disk]); + sources[sd->disk.raid_disk] = + -1; + } + new_degraded++; + } + } + } + } + + return new_degraded; +} + /******************************************************************************* * Function: imsm_manage_reshape * Description: Function finds array under reshape and it manages reshape @@ -8348,6 +8395,7 @@ static int imsm_manage_reshape( unsigned long long start_src; /* [bytes] */ unsigned long long start; /* [bytes] */ unsigned long long start_buf_shift; /* [bytes] */ + int degraded = 0; if (!fds || !offsets || !destfd || !destoffsets || !sra) goto abort; @@ -8414,6 +8462,15 @@ static int imsm_manage_reshape( * __le32_to_cpu(migr_rec->curr_migr_unit); unsigned long long border; + /* Check that array hasn't become failed. + */ + degraded = check_degradation_change(sra, fds, degraded); + if (degraded > 1) { + dprintf("imsm: Abort reshape due to degradation" + " level (%i)\n", degraded); + goto abort; + } + next_step = __le32_to_cpu(migr_rec->blocks_per_unit); if ((current_position + next_step) > max_position)