dm raid: fix raid_resume() to keep raid set frozen as needed
authorHeinz Mauelshagen <heinzm@redhat.com>
Sat, 2 Dec 2017 00:03:52 +0000 (01:03 +0100)
committerMike Snitzer <snitzer@redhat.com>
Fri, 8 Dec 2017 15:59:57 +0000 (10:59 -0500)
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>
drivers/md/dm-raid.c

index 2bb0ac7c3fba07ac99018053948c7b5f0e0a92e6..bf3c9e3c736dee14c2e772e5b4f930ab48ab41aa 100644 (file)
@@ -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);