diff options
-rw-r--r-- | drivers/md/md.c | 33 |
1 files changed, 21 insertions, 12 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c index 42b1d9ead7f2..dd64ad30a0fe 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c | |||
@@ -4016,19 +4016,24 @@ suspend_lo_store(mddev_t *mddev, const char *buf, size_t len) | |||
4016 | { | 4016 | { |
4017 | char *e; | 4017 | char *e; |
4018 | unsigned long long new = simple_strtoull(buf, &e, 10); | 4018 | unsigned long long new = simple_strtoull(buf, &e, 10); |
4019 | unsigned long long old = mddev->suspend_lo; | ||
4019 | 4020 | ||
4020 | if (mddev->pers == NULL || | 4021 | if (mddev->pers == NULL || |
4021 | mddev->pers->quiesce == NULL) | 4022 | mddev->pers->quiesce == NULL) |
4022 | return -EINVAL; | 4023 | return -EINVAL; |
4023 | if (buf == e || (*e && *e != '\n')) | 4024 | if (buf == e || (*e && *e != '\n')) |
4024 | return -EINVAL; | 4025 | return -EINVAL; |
4025 | if (new >= mddev->suspend_hi || | 4026 | |
4026 | (new > mddev->suspend_lo && new < mddev->suspend_hi)) { | 4027 | mddev->suspend_lo = new; |
4027 | mddev->suspend_lo = new; | 4028 | if (new >= old) |
4029 | /* Shrinking suspended region */ | ||
4028 | mddev->pers->quiesce(mddev, 2); | 4030 | mddev->pers->quiesce(mddev, 2); |
4029 | return len; | 4031 | else { |
4030 | } else | 4032 | /* Expanding suspended region - need to wait */ |
4031 | return -EINVAL; | 4033 | mddev->pers->quiesce(mddev, 1); |
4034 | mddev->pers->quiesce(mddev, 0); | ||
4035 | } | ||
4036 | return len; | ||
4032 | } | 4037 | } |
4033 | static struct md_sysfs_entry md_suspend_lo = | 4038 | static struct md_sysfs_entry md_suspend_lo = |
4034 | __ATTR(suspend_lo, S_IRUGO|S_IWUSR, suspend_lo_show, suspend_lo_store); | 4039 | __ATTR(suspend_lo, S_IRUGO|S_IWUSR, suspend_lo_show, suspend_lo_store); |
@@ -4045,20 +4050,24 @@ suspend_hi_store(mddev_t *mddev, const char *buf, size_t len) | |||
4045 | { | 4050 | { |
4046 | char *e; | 4051 | char *e; |
4047 | unsigned long long new = simple_strtoull(buf, &e, 10); | 4052 | unsigned long long new = simple_strtoull(buf, &e, 10); |
4053 | unsigned long long old = mddev->suspend_hi; | ||
4048 | 4054 | ||
4049 | if (mddev->pers == NULL || | 4055 | if (mddev->pers == NULL || |
4050 | mddev->pers->quiesce == NULL) | 4056 | mddev->pers->quiesce == NULL) |
4051 | return -EINVAL; | 4057 | return -EINVAL; |
4052 | if (buf == e || (*e && *e != '\n')) | 4058 | if (buf == e || (*e && *e != '\n')) |
4053 | return -EINVAL; | 4059 | return -EINVAL; |
4054 | if ((new <= mddev->suspend_lo && mddev->suspend_lo >= mddev->suspend_hi) || | 4060 | |
4055 | (new > mddev->suspend_lo && new > mddev->suspend_hi)) { | 4061 | mddev->suspend_hi = new; |
4056 | mddev->suspend_hi = new; | 4062 | if (new <= old) |
4063 | /* Shrinking suspended region */ | ||
4064 | mddev->pers->quiesce(mddev, 2); | ||
4065 | else { | ||
4066 | /* Expanding suspended region - need to wait */ | ||
4057 | mddev->pers->quiesce(mddev, 1); | 4067 | mddev->pers->quiesce(mddev, 1); |
4058 | mddev->pers->quiesce(mddev, 0); | 4068 | mddev->pers->quiesce(mddev, 0); |
4059 | return len; | 4069 | } |
4060 | } else | 4070 | return len; |
4061 | return -EINVAL; | ||
4062 | } | 4071 | } |
4063 | static struct md_sysfs_entry md_suspend_hi = | 4072 | static struct md_sysfs_entry md_suspend_hi = |
4064 | __ATTR(suspend_hi, S_IRUGO|S_IWUSR, suspend_hi_show, suspend_hi_store); | 4073 | __ATTR(suspend_hi, S_IRUGO|S_IWUSR, suspend_hi_show, suspend_hi_store); |