summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNeilBrown <neilb@suse.de>2012-06-05 08:50:44 +1000
committerNeilBrown <neilb@suse.de>2012-06-05 08:50:44 +1000
commitc94996f693f1ac3acfc3dac86b97a7e5d63e4919 (patch)
treedf8d46eea3f6a51d433b59d0c87ea964dbb19671
parent872ddb0608700a338c25a84a0e23c744714c8f0d (diff)
downloadmdadm-c94996f693f1ac3acfc3dac86b97a7e5d63e4919.tar.gz
Allow data-offset to be specified per-device for create
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>
-rw-r--r--Create.c15
-rw-r--r--Manage.c4
-rw-r--r--managemon.c2
-rw-r--r--mdadm.h3
-rw-r--r--super-ddf.c3
-rw-r--r--super-intel.c2
-rw-r--r--super0.c2
-rw-r--r--super1.c9
-rw-r--r--util.c3
9 files changed, 28 insertions, 15 deletions
diff --git a/Create.c b/Create.c
index b4b6804..f491631 100644
--- 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;
}
diff --git a/Manage.c b/Manage.c
index d51a93c..8c49ef6 100644
--- 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;
diff --git a/managemon.c b/managemon.c
index 6c21ecb..1ebaf2a 100644
--- a/managemon.c
+++ b/managemon.c
@@ -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 abe7c3c..40f600b 100644
--- 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.
*/
diff --git a/super-ddf.c b/super-ddf.c
index 6225a6f..f523ebe 100644
--- a/super-ddf.c
+++ b/super-ddf.c
@@ -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;
diff --git a/super-intel.c b/super-intel.c
index e09fc60..c91adf2 100644
--- a/super-intel.c
+++ b/super-intel.c
@@ -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;
diff --git a/super0.c b/super0.c
index ebebc49..9aca4de 100644
--- 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];
diff --git a/super1.c b/super1.c
index 002c861..871af3f 100644
--- 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 ac0f78c..65fbe20 100644
--- 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)