]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Assemble: allow --update=revert-reshape
authorNeilBrown <neilb@suse.de>
Thu, 23 May 2013 05:48:48 +0000 (15:48 +1000)
committerNeilBrown <neilb@suse.de>
Tue, 28 May 2013 06:44:23 +0000 (16:44 +1000)
This will cause a reshape to start going backwards.

Grow.c
mdadm.c
mdadm.h
super0.c
super1.c

diff --git a/Grow.c b/Grow.c
index 7b9cc70e2fdfe1db46d7f0088743fe166feb63bd..2eb8c7ce042bd6b224547e1d9eb2b3cd8aec30fe 100644 (file)
--- 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 83f1caa90f83fe4dee8cbed00124045378772487..928d880bab64777a06e6af46d9afacf2bfd9b819 100644 (file)
--- 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 d97055ae4f666c54c64351e4e3e86a9cdd22ad22..b7af65dcb74556b6c5dba1a07a6dcbf312f3d292 100644 (file)
--- 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,
index 01c31c27b7ce731129397d5b4821d83067d4be17..e4bbe3e1a0f9585c5d65b4e4813c8a2aeaae574e 100644 (file)
--- 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)
index a4677b9bbb91d0f3ddfe3ff06a45322a2a5e9d81..d92e59455af279d682aebc1db3574e207fe14327 100644 (file)
--- 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)