]> 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>
Thu, 4 Oct 2012 06:34:20 +0000 (16:34 +1000)
committerNeilBrown <neilb@suse.de>
Thu, 4 Oct 2012 06:34:20 +0000 (16:34 +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 6a49183da0ff536ebd3f7f0168bc76a67e5c8f08..42c92acb871ef4399b2d0bac7bb37a67adfe8494 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -681,7 +681,8 @@ int Create(struct supertype *st, char *mddev,
                                name += 2;
                }
        }
-       if (!st->ss->init_super(st, &info.array, s->size, name, c->homehost, uuid))
+       if (!st->ss->init_super(st, &info.array, s->size, name, c->homehost, uuid,
+                               INVALID_SECTORS))
                goto abort_locked;
 
        total_slots = info.array.nr_disks;
diff --git a/Kill.c b/Kill.c
index 6e426c0e3c6661f5d5eaf2963a963f1c5c2bd954..cc2e589301ee8f201c30e68dcfdac08943e803df 100644 (file)
--- a/Kill.c
+++ b/Kill.c
@@ -63,7 +63,8 @@ int Kill(char *dev, struct supertype *st, int force, int verbose, 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,
+                                  INVALID_SECTORS);
                if (st->ss->store_super(st, fd)) {
                        if (verbose >= 0)
                                pr_err("Could not zero superblock on %s\n",
diff --git a/mdadm.h b/mdadm.h
index 04e7d0fcee317719e33c7d46e2a4c74d4c1f3307..425cac396a85db765a8a1793e8342d4759b20ffa 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -726,7 +726,8 @@ 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,
+                         unsigned long long data_offset);
 
        /* update the metadata to include new device, either at create or
         * when hot-adding a spare.
index 7ab8f2c15310cdd212d85f2ec9845e707303844e..baadc7959429606e9147e66f4957784f19185351 100644 (file)
@@ -1568,12 +1568,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, unsigned 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, unsigned 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
@@ -1609,8 +1609,14 @@ static int init_super_ddf(struct supertype *st,
        struct phys_disk *pd;
        struct virtual_disk *vd;
 
+       if (data_offset != INVALID_SECTORS) {
+               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) {
                pr_err("%s could not allocate superblock\n", __func__);
@@ -1939,7 +1945,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, unsigned long long data_offset)
 {
        /* We are creating a BVD inside a pre-existing container.
         * so st->sb is already set.
index 561fa34b34f7423f8c5bb728f2b0332f7539bc12..fc1d6ab83184ba9088d08249a529e40b75b6ad64 100644 (file)
@@ -4561,7 +4561,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.
@@ -4719,7 +4720,8 @@ 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,
+                          unsigned 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
@@ -4734,8 +4736,14 @@ static int init_super_imsm(struct supertype *st, mdu_array_info_t *info,
        size_t mpb_size;
        char *version;
 
+       if (data_offset != INVALID_SECTORS) {
+               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 983ef853a2544585c509f26036aaf28820819c92..4e6375f120acd99ecac6fff675104e3c3a3ba2ff 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, unsigned long long data_offset)
 {
        mdp_super_t *sb;
        int spares;
 
+       if (data_offset != INVALID_SECTORS) {
+               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) {
                pr_err("%s could not allocate superblock\n", __func__);
index ba7563b075dc111b5b2471bb11d3df643bae91e6..01743169763638578b8dc17c5cdaa179641b1526 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -957,7 +957,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, unsigned long long data_offset)
 {
        struct mdp_superblock_1 *sb;
        int spares;
@@ -1020,7 +1021,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);
@@ -1189,6 +1190,7 @@ static int write_init_super1(struct supertype *st)
        struct devinfo *di;
        unsigned long long dsize, array_size;
        unsigned long long sb_offset, headroom;
+       unsigned long long data_offset;
 
        for (di = st->info; di; di = di->next) {
                if (di->disk.state == 1)
@@ -1277,7 +1279,9 @@ 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 = __le64_to_cpu(sb->data_offset);
+                       if (data_offset == INVALID_SECTORS)
+                               sb->data_offset = 0;
                        if (sb_offset < array_size + bm_space)
                                bm_space = sb_offset - array_size;
                        sb->data_size = __cpu_to_le64(sb_offset - bm_space);
@@ -1288,18 +1292,23 @@ static int write_init_super1(struct supertype *st)
                        break;
                case 1:
                        sb->super_offset = __cpu_to_le64(0);
-                       reserved = bm_space + 4*2;
-                       if (reserved < headroom)
-                               reserved = headroom;
-                       if (reserved + array_size > dsize)
-                               reserved = dsize - array_size;
-                       /* Try for multiple of 1Meg so it is nicely aligned */
-                       #define ONE_MEG (2*1024)
-                       if (reserved > ONE_MEG)
-                               reserved = (reserved/ONE_MEG) * ONE_MEG;
-
-                       /* force 4K alignment */
-                       reserved &= ~7ULL;
+                       data_offset = __le64_to_cpu(sb->data_offset);
+                       if (data_offset == INVALID_SECTORS) {
+                               reserved = bm_space + 4*2;
+                               if (reserved < headroom)
+                                       reserved = headroom;
+                               if (reserved + array_size > dsize)
+                                       reserved = dsize - array_size;
+                               /* Try for multiple of 1Meg so it is nicely aligned */
+                               #define ONE_MEG (2*1024)
+                               if (reserved > ONE_MEG)
+                                       reserved = (reserved/ONE_MEG) * ONE_MEG;
+
+                               /* force 4K alignment */
+                               reserved &= ~7ULL;
+
+                       } else
+                               reserved = data_offset;
 
                        sb->data_offset = __cpu_to_le64(reserved);
                        sb->data_size = __cpu_to_le64(dsize - reserved);
@@ -1311,23 +1320,28 @@ static int write_init_super1(struct supertype *st)
                case 2:
                        sb_offset = 4*2;
                        sb->super_offset = __cpu_to_le64(4*2);
-                       if (4*2 + 4*2 + bm_space + array_size
-                           > dsize)
-                               bm_space = dsize - array_size
-                                       - 4*2 - 4*2;
-
-                       reserved = bm_space + 4*2 + 4*2;
-                       if (reserved < headroom)
-                               reserved = headroom;
-                       if (reserved + array_size > dsize)
-                               reserved = dsize - array_size;
-                       /* Try for multiple of 1Meg so it is nicely aligned */
-                       #define ONE_MEG (2*1024)
-                       if (reserved > ONE_MEG)
-                               reserved = (reserved/ONE_MEG) * ONE_MEG;
-
-                       /* force 4K alignment */
-                       reserved &= ~7ULL;
+                       data_offset = __le64_to_cpu(sb->data_offset);
+                       if (data_offset == INVALID_SECTORS) {
+                               if (4*2 + 4*2 + bm_space + array_size
+                                   > dsize)
+                                       bm_space = dsize - array_size
+                                               - 4*2 - 4*2;
+
+                               reserved = bm_space + 4*2 + 4*2;
+                               if (reserved < headroom)
+                                       reserved = headroom;
+                               if (reserved + array_size > dsize)
+                                       reserved = dsize - array_size;
+                               /* Try for multiple of 1Meg so it is nicely aligned */
+                               #define ONE_MEG (2*1024)
+                               if (reserved > ONE_MEG)
+                                       reserved = (reserved/ONE_MEG) * ONE_MEG;
+
+                               /* force 4K alignment */
+                               reserved &= ~7ULL;
+
+                       } else
+                               reserved = data_offset;
 
                        sb->data_offset = __cpu_to_le64(reserved);
                        sb->data_size = __cpu_to_le64(dsize - reserved);