summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2013-05-23 07:48:48 +0200
committerNeilBrown <neilb@suse.de>2013-05-28 08:44:23 +0200
commit199f1a1fadcd0fb5efba656ad92a44c51f8cc8ea (patch)
tree5f85a1db5fb927b5a33643c621ff64f60ffb4c3f
parentAssemble: --update=metadata converts v0.90 to v1.0 (diff)
downloadmdadm-199f1a1fadcd0fb5efba656ad92a44c51f8cc8ea.tar.xz
mdadm-199f1a1fadcd0fb5efba656ad92a44c51f8cc8ea.zip
Assemble: allow --update=revert-reshape
This will cause a reshape to start going backwards.
-rw-r--r--Grow.c3
-rw-r--r--mdadm.c4
-rw-r--r--mdadm.h5
-rw-r--r--super0.c22
-rw-r--r--super1.c29
5 files changed, 61 insertions, 2 deletions
diff --git a/Grow.c b/Grow.c
index 7b9cc70e..2eb8c7ce 100644
--- a/Grow.c
+++ b/Grow.c
@@ -2876,7 +2876,8 @@ started:
}
if (!backup_file)
- switch(set_new_data_offset(sra, st, devname, info->delta_disks,
+ switch(set_new_data_offset(sra, st, devname,
+ reshape.after.data_disks - reshape.before.data_disks,
data_offset,
reshape.min_offset_change)) {
case -1:
diff --git a/mdadm.c b/mdadm.c
index 83f1caa9..928d880b 100644
--- a/mdadm.c
+++ b/mdadm.c
@@ -757,6 +757,8 @@ int main(int argc, char *argv[])
continue;
if (strcmp(c.update, "metadata") == 0)
continue;
+ if (strcmp(c.update, "revert-reshape") == 0)
+ continue;
if (strcmp(c.update, "byteorder")==0) {
if (ss) {
pr_err("must not set metadata"
@@ -787,7 +789,7 @@ int main(int argc, char *argv[])
fprintf(outf, "Valid --update options are:\n"
" 'sparc2.2', 'super-minor', 'uuid', 'name', 'resync',\n"
" 'summaries', 'homehost', 'byteorder', 'devicesize',\n"
- " 'no-bitmap', 'metadata'\n");
+ " 'no-bitmap', 'metadata', 'revert-reshape'\n");
exit(outf == stdout ? 0 : 2);
case O(MANAGE,'U'):
diff --git a/mdadm.h b/mdadm.h
index d97055ae..b7af65dc 100644
--- a/mdadm.h
+++ b/mdadm.h
@@ -736,6 +736,11 @@ extern struct superswitch {
* linear-grow-update - now change the size of the array.
* writemostly - set the WriteMostly1 bit in the superblock devflags
* readwrite - clear the WriteMostly1 bit in the superblock devflags
+ * no-bitmap - clear any record that a bitmap is present.
+ * bbl - add a bad-block-log if possible
+ * no-bbl - remove and bad-block-log is it is empty.
+ * revert-reshape - If a reshape is in progress, modify metadata so
+ * it will resume going in the opposite direction.
*/
int (*update_super)(struct supertype *st, struct mdinfo *info,
char *update,
diff --git a/super0.c b/super0.c
index 01c31c27..e4bbe3e1 100644
--- a/super0.c
+++ b/super0.c
@@ -645,6 +645,28 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
uuid_from_super0(st, info->uuid);
st->other = super1_make_v0(st, info, st->sb);
}
+ } else if (strcmp(update, "revert-reshape") == 0) {
+ rv = -2;
+ if (sb->minor_version <= 90)
+ pr_err("No active reshape to revert on %s\n",
+ devname);
+ else if (sb->delta_disks == 0)
+ pr_err("%s: Can on revert reshape which changes number of devices\n",
+ devname);
+ else {
+ int tmp;
+ rv = 0;
+ sb->raid_disks -= sb->delta_disks;
+ sb->delta_disks = -sb->delta_disks;
+
+ tmp = sb->new_layout;
+ sb->new_layout = sb->layout;
+ sb->layout = tmp;
+
+ tmp = sb->new_chunk;
+ sb->new_chunk = sb->chunk_size;
+ sb->chunk_size = tmp;
+ }
} else if (strcmp(update, "no-bitmap") == 0) {
sb->state &= ~(1<<MD_SB_BITMAP_PRESENT);
} else if (strcmp(update, "_reshape_progress")==0)
diff --git a/super1.c b/super1.c
index a4677b9b..d92e5945 100644
--- a/super1.c
+++ b/super1.c
@@ -1252,6 +1252,35 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
misc->device_size - __le64_to_cpu(sb->data_offset));
printf("Size is %llu\n", (unsigned long long)
__le64_to_cpu(sb->data_size));
+ } else if (strcmp(update, "revert-reshape") == 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 {
+ rv = 0;
+ __u32 temp;
+ 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)) {
+ sb->data_offset = __cpu_to_le64(__le64_to_cpu(sb->data_offset) +
+ (long)(int32_t)__le32_to_cpu(sb->new_offset));
+ sb->new_offset = __cpu_to_le32(-(int32_t)__le32_to_cpu(sb->new_offset));
+ }
+ }
} else if (strcmp(update, "_reshape_progress")==0)
sb->reshape_position = __cpu_to_le64(info->reshape_progress);
else if (strcmp(update, "writemostly")==0)