]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Grow: use new_data_offset instead of backups for raid4/5/6 reshape.
authorNeilBrown <neilb@suse.de>
Tue, 21 May 2013 06:28:23 +0000 (16:28 +1000)
committerNeilBrown <neilb@suse.de>
Wed, 22 May 2013 02:22:36 +0000 (12:22 +1000)
If we can modify the data_offset, we can avoid doing any backups at all.
If we can't fall back on old approach - but not if --data-offset
 was requested.

Signed-off-by: NeilBrown <neilb@suse.de>
Grow.c

diff --git a/Grow.c b/Grow.c
index 4c4cad3acf1eb04b40a1df07e826575a0ffbd6d9..24bf6a9b011b68a708d5a308cecd03cc083c9b91 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -1438,6 +1438,7 @@ char *analyse_change(struct mdinfo *info, struct reshape *re)
                info->new_chunk, info->array.chunk_size,
                re->after.data_disks,
                re->before.data_disks);
+       re->min_offset_change = re->backup_blocks / re->before.data_disks;
 
        re->new_size = info->component_size * re->after.data_disks;
        return NULL;
@@ -2856,6 +2857,39 @@ started:
                goto release;
        }
 
+       switch(set_new_data_offset(sra, st, devname, info->delta_disks,
+                                  data_offset,
+                                  reshape.min_offset_change)) {
+       case -1:
+               goto release;
+       case 0:
+               /* Updated data_offset, so it's easy now */
+               update_cache_size(container, sra, info,
+                                 min(reshape.before.data_disks,
+                                     reshape.after.data_disks),
+                                 reshape.backup_blocks);
+
+               /* Right, everything seems fine. Let's kick things off.
+                */
+               sync_metadata(st);
+
+               if (impose_reshape(sra, info, st, fd, restart,
+                                  devname, container, &reshape) < 0)
+                       goto release;
+               if (sysfs_set_str(sra, NULL, "sync_action", "reshape") < 0) {
+                       pr_err("Failed to initiate reshape!\n");
+                       goto release;
+               }
+
+               return 0;
+       case 1: /* Couldn't set data_offset, try the old way */
+               if (data_offset != INVALID_SECTORS) {
+                       pr_err("Cannot update data_offset on this array\n");
+                       goto release;
+               }
+               break;
+       }
+
        /* Decide how many blocks (sectors) for a reshape
         * unit.  The number we have so far is just a minimum
         */