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>
This commit is contained in:
parent
ee2429e0bc
commit
72ca9bcff3
18
Create.c
18
Create.c
|
@ -289,6 +289,7 @@ int Create(struct supertype *st, char *mddev,
|
||||||
char *dname = dv->devname;
|
char *dname = dv->devname;
|
||||||
unsigned long long freesize;
|
unsigned long long freesize;
|
||||||
int dfd;
|
int dfd;
|
||||||
|
char *doff;
|
||||||
|
|
||||||
if (strcasecmp(dname, "missing")==0) {
|
if (strcasecmp(dname, "missing")==0) {
|
||||||
if (first_missing > dnum)
|
if (first_missing > dnum)
|
||||||
|
@ -298,6 +299,16 @@ int Create(struct supertype *st, char *mddev,
|
||||||
missing_disks ++;
|
missing_disks ++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (data_offset != VARIABLE_OFFSET) {
|
||||||
|
doff = strchr(dname, ':');
|
||||||
|
if (doff) {
|
||||||
|
*doff++ = 0;
|
||||||
|
dv->data_offset = parse_size(doff);
|
||||||
|
} else
|
||||||
|
dv->data_offset = INVALID_SECTORS;
|
||||||
|
} else
|
||||||
|
dv->data_offset = data_offset;
|
||||||
|
|
||||||
dfd = open(dname, O_RDONLY);
|
dfd = open(dname, O_RDONLY);
|
||||||
if (dfd < 0) {
|
if (dfd < 0) {
|
||||||
pr_err("cannot open %s: %s\n",
|
pr_err("cannot open %s: %s\n",
|
||||||
|
@ -335,7 +346,7 @@ int Create(struct supertype *st, char *mddev,
|
||||||
switch (st->ss->validate_geometry(
|
switch (st->ss->validate_geometry(
|
||||||
st, s->level, s->layout, s->raiddisks,
|
st, s->level, s->layout, s->raiddisks,
|
||||||
&s->chunk, s->size*2,
|
&s->chunk, s->size*2,
|
||||||
data_offset, dname,
|
dv->data_offset, dname,
|
||||||
&freesize, c->verbose > 0)) {
|
&freesize, c->verbose > 0)) {
|
||||||
case -1: /* Not valid, message printed, and not
|
case -1: /* Not valid, message printed, and not
|
||||||
* worth checking any further */
|
* worth checking any further */
|
||||||
|
@ -372,7 +383,7 @@ int Create(struct supertype *st, char *mddev,
|
||||||
if (!st->ss->validate_geometry(st, s->level, s->layout,
|
if (!st->ss->validate_geometry(st, s->level, s->layout,
|
||||||
s->raiddisks,
|
s->raiddisks,
|
||||||
&s->chunk, s->size*2,
|
&s->chunk, s->size*2,
|
||||||
data_offset,
|
dv->data_offset,
|
||||||
dname, &freesize,
|
dname, &freesize,
|
||||||
c->verbose >= 0)) {
|
c->verbose >= 0)) {
|
||||||
|
|
||||||
|
@ -866,7 +877,8 @@ int Create(struct supertype *st, char *mddev,
|
||||||
if (fd >= 0)
|
if (fd >= 0)
|
||||||
remove_partitions(fd);
|
remove_partitions(fd);
|
||||||
if (st->ss->add_to_super(st, &inf->disk,
|
if (st->ss->add_to_super(st, &inf->disk,
|
||||||
fd, dv->devname)) {
|
fd, dv->devname,
|
||||||
|
dv->data_offset)) {
|
||||||
ioctl(mdfd, STOP_ARRAY, NULL);
|
ioctl(mdfd, STOP_ARRAY, NULL);
|
||||||
goto abort;
|
goto abort;
|
||||||
}
|
}
|
||||||
|
|
4
Manage.c
4
Manage.c
|
@ -733,7 +733,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
|
||||||
disc.state |= 1 << MD_DISK_WRITEMOSTLY;
|
disc.state |= 1 << MD_DISK_WRITEMOSTLY;
|
||||||
dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT);
|
dfd = dev_open(dv->devname, O_RDWR | O_EXCL|O_DIRECT);
|
||||||
if (tst->ss->add_to_super(tst, &disc, dfd,
|
if (tst->ss->add_to_super(tst, &disc, dfd,
|
||||||
dv->devname))
|
dv->devname, INVALID_SECTORS))
|
||||||
return -1;
|
return -1;
|
||||||
if (tst->ss->write_init_super(tst))
|
if (tst->ss->write_init_super(tst))
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -791,7 +791,7 @@ int Manage_add(int fd, int tfd, struct mddev_dev *dv,
|
||||||
if (mdmon_running(tst->container_dev))
|
if (mdmon_running(tst->container_dev))
|
||||||
tst->update_tail = &tst->updates;
|
tst->update_tail = &tst->updates;
|
||||||
if (tst->ss->add_to_super(tst, &disc, dfd,
|
if (tst->ss->add_to_super(tst, &disc, dfd,
|
||||||
dv->devname)) {
|
dv->devname, INVALID_SECTORS)) {
|
||||||
close(dfd);
|
close(dfd);
|
||||||
close(container_fd);
|
close(container_fd);
|
||||||
return -1;
|
return -1;
|
||||||
|
|
|
@ -304,7 +304,7 @@ static void add_disk_to_container(struct supertype *st, struct mdinfo *sd)
|
||||||
st2->ss->free_super(st2);
|
st2->ss->free_super(st2);
|
||||||
|
|
||||||
st->update_tail = &update;
|
st->update_tail = &update;
|
||||||
st->ss->add_to_super(st, &dk, dfd, NULL);
|
st->ss->add_to_super(st, &dk, dfd, NULL, INVALID_SECTORS);
|
||||||
st->ss->write_init_super(st);
|
st->ss->write_init_super(st);
|
||||||
queue_metadata_update(update);
|
queue_metadata_update(update);
|
||||||
st->update_tail = NULL;
|
st->update_tail = NULL;
|
||||||
|
|
13
mdadm.8.in
13
mdadm.8.in
|
@ -787,7 +787,7 @@ Since Linux 3.4,
|
||||||
can also be used with
|
can also be used with
|
||||||
.B --grow
|
.B --grow
|
||||||
for some RAID levels (initially on RAID10). This allows the
|
for some RAID levels (initially on RAID10). This allows the
|
||||||
data-offset to be changed as part of the reshape process. When the
|
data\-offset to be changed as part of the reshape process. When the
|
||||||
data offset is changed, no backup file is required as the difference
|
data offset is changed, no backup file is required as the difference
|
||||||
in offsets is used to provide the same functionality.
|
in offsets is used to provide the same functionality.
|
||||||
|
|
||||||
|
@ -795,6 +795,17 @@ When the new offset is earlier than the old offset, the number of
|
||||||
devices in the array cannot shrink. When it is after the old offset,
|
devices in the array cannot shrink. When it is after the old offset,
|
||||||
the number of devices in the array cannot increase.
|
the number of devices in the array cannot increase.
|
||||||
|
|
||||||
|
When creating an array,
|
||||||
|
.B \-\-data\-offset
|
||||||
|
can be specified as
|
||||||
|
.BR variable .
|
||||||
|
In the case each member device is expected to have a offset appended
|
||||||
|
to the name, separated by a colon. This makes it possible to recreate
|
||||||
|
exactly an array which has varying data offsets (as can happen when
|
||||||
|
different versions of
|
||||||
|
.I mdadm
|
||||||
|
are used to add different devices).
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BR \-\-continue
|
.BR \-\-continue
|
||||||
This option is complementary to the
|
This option is complementary to the
|
||||||
|
|
6
mdadm.c
6
mdadm.c
|
@ -465,7 +465,11 @@ int main(int argc, char *argv[])
|
||||||
"Second value is %s.\n", optarg);
|
"Second value is %s.\n", optarg);
|
||||||
exit(2);
|
exit(2);
|
||||||
}
|
}
|
||||||
data_offset = parse_size(optarg);
|
if (mode == CREATE &&
|
||||||
|
strcmp(optarg, "variable") == 0)
|
||||||
|
data_offset = VARIABLE_OFFSET;
|
||||||
|
else
|
||||||
|
data_offset = parse_size(optarg);
|
||||||
if (data_offset == INVALID_SECTORS) {
|
if (data_offset == INVALID_SECTORS) {
|
||||||
fprintf(stderr, Name ": invalid data-offset: %s\n",
|
fprintf(stderr, Name ": invalid data-offset: %s\n",
|
||||||
optarg);
|
optarg);
|
||||||
|
|
6
mdadm.h
6
mdadm.h
|
@ -433,6 +433,7 @@ struct mddev_dev {
|
||||||
*/
|
*/
|
||||||
char writemostly; /* 1 for 'set writemostly', 2 for 'clear writemostly' */
|
char writemostly; /* 1 for 'set writemostly', 2 for 'clear writemostly' */
|
||||||
char used; /* set when used */
|
char used; /* set when used */
|
||||||
|
long long data_offset;
|
||||||
struct mddev_dev *next;
|
struct mddev_dev *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -742,7 +743,8 @@ extern struct superswitch {
|
||||||
* when hot-adding a spare.
|
* when hot-adding a spare.
|
||||||
*/
|
*/
|
||||||
int (*add_to_super)(struct supertype *st, mdu_disk_info_t *dinfo,
|
int (*add_to_super)(struct supertype *st, mdu_disk_info_t *dinfo,
|
||||||
int fd, char *devname);
|
int fd, char *devname,
|
||||||
|
unsigned long long data_offset);
|
||||||
/* update the metadata to delete a device,
|
/* update the metadata to delete a device,
|
||||||
* when hot-removing.
|
* when hot-removing.
|
||||||
*/
|
*/
|
||||||
|
@ -1479,5 +1481,7 @@ char *xstrdup(const char *str);
|
||||||
* a value for 'invalid'. Use '1'.
|
* a value for 'invalid'. Use '1'.
|
||||||
*/
|
*/
|
||||||
#define INVALID_SECTORS 1
|
#define INVALID_SECTORS 1
|
||||||
|
/* And another special number needed for --data_offset=variable */
|
||||||
|
#define VARIABLE_OFFSET 3
|
||||||
|
|
||||||
extern int __offroot;
|
extern int __offroot;
|
||||||
|
|
|
@ -2174,7 +2174,8 @@ static void add_to_super_ddf_bvd(struct supertype *st,
|
||||||
* expanding a pre-existing container
|
* expanding a pre-existing container
|
||||||
*/
|
*/
|
||||||
static int add_to_super_ddf(struct supertype *st,
|
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,
|
||||||
|
unsigned long long data_offset)
|
||||||
{
|
{
|
||||||
struct ddf_super *ddf = st->sb;
|
struct ddf_super *ddf = st->sb;
|
||||||
struct dl *dd;
|
struct dl *dd;
|
||||||
|
|
|
@ -4937,7 +4937,8 @@ int mark_spare(struct dl *disk)
|
||||||
}
|
}
|
||||||
|
|
||||||
static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
|
static int add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
|
||||||
int fd, char *devname)
|
int fd, char *devname,
|
||||||
|
unsigned long long data_offset)
|
||||||
{
|
{
|
||||||
struct intel_super *super = st->sb;
|
struct intel_super *super = st->sb;
|
||||||
struct dl *dd;
|
struct dl *dd;
|
||||||
|
|
2
super0.c
2
super0.c
|
@ -695,7 +695,7 @@ struct devinfo {
|
||||||
#ifndef MDASSEMBLE
|
#ifndef MDASSEMBLE
|
||||||
/* Add a device to the superblock being created */
|
/* Add a device to the superblock being created */
|
||||||
static int add_to_super0(struct supertype *st, mdu_disk_info_t *dinfo,
|
static int add_to_super0(struct supertype *st, mdu_disk_info_t *dinfo,
|
||||||
int fd, char *devname)
|
int fd, char *devname, unsigned long long data_offset)
|
||||||
{
|
{
|
||||||
mdp_super_t *sb = st->sb;
|
mdp_super_t *sb = st->sb;
|
||||||
mdp_disk_t *dk = &sb->disks[dinfo->number];
|
mdp_disk_t *dk = &sb->disks[dinfo->number];
|
||||||
|
|
9
super1.c
9
super1.c
|
@ -1106,13 +1106,14 @@ static int init_super1(struct supertype *st, mdu_array_info_t *info,
|
||||||
struct devinfo {
|
struct devinfo {
|
||||||
int fd;
|
int fd;
|
||||||
char *devname;
|
char *devname;
|
||||||
|
long long data_offset;
|
||||||
mdu_disk_info_t disk;
|
mdu_disk_info_t disk;
|
||||||
struct devinfo *next;
|
struct devinfo *next;
|
||||||
};
|
};
|
||||||
#ifndef MDASSEMBLE
|
#ifndef MDASSEMBLE
|
||||||
/* Add a device to the superblock being created */
|
/* Add a device to the superblock being created */
|
||||||
static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
|
static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
|
||||||
int fd, char *devname)
|
int fd, char *devname, unsigned long long data_offset)
|
||||||
{
|
{
|
||||||
struct mdp_superblock_1 *sb = st->sb;
|
struct mdp_superblock_1 *sb = st->sb;
|
||||||
__u16 *rp = sb->dev_roles + dk->number;
|
__u16 *rp = sb->dev_roles + dk->number;
|
||||||
|
@ -1140,6 +1141,7 @@ static int add_to_super1(struct supertype *st, mdu_disk_info_t *dk,
|
||||||
di->fd = fd;
|
di->fd = fd;
|
||||||
di->devname = devname;
|
di->devname = devname;
|
||||||
di->disk = *dk;
|
di->disk = *dk;
|
||||||
|
di->data_offset = data_offset;
|
||||||
di->next = NULL;
|
di->next = NULL;
|
||||||
*dip = di;
|
*dip = di;
|
||||||
|
|
||||||
|
@ -1338,14 +1340,13 @@ static int write_init_super1(struct supertype *st)
|
||||||
headroom/2 >= __le32_to_cpu(sb->chunksize) * 2)
|
headroom/2 >= __le32_to_cpu(sb->chunksize) * 2)
|
||||||
headroom >>= 1;
|
headroom >>= 1;
|
||||||
|
|
||||||
|
data_offset = di->data_offset;
|
||||||
switch(st->minor_version) {
|
switch(st->minor_version) {
|
||||||
case 0:
|
case 0:
|
||||||
sb_offset = dsize;
|
sb_offset = dsize;
|
||||||
sb_offset -= 8*2;
|
sb_offset -= 8*2;
|
||||||
sb_offset &= ~(4*2-1);
|
sb_offset &= ~(4*2-1);
|
||||||
sb->super_offset = __cpu_to_le64(sb_offset);
|
sb->super_offset = __cpu_to_le64(sb_offset);
|
||||||
data_offset = __le64_to_cpu(sb->data_offset);
|
|
||||||
if (data_offset == INVALID_SECTORS)
|
if (data_offset == INVALID_SECTORS)
|
||||||
sb->data_offset = 0;
|
sb->data_offset = 0;
|
||||||
if (sb_offset < array_size + bm_space)
|
if (sb_offset < array_size + bm_space)
|
||||||
|
@ -1358,7 +1359,6 @@ static int write_init_super1(struct supertype *st)
|
||||||
break;
|
break;
|
||||||
case 1:
|
case 1:
|
||||||
sb->super_offset = __cpu_to_le64(0);
|
sb->super_offset = __cpu_to_le64(0);
|
||||||
data_offset = __le64_to_cpu(sb->data_offset);
|
|
||||||
if (data_offset == INVALID_SECTORS) {
|
if (data_offset == INVALID_SECTORS) {
|
||||||
reserved = bm_space + 4*2;
|
reserved = bm_space + 4*2;
|
||||||
if (reserved < headroom)
|
if (reserved < headroom)
|
||||||
|
@ -1386,7 +1386,6 @@ static int write_init_super1(struct supertype *st)
|
||||||
case 2:
|
case 2:
|
||||||
sb_offset = 4*2;
|
sb_offset = 4*2;
|
||||||
sb->super_offset = __cpu_to_le64(4*2);
|
sb->super_offset = __cpu_to_le64(4*2);
|
||||||
data_offset = __le64_to_cpu(sb->data_offset);
|
|
||||||
if (data_offset == INVALID_SECTORS) {
|
if (data_offset == INVALID_SECTORS) {
|
||||||
if (4*2 + 4*2 + bm_space + array_size
|
if (4*2 + 4*2 + bm_space + array_size
|
||||||
> dsize)
|
> dsize)
|
||||||
|
|
Loading…
Reference in New Issue