]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - mdadm.c
Add --data-offset flag for Create and Grow
[thirdparty/mdadm.git] / mdadm.c
diff --git a/mdadm.c b/mdadm.c
index 3ee7ddbaf17be98d7a59253c0ff6f762449c2031..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;
@@ -324,8 +325,15 @@ int main(int argc, char *argv[])
                        continue;
                }
                if (opt == 1) {
-                       /* an undecorated option - must be a device name.
+                       /* an undecorated option - must be a device name.
                         */
+
+                       if (devs_found > 0 && devmode == DetailPlatform) {
+                               pr_err("controller may only be specified once. %s ignored\n",
+                                               optarg);
+                               continue;
+                       }
+
                        if (devs_found > 0 && mode == MANAGE && !devmode) {
                                pr_err("Must give one of -a/-r/-f"
                                        " for subsequent devices at %s\n", optarg);
@@ -365,7 +373,8 @@ int main(int argc, char *argv[])
                                exit(2);
                        }
                        s.chunk = parse_size(optarg);
-                       if (s.chunk < 8 || (s.chunk&1)) {
+                       if (s.chunk == INVALID_SECTORS ||
+                           s.chunk < 8 || (s.chunk&1)) {
                                pr_err("invalid chunk/rounding value: %s\n",
                                        optarg);
                                exit(2);
@@ -419,7 +428,8 @@ int main(int argc, char *argv[])
                                s.size = MAX_SIZE;
                        else {
                                s.size = parse_size(optarg);
-                               if (s.size < 8) {
+                               if (s.size == INVALID_SECTORS ||
+                                   s.size < 8) {
                                        pr_err("invalid size: %s\n",
                                                optarg);
                                        exit(2);
@@ -439,7 +449,8 @@ int main(int argc, char *argv[])
                                array_size = MAX_SIZE;
                        else {
                                array_size = parse_size(optarg);
-                               if (array_size <= 0) {
+                               if (array_size == 0 ||
+                                   array_size == INVALID_SECTORS) {
                                        pr_err("invalid array size: %s\n",
                                                optarg);
                                        exit(2);
@@ -447,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*/
@@ -713,6 +739,10 @@ int main(int argc, char *argv[])
                                continue;
                        if (strcmp(c.update, "no-bitmap")==0)
                                continue;
+                       if (strcmp(c.update, "bbl") == 0)
+                               continue;
+                       if (strcmp(c.update, "no-bbl") == 0)
+                               continue;
                        if (strcmp(c.update, "byteorder")==0) {
                                if (ss) {
                                        pr_err("must not set metadata"
@@ -760,8 +790,10 @@ int main(int argc, char *argv[])
                                exit(2);
                        }
                        c.update = optarg;
-                       if (strcmp(c.update, "devicesize") != 0) {
-                               pr_err("only 'devicesize' can be"
+                       if (strcmp(c.update, "devicesize") != 0 &&
+                           strcmp(c.update, "bbl") != 0 &&
+                           strcmp(c.update, "no-bbl") != 0) {
+                               pr_err("only 'devicesize', 'bbl' and 'no-bbl' can be"
                                        " updated with --re-add\n");
                                exit(2);
                        }
@@ -1049,7 +1081,8 @@ int main(int argc, char *argv[])
                case O(BUILD,BitmapChunk):
                case O(CREATE,BitmapChunk): /* bitmap chunksize */
                        s.bitmap_chunk = parse_size(optarg);
-                       if (s.bitmap_chunk <= 0 ||
+                       if (s.bitmap_chunk == 0 ||
+                           s.bitmap_chunk == INVALID_SECTORS ||
                            s.bitmap_chunk & (s.bitmap_chunk - 1)) {
                                pr_err("invalid bitmap chunksize: %s\n",
                                       optarg);
@@ -1328,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') {
@@ -1344,7 +1377,9 @@ int main(int argc, char *argv[])
                        }
                        rv = Examine(devlist, &c, ss);
                } else if (devmode == DetailPlatform) {
-                       rv = Detail_Platform(ss ? ss->ss : NULL, ss ? c.scan : 1, c.verbose, c.export);
+                       rv = Detail_Platform(ss ? ss->ss : NULL, ss ? c.scan : 1,
+                                            c.verbose, c.export,
+                                            devlist ? devlist->devname : NULL);
                } else if (devlist == NULL) {
                        if (devmode == 'S' && c.scan)
                                rv = stop_scan(c.verbose);
@@ -1450,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;