From b915c95fd3c37698b7e240b00830dbc0d576c16c Mon Sep 17 00:00:00 2001 From: Adam Kwolek Date: Wed, 8 Jun 2011 17:09:09 +1000 Subject: [PATCH] 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 --- super-intel.c | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/super-intel.c b/super-intel.c index ca97bcc..4b30024 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)