summaryrefslogtreecommitdiff
path: root/drivers/md
diff options
context:
space:
mode:
authorHeinz Mauelshagen <heinzm@redhat.com>2017-12-02 03:03:52 +0300
committerMike Snitzer <snitzer@redhat.com>2017-12-08 18:59:57 +0300
commitd39f0010e40964d959c5157be02839da8a178015 (patch)
treed0d8ed8c121f50b383c84a6af4931d67b36e2990 /drivers/md
parent188a212df1f3a2d7ea9bb0fc0ab4173042c23470 (diff)
downloadlinux-d39f0010e40964d959c5157be02839da8a178015.tar.xz
dm raid: fix raid_resume() to keep raid set frozen as needed
During a reshape request: if userspace reloads a "raid" table multiple times, resulting in multiple superblock reads, the raid set needs to stay frozen until all config changes (chunk size, layout data_offset, delta_disks) have been stored in the superblocks and respective flags cleared. Signed-off-by: Heinz Mauelshagen <heinzm@redhat.com> Signed-off-by: Mike Snitzer <snitzer@redhat.com>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/dm-raid.c12
1 files changed, 9 insertions, 3 deletions
diff --git a/drivers/md/dm-raid.c b/drivers/md/dm-raid.c
index 2bb0ac7c3fba..bf3c9e3c736d 100644
--- a/drivers/md/dm-raid.c
+++ b/drivers/md/dm-raid.c
@@ -3899,7 +3899,7 @@ static int raid_preresume(struct dm_target *ti)
}
/* Check for any reshape request unless new raid set */
- if (test_and_clear_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags)) {
+ if (test_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags)) {
/* Initiate a reshape. */
rs_set_rdev_sectors(rs);
mddev_lock_nointr(mddev);
@@ -3941,8 +3941,14 @@ static void raid_resume(struct dm_target *ti)
* This ensures that the constructor for the inactive table
* retrieves an up-to-date reshape_position.
*/
- if (!(rs->ctr_flags & RESUME_STAY_FROZEN_FLAGS))
- clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+ if (!test_and_clear_bit(RT_FLAG_RESHAPE_RS, &rs->runtime_flags) &&
+ !(rs->ctr_flags & RESUME_STAY_FROZEN_FLAGS)) {
+ if (rs_is_reshapable(rs)) {
+ if (!rs_is_reshaping(rs) || _get_reshape_sectors(rs))
+ clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+ } else
+ clear_bit(MD_RECOVERY_FROZEN, &mddev->recovery);
+ }
if (test_and_clear_bit(RT_FLAG_RS_SUSPENDED, &rs->runtime_flags)) {
mddev_lock_nointr(mddev);