+ } else if (strncmp(update, "revert-reshape", 14) == 0) {
+ rv = -2;
+ if (!(sb->feature_map &
+ __cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE)))
+ pr_err("No active reshape to revert on %s\n",
+ devname);
+ else {
+ __u32 temp;
+ unsigned long long reshape_sectors;
+ long reshape_chunk;
+ rv = 0;
+ /* If the reshape hasn't started, just stop it.
+ * It is conceivable that a stripe was modified but
+ * the metadata not updated. In that case the backup
+ * should have been used to get passed the critical stage.
+ * If that couldn't happen, the "-nobackup" version
+ * will be used.
+ */
+ if (strcmp(update, "revert-reshape-nobackup") == 0 &&
+ sb->reshape_position == 0 &&
+ (__le32_to_cpu(sb->delta_disks) > 0 ||
+ (__le32_to_cpu(sb->delta_disks) == 0 &&
+ !(sb->feature_map & __cpu_to_le32(MD_FEATURE_RESHAPE_BACKWARDS))))) {
+ sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_RESHAPE_ACTIVE);
+ sb->raid_disks = __cpu_to_le32(__le32_to_cpu(sb->raid_disks) -
+ __le32_to_cpu(sb->delta_disks));
+ sb->delta_disks = 0;
+ goto done;
+ }
+ /* reshape_position is a little messy.
+ * Its value must be a multiple of the larger
+ * chunk size, and of the "after" data disks.
+ * So when reverting we need to change it to
+ * be a multiple of the new "after" data disks,
+ * which is the old "before".
+ * If it isn't already a multiple of 'before',
+ * the only thing we could do would be
+ * copy some block around on the disks, which
+ * is easy to get wrong.
+ * So we reject a revert-reshape unless the
+ * alignment is good.
+ */
+ if (__le32_to_cpu(sb->level) >= 4 &&
+ __le32_to_cpu(sb->level) <= 6) {
+ reshape_sectors =
+ __le64_to_cpu(sb->reshape_position);
+ reshape_chunk = __le32_to_cpu(sb->new_chunk);
+ reshape_chunk *= __le32_to_cpu(sb->raid_disks) -
+ __le32_to_cpu(sb->delta_disks) -
+ (__le32_to_cpu(sb->level)==6 ? 2 : 1);
+ if (reshape_sectors % reshape_chunk) {
+ pr_err("Reshape position is not suitably aligned.\n");
+ pr_err("Try normal assembly and stop again\n");
+ return -2;
+ }
+ }
+ sb->raid_disks =
+ __cpu_to_le32(__le32_to_cpu(sb->raid_disks) -
+ __le32_to_cpu(sb->delta_disks));
+ if (sb->delta_disks == 0)
+ sb->feature_map ^= __cpu_to_le32(MD_FEATURE_RESHAPE_BACKWARDS);
+ else
+ sb->delta_disks = __cpu_to_le32(-__le32_to_cpu(sb->delta_disks));
+
+ temp = sb->new_layout;
+ sb->new_layout = sb->layout;
+ sb->layout = temp;
+
+ temp = sb->new_chunk;
+ sb->new_chunk = sb->chunksize;
+ sb->chunksize = temp;
+
+ if (sb->feature_map &
+ __cpu_to_le32(MD_FEATURE_NEW_OFFSET)) {
+ long offset_delta =
+ (int32_t)__le32_to_cpu(sb->new_offset);
+ sb->data_offset = __cpu_to_le64(__le64_to_cpu(sb->data_offset) + offset_delta);
+ sb->new_offset = __cpu_to_le32(-offset_delta);
+ sb->data_size = __cpu_to_le64(__le64_to_cpu(sb->data_size) - offset_delta);
+ }
+ done:;
+ }
+ } else if (strcmp(update, "_reshape_progress") == 0)