diff options
author | NeilBrown <neilb@suse.de> | 2013-05-23 07:48:48 +0200 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2013-05-28 08:44:23 +0200 |
commit | 199f1a1fadcd0fb5efba656ad92a44c51f8cc8ea (patch) | |
tree | 5f85a1db5fb927b5a33643c621ff64f60ffb4c3f | |
parent | Assemble: --update=metadata converts v0.90 to v1.0 (diff) | |
download | mdadm-199f1a1fadcd0fb5efba656ad92a44c51f8cc8ea.tar.xz mdadm-199f1a1fadcd0fb5efba656ad92a44c51f8cc8ea.zip |
Assemble: allow --update=revert-reshape
This will cause a reshape to start going backwards.
-rw-r--r-- | Grow.c | 3 | ||||
-rw-r--r-- | mdadm.c | 4 | ||||
-rw-r--r-- | mdadm.h | 5 | ||||
-rw-r--r-- | super0.c | 22 | ||||
-rw-r--r-- | super1.c | 29 |
5 files changed, 61 insertions, 2 deletions
@@ -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: @@ -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'): @@ -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, @@ -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) @@ -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) |