summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukasz Dorau <lukasz.dorau@intel.com>2012-05-25 15:06:41 +0200
committerNeilBrown <neilb@suse.de>2012-09-27 16:49:54 +1000
commit42f0ca1e1a455d186a9d5ae6822d42e8def64524 (patch)
tree2e47d31441d58659443f094066fbd7404606d0df
parent0d478e243a90a48fe4da581c7302771f0d66fb3b (diff)
downloadmdadm-42f0ca1e1a455d186a9d5ae6822d42e8def64524.tar.gz
imsm: fix: correct checking volume's degradation
We do not check the return value of sysfs_get_ll() now. It is wrong. If reading of the sysfs "degraded" key does not succeed, the "new_degraded" variable will not be initiated and accidentally it can have the value of "degraded" variable. In that case the change of degradation will not be checked. It happens if mdadm is compiled with gcc's "-fstack-protector" option when one tries to stop a volume under reshape (e.g. OLCE). Reshape seems to be finished then (metadata is in normal/clean state) but it is not finished, it is broken and data are corrupted. Now we always check the return value of sysfs_get_ll(). Even if reading of the sysfs "degraded" key does not succeed (rv == -1) the change of degradation will be checked. Signed-off-by: Lukasz Dorau <lukasz.dorau@intel.com> Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--super-intel.c6
1 files changed, 4 insertions, 2 deletions
diff --git a/super-intel.c b/super-intel.c
index 6c87e20..07ab9ae 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -10370,8 +10370,10 @@ int check_degradation_change(struct mdinfo *info,
int degraded)
{
unsigned long long new_degraded;
- sysfs_get_ll(info, NULL, "degraded", &new_degraded);
- if (new_degraded != (unsigned long long)degraded) {
+ int rv;
+
+ rv = sysfs_get_ll(info, NULL, "degraded", &new_degraded);
+ if ((rv == -1) || (new_degraded != (unsigned long long)degraded)) {
/* check each device to ensure it is still working */
struct mdinfo *sd;
new_degraded = 0;