summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-05-09 20:49:31 +1000
committerNeilBrown <neilb@suse.de>2012-05-09 20:49:31 +1000
commit0308308138db260771bec109a4e9c1b0bb003b8d (patch)
treefc6ce993d6e739115bcbafca00e5e3e456a278e1
parent0f8103975695315c5d6420c043e642aaabe62c18 (diff)
downloadmdadm-0308308138db260771bec109a4e9c1b0bb003b8d.tar.gz
Add data_offset arg to ->init_super and use it in super1.c
So if ->data_offset is already set, use that rather than computing one. Signed-off-by: NeilBrown <neilb@suse.de>
-rw-r--r--Create.c2
-rw-r--r--Kill.c2
-rw-r--r--mdadm.h2
-rw-r--r--super-ddf.c14
-rw-r--r--super-intel.c13
-rw-r--r--super0.c7
-rw-r--r--super1.c76
7 files changed, 72 insertions, 44 deletions
diff --git a/Create.c b/Create.c
index 0ad308f..6ba4383 100644
--- 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 bac4844..cd4f3d9 100644
--- 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 0019a65..b3c9f53 100644
--- 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.
diff --git a/super-ddf.c b/super-ddf.c
index a4144b7..6225a6f 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -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.
diff --git a/super-intel.c b/super-intel.c
index ea69094..d1dd705 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -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);
diff --git a/super0.c b/super0.c
index e0c5a55..ebebc49 100644
--- 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__);
diff --git a/super1.c b/super1.c
index f8f3545..ee7b18b 100644
--- 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);