]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Add --data-offset flag for Create and Grow
authorNeilBrown <neilb@suse.de>
Thu, 4 Oct 2012 06:34:21 +0000 (16:34 +1000)
committerNeilBrown <neilb@suse.de>
Thu, 4 Oct 2012 06:34:21 +0000 (16:34 +1000)
This can be used to over-ride the automatic assignment of
data offset.
For --create, it is useful to re-create old arrays where different
   defaults applied.
For --grow it may be able to force a reshape in the reverse direction.

Signed-off-by: NeilBrown <neilb@suse.de>
Create.c
Grow.c
ReadMe.c
mdadm.8.in
mdadm.c
mdadm.h

index 42c92acb871ef4399b2d0bac7bb37a67adfe8494..91c641f55ce718041740dbd7793bb5021db0609c 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -65,7 +65,7 @@ int Create(struct supertype *st, char *mddev,
           char *name, int *uuid,
           int subdevs, struct mddev_dev *devlist,
           struct shape *s,
-          struct context *c)
+          struct context *c, unsigned long long data_offset)
 {
        /*
         * Create a new raid array.
@@ -252,7 +252,7 @@ int Create(struct supertype *st, char *mddev,
        newsize = s->size * 2;
        if (st && ! st->ss->validate_geometry(st, s->level, s->layout, s->raiddisks,
                                              &s->chunk, s->size*2,
-                                             INVALID_SECTORS, NULL,
+                                             data_offset, NULL,
                                              &newsize, c->verbose>=0))
                return 1;
 
@@ -335,7 +335,7 @@ int Create(struct supertype *st, char *mddev,
                                switch (st->ss->validate_geometry(
                                                st, s->level, s->layout, s->raiddisks,
                                                &s->chunk, s->size*2,
-                                               INVALID_SECTORS, dname,
+                                               data_offset, dname,
                                                &freesize, c->verbose > 0)) {
                                case -1: /* Not valid, message printed, and not
                                          * worth checking any further */
@@ -372,7 +372,7 @@ int Create(struct supertype *st, char *mddev,
                        if (!st->ss->validate_geometry(st, s->level, s->layout,
                                                       s->raiddisks,
                                                       &s->chunk, s->size*2,
-                                                      INVALID_SECTORS,
+                                                      data_offset,
                                                       dname, &freesize,
                                                       c->verbose >= 0)) {
 
@@ -474,7 +474,7 @@ int Create(struct supertype *st, char *mddev,
                        if (!st->ss->validate_geometry(st, s->level, s->layout,
                                                       s->raiddisks,
                                                       &s->chunk, minsize*2,
-                                                      INVALID_SECTORS,
+                                                      data_offset,
                                                       NULL, NULL, 0)) {
                                pr_err("devices too large for RAID level %d\n", s->level);
                                return 1;
@@ -682,7 +682,7 @@ int Create(struct supertype *st, char *mddev,
                }
        }
        if (!st->ss->init_super(st, &info.array, s->size, name, c->homehost, uuid,
-                               INVALID_SECTORS))
+                               data_offset))
                goto abort_locked;
 
        total_slots = info.array.nr_disks;
diff --git a/Grow.c b/Grow.c
index 18fb3ee154a943edf47a656e0b13e464e8c26238..f6fe1683234f2393f23dabf4e74dd1dc31e0b9e9 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -1440,6 +1440,7 @@ static int reshape_container(char *container, char *devname,
 
 int Grow_reshape(char *devname, int fd,
                 struct mddev_dev *devlist,
+                unsigned long long data_offset,
                 struct context *c, struct shape *s)
 {
        /* Make some changes in the shape of an array.
@@ -1476,6 +1477,11 @@ int Grow_reshape(char *devname, int fd,
        struct mdinfo info;
        struct mdinfo *sra;
 
+       if (data_offset != INVALID_SECTORS) {
+               fprintf(stderr, Name ": --grow --data-offset not yet supported\n");
+               return 1;
+       }
+
        if (ioctl(fd, GET_ARRAY_INFO, &array) < 0) {
                pr_err("%s is not an active md array - aborting\n",
                        devname);
index 346f08cb5f773c8a3f1413152d516799af236e73..def75ec6c802f8a9575f63cc6aa4e93625a0dbd1 100644 (file)
--- a/ReadMe.c
+++ b/ReadMe.c
@@ -129,6 +129,7 @@ struct option long_options[] = {
     {"re-add",    0, 0,  ReAdd},
     {"homehost",  1, 0,  HomeHost},
     {"symlinks",  1, 0,  Symlinks},
+    {"data-offset",1, 0, DataOffset},
 
     /* For assemble */
     {"uuid",      1, 0, 'u'},
@@ -349,6 +350,8 @@ char Help_create[] =
 "  --raid-devices= -n : number of active devices in array\n"
 "  --spare-devices= -x: number of spare (eXtra) devices in initial array\n"
 "  --size=       -z   : Size (in K) of each drive in RAID1/4/5/6/10 - optional\n"
+"  --data-offset=     : Space to leave between start of device and start\n"
+"                     : of array data.\n"
 "  --force       -f   : Honour devices as listed on command line.  Don't\n"
 "                     : insert a missing drive for RAID5.\n"
 "  --run         -R   : insist of running the array even if not all\n"
@@ -545,6 +548,7 @@ char Help_grow[] =
 "                      : when changing parameters other than raid-devices\n"
 "  --array-size=  -Z   : Change visible size of array.  This does not change\n"
 "                      : any data on the device, and is not stable across restarts.\n"
+"  --data-offset=      : Location on device to move start of data to.\n"
 ;
 
 char Help_incr[] =
index 845c00cdb4732d3be497b4265058818ef5c22fe8..255b6505009f8143f6a71ec8cb6d7fce012fd6f2 100644 (file)
@@ -767,6 +767,34 @@ or layout.  See the GROW MODE section below on RAID\-DEVICES CHANGES.
 The file must be stored on a separate device, not on the RAID array
 being reshaped.
 
+.TP
+.B \-\-data\-offset=
+Arrays with 1.x metadata can leave a gap between the start of the
+device and the start of array data.  This gap can be used for various
+metadata.  The start of data is known as the
+.IR data\-offset .
+Normally an appropriate data offset is computed automatically.
+However it can be useful to set it explicitly such as when re-creating
+an array which was originally created using a different version of
+.I mdadm
+which computed a different offset.
+
+Setting the offset explicitly over-rides the default.  The value given
+is in Kilobytes unless an 'M' or 'G' suffix is given.
+
+Since Linux 3.4,
+.B \-\-data\-offset
+can also be used with
+.B --grow
+for some RAID levels (initially on RAID10).  This allows the
+data-offset to be changed as part of the reshape process.  When the
+data offset is changed, no backup file is required as the difference
+in offsets is used to provide the same functionality.
+
+When the new offset is earlier than the old offset, the number of
+devices in the array cannot shrink.  When it is after the old offset,
+the number of devices in the array cannot increase.
+
 .TP
 .BR \-\-continue
 This option is complementary to the
diff --git a/mdadm.c b/mdadm.c
index 51c57c5d06dabdb8a9d2c720440ba10b3095be00..5f395714e240307851b18ed51413ec8834a4c796 100644 (file)
--- a/mdadm.c
+++ b/mdadm.c
@@ -49,6 +49,7 @@ int main(int argc, char *argv[])
        int i;
 
        unsigned long long array_size = 0;
+       unsigned long long data_offset = INVALID_SECTORS;
        struct mddev_ident ident;
        char *configfile = NULL;
        int devmode = 0;
@@ -457,6 +458,21 @@ int main(int argc, char *argv[])
                        }
                        continue;
 
+               case O(CREATE,DataOffset):
+               case O(GROW,DataOffset):
+                       if (data_offset != INVALID_SECTORS) {
+                               fprintf(stderr, Name ": data-offset may only be specified one. "
+                                       "Second value is %s.\n", optarg);
+                               exit(2);
+                       }
+                       data_offset = parse_size(optarg);
+                       if (data_offset == INVALID_SECTORS) {
+                               fprintf(stderr, Name ": invalid data-offset: %s\n",
+                                       optarg);
+                               exit(2);
+                       }
+                       continue;
+
                case O(GROW,'l'):
                case O(CREATE,'l'):
                case O(BUILD,'l'): /* set raid level*/
@@ -1345,7 +1361,7 @@ int main(int argc, char *argv[])
                rv = Create(ss, devlist->devname,
                            ident.name, ident.uuid_set ? ident.uuid : NULL,
                            devs_found-1, devlist->next,
-                           &s, &c);
+                           &s, &c, data_offset);
                break;
        case MISC:
                if (devmode == 'E') {
@@ -1469,7 +1485,8 @@ int main(int argc, char *argv[])
                else if (s.size > 0 || s.raiddisks || s.layout_str != NULL
                         || s.chunk != 0 || s.level != UnSet) {
                        rv = Grow_reshape(devlist->devname, mdfd,
-                                         devlist->next, &c, &s);
+                                         devlist->next,
+                                         data_offset, &c, &s);
                } else if (array_size == 0)
                        pr_err("no changes to --grow\n");
                break;
diff --git a/mdadm.h b/mdadm.h
index 425cac396a85db765a8a1793e8342d4759b20ffa..79c47be41afcbed146cef873347c7fef9d428423 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -326,6 +326,7 @@ enum special_options {
        OffRootOpt,
        Prefer,
        KillOpt,
+       DataOffset,
 };
 
 enum prefix_standard {
@@ -1099,6 +1100,7 @@ extern int Grow_addbitmap(char *devname, int fd,
                          struct context *c, struct shape *s);
 extern int Grow_reshape(char *devname, int fd,
                        struct mddev_dev *devlist,
+                       unsigned long long data_offset,
                        struct context *c, struct shape *s);
 extern int Grow_restart(struct supertype *st, struct mdinfo *info,
                        int *fdlist, int cnt, char *backup_file, int verbose);
@@ -1127,7 +1129,8 @@ extern int Create(struct supertype *st, char *mddev,
                  char *name, int *uuid,
                  int subdevs, struct mddev_dev *devlist,
                  struct shape *s,
-                 struct context *c);
+                 struct context *c,
+                 unsigned long long data_offset);
 
 extern int Detail(char *dev, struct context *c);
 extern int Detail_Platform(struct superswitch *ss, int scan, int verbose, int export, char *controller_path);