]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Allow data-offset to be specified per-device for create
authorNeilBrown <neilb@suse.de>
Mon, 4 Jun 2012 22:50:44 +0000 (08:50 +1000)
committerNeilBrown <neilb@suse.de>
Mon, 4 Jun 2012 22:50:44 +0000 (08:50 +1000)
 mdadm --create /dev/md0 .... /dev/sda1:1024 /dev/sdb1:2048 ...

The size is in K unless a suffix: K M G is given.
The suffix 's' means sectors.

Signed-off-by: NeilBrown <neilb@suse.de>
Create.c
Manage.c
managemon.c
mdadm.h
super-ddf.c
super-intel.c
super0.c
super1.c
util.c

index b4b680477039a101312816034ba2abab64544d80..f49163176ba9ba6221b35ca108de1c0fa4c812b3 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -301,6 +301,7 @@ int Create(struct supertype *st, char *mddev,
                char *dname = dv->devname;
                unsigned long long freesize;
                int dfd;
+               char *doff;
 
                if (strcasecmp(dname, "missing")==0) {
                        if (first_missing > dnum)
@@ -310,6 +311,13 @@ int Create(struct supertype *st, char *mddev,
                        missing_disks ++;
                        continue;
                }
+               doff = strchr(dname, ':');
+               if (doff) {
+                       *doff++ = 0;
+                       dv->data_offset = parse_size(doff);
+               } else
+                       dv->data_offset = data_offset;
+
                dfd = open(dname, O_RDONLY);
                if (dfd < 0) {
                        fprintf(stderr, Name ": cannot open %s: %s\n",
@@ -346,7 +354,7 @@ int Create(struct supertype *st, char *mddev,
                                        layout = default_layout(st, level, verbose);
                                switch (st->ss->validate_geometry(
                                                st, level, layout, raiddisks,
-                                               &chunk, size*2, data_offset, dname,
+                                               &chunk, size*2, dv->data_offset, dname,
                                                &freesize, verbose > 0)) {
                                case -1: /* Not valid, message printed, and not
                                          * worth checking any further */
@@ -382,7 +390,7 @@ int Create(struct supertype *st, char *mddev,
                                layout = default_layout(st, level, 0);
                        if (!st->ss->validate_geometry(st, level, layout,
                                                       raiddisks,
-                                                      &chunk, size*2, data_offset,
+                                                      &chunk, size*2, dv->data_offset,
                                                       dname, &freesize,
                                                       verbose >= 0)) {
 
@@ -883,7 +891,8 @@ int Create(struct supertype *st, char *mddev,
                                if (fd >= 0)
                                        remove_partitions(fd);
                                if (st->ss->add_to_super(st, &inf->disk,
-                                                        fd, dv->devname)) {
+                                                        fd, dv->devname,
+                                                        dv->data_offset)) {
                                        ioctl(mdfd, STOP_ARRAY, NULL);
                                        goto abort;
                                }
index d51a93cef8a428e786e62d567dfd67140d0634ea..8c49ef690c203381f619497fd0472ec52312403d 100644 (file)
--- a/Manage.c
+++ b/Manage.c
@@ -945,7 +945,7 @@ int Manage_subdevs(char *devname, int fd,
                                        disc.state |= 1 << MD_DISK_WRITEMOSTLY;
                                dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT);
                                if (tst->ss->add_to_super(tst, &disc, dfd,
-                                                         dv->devname)) {
+                                                         dv->devname, -1)) {
                                        close(dfd);
                                        goto abort;
                                }
@@ -1007,7 +1007,7 @@ int Manage_subdevs(char *devname, int fd,
                                if (mdmon_running(tst->container_dev))
                                        tst->update_tail = &tst->updates;
                                if (tst->ss->add_to_super(tst, &disc, dfd,
-                                                         dv->devname)) {
+                                                         dv->devname, -1)) {
                                        close(dfd);
                                        close(container_fd);
                                        goto abort;
index 6c21ecbd229ade70bd16c210c21af527e28571a0..1ebaf2a3b033a5231449390bf268552dda02306e 100644 (file)
@@ -304,7 +304,7 @@ static void add_disk_to_container(struct supertype *st, struct mdinfo *sd)
        st2->ss->free_super(st2);
 
        st->update_tail = &update;
-       st->ss->add_to_super(st, &dk, dfd, NULL);
+       st->ss->add_to_super(st, &dk, dfd, NULL, -1);
        st->ss->write_init_super(st);
        queue_metadata_update(update);
        st->update_tail = NULL;
diff --git a/mdadm.h b/mdadm.h
index abe7c3c1060b6244c607c8a8c3ea3d7db9a7e8cc..40f600b63fc36aaeb7e18033b0af63ff51243379 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -389,6 +389,7 @@ struct mddev_dev {
        char writemostly;       /* 1 for 'set writemostly', 2 for 'clear writemostly' */
        char re_add;
        char used;              /* set when used */
+       long long data_offset;
        struct mddev_dev *next;
 };
 
@@ -696,7 +697,7 @@ extern struct superswitch {
         * when hot-adding a spare.
         */
        int (*add_to_super)(struct supertype *st, mdu_disk_info_t *dinfo,
-                           int fd, char *devname);
+                           int fd, char *devname, long long data_offset);
        /* update the metadata to delete a device,
         * when hot-removing.
         */
index 6225a6fbe4f49e82ce3467766b0bfe2177ee2b2c..f523ebe37d385d014322732146f15082c2cde2b7 100644 (file)
@@ -2191,7 +2191,8 @@ static void add_to_super_ddf_bvd(struct supertype *st,
  * expanding a pre-existing container
  */
 static int add_to_super_ddf(struct supertype *st,
-                            mdu_disk_info_t *dk, int fd, char *devname)
+                           mdu_disk_info_t *dk, int fd, char *devname,
+                           long long data_offset)
 {
        struct ddf_super *ddf = st->sb;
        struct dl *dd;
index e09fc6092e2bf9c8d5a29ffff30bb17c5e8f9a32..c91adf2a3f556a9119a3848b371606b8d93ab41f 100644 (file)
@@ -4945,7 +4945,7 @@ int mark_spare(struct dl *disk)
 }
 
 static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
-                            int fd, char *devname)
+                            int fd, char *devname, long long data_offset)
 {
        struct intel_super *super = st->sb;
        struct dl *dd;
index ebebc491ae7ec42d57f7639ced7fa82c5da03e16..9aca4de854596b3e9d7cdd2467bb0a0246cd26db 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -695,7 +695,7 @@ struct devinfo {
 #ifndef MDASSEMBLE
 /* Add a device to the superblock being created */
 static int add_to_super0(struct supertype *st, mdu_disk_info_t *dinfo,
-                         int fd, char *devname)
+                        int fd, char *devname, long long data_offset)
 {
        mdp_super_t *sb = st->sb;
        mdp_disk_t *dk = &sb->disks[dinfo->number];
index 002c86170a9ad5770cf716287ed6a8432e72d191..871af3f0806de199a5cfef56070a5f48f583f2e3 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -1012,13 +1012,14 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info,
 struct devinfo {
        int fd;
        char *devname;
+       long long data_offset;
        mdu_disk_info_t disk;
        struct devinfo *next;
 };
 #ifndef MDASSEMBLE
 /* Add a device to the superblock being created */
 static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
-                         int fd, char *devname)
+                        int fd, char *devname, long long data_offset)
 {
        struct mdp_superblock_1 *sb = st->sb;
        __u16 *rp = sb->dev_roles + dk->number;
@@ -1046,6 +1047,7 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
        di->fd = fd;
        di->devname = devname;
        di->disk = *dk;
+       di->data_offset = data_offset;
        di->next = NULL;
        *dip = di;
 
@@ -1242,14 +1244,13 @@ static int write_init_super1(struct supertype *st)
                        headroom/2 >= __le32_to_cpu(sb->chunksize) * 2)
                        headroom >>= 1;
 
-
+               data_offset = di->data_offset;
                switch(st->minor_version) {
                case 0:
                        sb_offset = dsize;
                        sb_offset -= 8*2;
                        sb_offset &= ~(4*2-1);
                        sb->super_offset = __cpu_to_le64(sb_offset);
-                       data_offset = (long long)(int64_t)__le64_to_cpu(sb->data_offset);
                        if (data_offset < 0)
                                sb->data_offset = 0;
                        if (sb_offset < array_size + bm_space)
@@ -1258,7 +1259,6 @@ static int write_init_super1(struct supertype *st)
                        break;
                case 1:
                        sb->super_offset = __cpu_to_le64(0);
-                       data_offset = (long long)(int64_t)__le64_to_cpu(sb->data_offset);
                        if (data_offset < 0) {
                                reserved = bm_space + 4*2;
                                if (reserved < headroom)
@@ -1282,7 +1282,6 @@ static int write_init_super1(struct supertype *st)
                case 2:
                        sb_offset = 4*2;
                        sb->super_offset = __cpu_to_le64(4*2);
-                       data_offset = (long long)(int64_t)__le64_to_cpu(sb->data_offset);
                        if (data_offset < 0) {
                                if (4*2 + 4*2 + bm_space + array_size
                                    > dsize)
diff --git a/util.c b/util.c
index ac0f78c50189d14e910caf7ed4e4245aac9a62f1..65fbe20783ec2b024aa65bf1592b68cd2c697d9f 100644 (file)
--- a/util.c
+++ b/util.c
@@ -213,6 +213,9 @@ long long parse_size(char *size)
                        c++;
                        s *= 1024 * 1024 * 2;
                        break;
+               case 's': /* sectors */
+                       c++;
+                       break;
                }
        }
        if (*c)