]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
Add data_offset arg to ->init_super and use it in super1.c
authorNeilBrown <neilb@suse.de>
Wed, 9 May 2012 10:49:31 +0000 (20:49 +1000)
committerNeilBrown <neilb@suse.de>
Wed, 9 May 2012 10:49:31 +0000 (20:49 +1000)
So if ->data_offset is already set, use that rather than
computing one.

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

index 0ad308ff4be892c36990d148b57823ed9b76e93b..6ba438332dacdd2ef7ba0e88b4c1e9cc72f0389a 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -692,7 +692,7 @@ int Create(struct supertype *st, char *mddev,
                                name += 2;
                }
        }
-       if (!st->ss->init_super(st, &info.array, size, name, homehost, uuid))
+       if (!st->ss->init_super(st, &info.array, size, name, homehost, uuid, -1LL))
                goto abort_locked;
 
        total_slots = info.array.nr_disks;
diff --git a/Kill.c b/Kill.c
index bac48440bb626a98fc6e7231aaadecd49e0945dc..cd4f3d9e7111e935d2538d818a7c4ebd52c1b1a3 100644 (file)
--- a/Kill.c
+++ b/Kill.c
@@ -63,7 +63,7 @@ int Kill(char *dev, struct supertype *st, int force, int quiet, int noexcl)
        rv = st->ss->load_super(st, fd, dev);
        if (rv == 0 || (force && rv >= 2)) {
                st->ss->free_super(st);
-               st->ss->init_super(st, NULL, 0, "", NULL, NULL);
+               st->ss->init_super(st, NULL, 0, "", NULL, NULL, -1LL);
                if (st->ss->store_super(st, fd)) {
                        if (!quiet)
                                fprintf(stderr, Name ": Could not zero superblock on %s\n",
diff --git a/mdadm.h b/mdadm.h
index 0019a65a68afa400ab19389e0a235b4f3314d06e..b3c9f5344ba2200440ef6ba022347bfa6f2d3307 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -681,7 +681,7 @@ extern struct superswitch {
         */
        int (*init_super)(struct supertype *st, mdu_array_info_t *info,
                          unsigned long long size, char *name,
-                         char *homehost, int *uuid);
+                         char *homehost, int *uuid, long long data_offset);
 
        /* update the metadata to include new device, either at create or
         * when hot-adding a spare.
index a4144b70f6f37a94586a3b25271d5526b38bdcfb..6225a6fbe4f49e82ce3467766b0bfe2177ee2b2c 100644 (file)
@@ -1584,12 +1584,12 @@ static int init_super_ddf_bvd(struct supertype *st,
                              mdu_array_info_t *info,
                              unsigned long long size,
                              char *name, char *homehost,
-                             int *uuid);
+                             int *uuid, long long data_offset);
 
 static int init_super_ddf(struct supertype *st,
                          mdu_array_info_t *info,
                          unsigned long long size, char *name, char *homehost,
-                         int *uuid)
+                         int *uuid, long long data_offset)
 {
        /* This is primarily called by Create when creating a new array.
         * We will then get add_to_super called for each component, and then
@@ -1625,8 +1625,14 @@ static int init_super_ddf(struct supertype *st,
        struct phys_disk *pd;
        struct virtual_disk *vd;
 
+       if (data_offset >= 0) {
+               fprintf(stderr, Name ": data-offset not supported by DDF\n");
+               return 0;
+       }
+
        if (st->sb)
-               return init_super_ddf_bvd(st, info, size, name, homehost, uuid);
+               return init_super_ddf_bvd(st, info, size, name, homehost, uuid,
+                                         data_offset);
 
        if (posix_memalign((void**)&ddf, 512, sizeof(*ddf)) != 0) {
                fprintf(stderr, Name ": %s could not allocate superblock\n", __func__);
@@ -1956,7 +1962,7 @@ static int init_super_ddf_bvd(struct supertype *st,
                              mdu_array_info_t *info,
                              unsigned long long size,
                              char *name, char *homehost,
-                             int *uuid)
+                             int *uuid, long long data_offset)
 {
        /* We are creating a BVD inside a pre-existing container.
         * so st->sb is already set.
index ea6909478885ed93e30e6a38212c490e0bb1f695..d1dd705570eaaa17a8d03fe6aab1847e9939592a 100644 (file)
@@ -4557,7 +4557,8 @@ static int check_name(struct intel_super *super, char *name, int quiet)
 
 static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
                                  unsigned long long size, char *name,
-                                 char *homehost, int *uuid)
+                                 char *homehost, int *uuid,
+                                 long long data_offset)
 {
        /* We are creating a volume inside a pre-existing container.
         * so st->sb is already set.
@@ -4726,7 +4727,7 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
 
 static int init_super_imsm(struct supertype *st, mdu_array_info_t *info,
                           unsigned long long size, char *name,
-                          char *homehost, int *uuid)
+                          char *homehost, int *uuid, long long data_offset)
 {
        /* This is primarily called by Create when creating a new array.
         * We will then get add_to_super called for each component, and then
@@ -4741,8 +4742,14 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info,
        size_t mpb_size;
        char *version;
 
+       if (data_offset >= 0) {
+               fprintf(stderr, Name ": data-offset not supported by imsm\n");
+               return 0;
+       }
+
        if (st->sb)
-               return init_super_imsm_volume(st, info, size, name, homehost, uuid);
+               return init_super_imsm_volume(st, info, size, name, homehost, uuid,
+                                             data_offset);
 
        if (info)
                mpb_size = disks_to_mpb_size(info->nr_disks);
index e0c5a55831fea4cf73d15fe7618d0ea74bd8f49e..ebebc491ae7ec42d57f7639ced7fa82c5da03e16 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -601,11 +601,16 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
 
 static int init_super0(struct supertype *st, mdu_array_info_t *info,
                       unsigned long long size, char *ignored_name, char *homehost,
-                      int *uuid)
+                      int *uuid, long long data_offset)
 {
        mdp_super_t *sb;
        int spares;
 
+       if (data_offset >= 0) {
+               fprintf(stderr, Name ": data-offset not support for 0.90\n");
+               return 0;
+       }
+
        if (posix_memalign((void**)&sb, 4096,
                           MD_SB_BYTES + ROUND_UP(sizeof(bitmap_super_t), 4096)) != 0) {
                fprintf(stderr, Name ": %s could not allocate superblock\n", __func__);
index f8f3545ebbe23a6dfae4ec850c8619fa662d4d08..ee7b18b2de83be2de37c57f00655f5124146b00f 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -862,7 +862,8 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
 }
 
 static int init_super1(struct supertype *st, mdu_array_info_t *info,
-                      unsigned long long size, char *name, char *homehost, int *uuid)
+                      unsigned long long size, char *name, char *homehost,
+                      int *uuid, long long data_offset)
 {
        struct mdp_superblock_1 *sb;
        int spares;
@@ -926,7 +927,7 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info,
        sb->chunksize = __cpu_to_le32(info->chunk_size>>9);
        sb->raid_disks = __cpu_to_le32(info->raid_disks);
 
-       sb->data_offset = __cpu_to_le64(0);
+       sb->data_offset = __cpu_to_le64(data_offset);
        sb->data_size = __cpu_to_le64(0);
        sb->super_offset = __cpu_to_le64(0);
        sb->recovery_offset = __cpu_to_le64(0);
@@ -1095,6 +1096,7 @@ static int write_init_super1(struct supertype *st)
        struct devinfo *di;
        unsigned long long dsize, array_size;
        unsigned long long sb_offset, headroom;
+       long long data_offset;
 
        for (di = st->info; di && ! rv ; di = di->next) {
                if (di->disk.state == 1)
@@ -1181,47 +1183,55 @@ static int write_init_super1(struct supertype *st)
                        sb_offset -= 8*2;
                        sb_offset &= ~(4*2-1);
                        sb->super_offset = __cpu_to_le64(sb_offset);
-                       sb->data_offset = __cpu_to_le64(0);
+                       /* data_offset already set */
                        if (sb_offset < array_size + bm_space)
                                bm_space = sb_offset - array_size;
                        sb->data_size = __cpu_to_le64(sb_offset - bm_space);
                        break;
                case 1:
-                       sb->super_offset = __cpu_to_le64(0);
-                       reserved = bm_space + 4*2;
-                       /* Try for multiple of 1Meg so it is nicely aligned */
-                       #define ONE_MEG (2*1024)
-                       reserved = ((reserved + ONE_MEG-1)/ONE_MEG) * ONE_MEG;
-                       if (reserved + __le64_to_cpu(sb->size) > dsize)
-                               reserved = dsize - __le64_to_cpu(sb->size);
-                       /* force 4K alignment */
-                       reserved &= ~7ULL;
-
-                       if (reserved < headroom)
-                               reserved = headroom;
+                       data_offset = (long long)(int64_t)__le64_to_cpu(sb->data_offset);
+                       if (data_offset < 0) {
+                               sb->super_offset = __cpu_to_le64(0);
+                               reserved = bm_space + 4*2;
+                               /* Try for multiple of 1Meg so it is nicely aligned */
+                               #define ONE_MEG (2*1024)
+                               reserved = ((reserved + ONE_MEG-1)/ONE_MEG) * ONE_MEG;
+                               if (reserved + __le64_to_cpu(sb->size) > dsize)
+                                       reserved = dsize - __le64_to_cpu(sb->size);
+                               /* force 4K alignment */
+                               reserved &= ~7ULL;
+
+                               if (reserved < headroom)
+                                       reserved = headroom;
+                       } else
+                               reserved = data_offset;
 
                        sb->data_offset = __cpu_to_le64(reserved);
                        sb->data_size = __cpu_to_le64(dsize - reserved);
                        break;
                case 2:
-                       sb_offset = 4*2;
-                       sb->super_offset = __cpu_to_le64(4*2);
-                       if (4*2 + 4*2 + bm_space + __le64_to_cpu(sb->size)
-                           > dsize)
-                               bm_space = dsize - __le64_to_cpu(sb->size)
-                                       - 4*2 - 4*2;
-
-                       reserved = bm_space + 4*2 + 4*2;
-                       /* Try for multiple of 1Meg so it is nicely aligned */
-                       #define ONE_MEG (2*1024)
-                       reserved = ((reserved + ONE_MEG-1)/ONE_MEG) * ONE_MEG;
-                       if (reserved + __le64_to_cpu(sb->size) > dsize)
-                               reserved = dsize - __le64_to_cpu(sb->size);
-                       /* force 4K alignment */
-                       reserved &= ~7ULL;
-
-                       if (reserved < headroom)
-                               reserved = headroom;
+                       data_offset = (long long)(int64_t)__le64_to_cpu(sb->data_offset);
+                       if (data_offset < 0) {
+                               sb_offset = 4*2;
+                               sb->super_offset = __cpu_to_le64(4*2);
+                               if (4*2 + 4*2 + bm_space + __le64_to_cpu(sb->size)
+                                   > dsize)
+                                       bm_space = dsize - __le64_to_cpu(sb->size)
+                                               - 4*2 - 4*2;
+
+                               reserved = bm_space + 4*2 + 4*2;
+                               /* Try for multiple of 1Meg so it is nicely aligned */
+                               #define ONE_MEG (2*1024)
+                               reserved = ((reserved + ONE_MEG-1)/ONE_MEG) * ONE_MEG;
+                               if (reserved + __le64_to_cpu(sb->size) > dsize)
+                                       reserved = dsize - __le64_to_cpu(sb->size);
+                               /* force 4K alignment */
+                               reserved &= ~7ULL;
+
+                               if (reserved < headroom)
+                                       reserved = headroom;
+                       } else
+                               reserved = data_offset;
 
                        sb->data_offset = __cpu_to_le64(reserved);
                        sb->data_size = __cpu_to_le64(dsize - reserved);