summaryrefslogtreecommitdiff
path: root/super1.c
diff options
context:
space:
mode:
Diffstat (limited to 'super1.c')
-rw-r--r--super1.c90
1 files changed, 55 insertions, 35 deletions
diff --git a/super1.c b/super1.c
index 457e2d6e..79bb4d0c 100644
--- a/super1.c
+++ b/super1.c
@@ -558,12 +558,13 @@ static void uuid_from_super1(struct supertype *st, int uuid[4])
cuuid[i] = super->set_uuid[i];
}
-static void getinfo_super1(struct supertype *st, struct mdinfo *info)
+static void getinfo_super1(struct supertype *st, struct mdinfo *info, char *map)
{
struct mdp_superblock_1 *sb = st->sb;
int working = 0;
unsigned int i;
- int role;
+ unsigned int role;
+ unsigned int map_disks = info->array.raid_disks;
info->array.major_version = 1;
info->array.minor_version = st->minor_version;
@@ -629,15 +630,33 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info)
} else
info->reshape_active = 0;
+ if (map)
+ for (i=0; i<map_disks; i++)
+ map[i] = 0;
for (i = 0; i < __le32_to_cpu(sb->max_dev); i++) {
role = __le16_to_cpu(sb->dev_roles[i]);
- if (/*role == 0xFFFF || */role < info->array.raid_disks)
+ if (/*role == 0xFFFF || */role < (unsigned) info->array.raid_disks) {
working++;
+ if (map && role < map_disks)
+ map[role] = 1;
+ }
}
info->array.working_disks = working;
}
+static struct mdinfo *container_content1(struct supertype *st, char *subarray)
+{
+ struct mdinfo *info;
+
+ if (subarray)
+ return NULL;
+
+ info = malloc(sizeof(*info));
+ getinfo_super1(st, info, NULL);
+ return info;
+}
+
static int update_super1(struct supertype *st, struct mdinfo *info,
char *update,
char *devname, int verbose,
@@ -657,8 +676,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
if (sb->events != __cpu_to_le64(info->events))
rv = 1;
sb->events = __cpu_to_le64(info->events);
- }
- if (strcmp(update, "force-array")==0) {
+ } else if (strcmp(update, "force-array")==0) {
/* Degraded array and 'force' requests to
* maybe need to mark it 'clean'.
*/
@@ -669,8 +687,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
rv = 1;
sb->resync_offset = MaxSector;
}
- }
- if (strcmp(update, "assemble")==0) {
+ } else if (strcmp(update, "assemble")==0) {
int d = info->disk.number;
int want;
if (info->disk.state == 6)
@@ -695,8 +712,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
sb->reshape_position = __cpu_to_le64(info->reshape_progress);
rv = 1;
}
- }
- if (strcmp(update, "linear-grow-new") == 0) {
+ } else if (strcmp(update, "linear-grow-new") == 0) {
unsigned int i;
int rfd, fd;
unsigned int max = __le32_to_cpu(sb->max_dev);
@@ -738,17 +754,14 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
ds - __le64_to_cpu(sb->data_offset));
}
}
- }
- if (strcmp(update, "linear-grow-update") == 0) {
+ } else if (strcmp(update, "linear-grow-update") == 0) {
sb->raid_disks = __cpu_to_le32(info->array.raid_disks);
sb->dev_roles[info->disk.number] =
__cpu_to_le16(info->disk.raid_disk);
- }
- if (strcmp(update, "resync") == 0) {
+ } else if (strcmp(update, "resync") == 0) {
/* make sure resync happens */
sb->resync_offset = 0ULL;
- }
- if (strcmp(update, "uuid") == 0) {
+ } else if (strcmp(update, "uuid") == 0) {
copy_uuid(sb->set_uuid, info->uuid, super1.swapuuid);
if (__le32_to_cpu(sb->feature_map)&MD_FEATURE_BITMAP_OFFSET) {
@@ -758,8 +771,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
}
} else if (strcmp(update, "no-bitmap") == 0) {
sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_BITMAP_OFFSET);
- }
- if (strcmp(update, "homehost") == 0 &&
+ } else if (strcmp(update, "homehost") == 0 &&
homehost) {
char *c;
update = "name";
@@ -769,8 +781,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
else
strncpy(info->name, sb->set_name, 32);
info->name[32] = 0;
- }
- if (strcmp(update, "name") == 0) {
+ } else if (strcmp(update, "name") == 0) {
if (info->name[0] == 0)
sprintf(info->name, "%d", info->array.md_minor);
memset(sb->set_name, 0, sizeof(sb->set_name));
@@ -782,8 +793,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
strcat(sb->set_name, info->name);
} else
strcpy(sb->set_name, info->name);
- }
- if (strcmp(update, "devicesize") == 0 &&
+ } else if (strcmp(update, "devicesize") == 0 &&
__le64_to_cpu(sb->super_offset) <
__le64_to_cpu(sb->data_offset)) {
/* set data_size to device size less data_offset */
@@ -795,9 +805,10 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
misc->device_size - __le64_to_cpu(sb->data_offset));
printf("Size is %llu\n", (unsigned long long)
__le64_to_cpu(sb->data_size));
- }
- if (strcmp(update, "_reshape_progress")==0)
+ } else if (strcmp(update, "_reshape_progress")==0)
sb->reshape_position = __cpu_to_le64(info->reshape_progress);
+ else
+ rv = -1;
sb->sb_csum = calc_sb_1_csum(sb);
return rv;
@@ -1022,11 +1033,13 @@ static unsigned long choose_bm_space(unsigned long devsize)
return 4*2;
}
+static void free_super1(struct supertype *st);
+
#ifndef MDASSEMBLE
static int write_init_super1(struct supertype *st)
{
struct mdp_superblock_1 *sb = st->sb;
- struct supertype refst;
+ struct supertype *refst;
int rfd;
int rv = 0;
unsigned long long bm_space;
@@ -1058,10 +1071,9 @@ static int write_init_super1(struct supertype *st)
sb->events = 0;
- refst =*st;
- refst.sb = NULL;
- if (load_super1(&refst, di->fd, NULL)==0) {
- struct mdp_superblock_1 *refsb = refst.sb;
+ refst = dup_super(st);
+ if (load_super1(refst, di->fd, NULL)==0) {
+ struct mdp_superblock_1 *refsb = refst->sb;
memcpy(sb->device_uuid, refsb->device_uuid, 16);
if (memcmp(sb->set_uuid, refsb->set_uuid, 16)==0) {
@@ -1074,8 +1086,9 @@ static int write_init_super1(struct supertype *st)
if (get_linux_version() >= 2006018)
sb->dev_number = refsb->dev_number;
}
- free(refsb);
+ free_super1(refst);
}
+ free(refst);
if (!get_dev_size(di->fd, NULL, &dsize))
return 1;
@@ -1210,8 +1223,6 @@ static int compare_super1(struct supertype *st, struct supertype *tst)
return 0;
}
-static void free_super1(struct supertype *st);
-
static int load_super1(struct supertype *st, int fd, char *devname)
{
unsigned long long dsize;
@@ -1223,9 +1234,6 @@ static int load_super1(struct supertype *st, int fd, char *devname)
free_super1(st);
- if (st->subarray[0])
- return 1;
-
if (st->ss == NULL || st->minor_version == -1) {
int bestvers = -1;
struct supertype tst;
@@ -1380,6 +1388,7 @@ static struct supertype *match_metadata_desc1(char *arg)
if (!st) return st;
memset(st, 0, sizeof(*st));
+ st->container_dev = NoMdDev;
st->ss = &super1;
st->max_devs = 384;
st->sb = NULL;
@@ -1646,13 +1655,20 @@ static void free_super1(struct supertype *st)
{
if (st->sb)
free(st->sb);
+ while (st->info) {
+ struct devinfo *di = st->info;
+ st->info = di->next;
+ if (di->fd >= 0)
+ close(di->fd);
+ free(di);
+ }
st->sb = NULL;
}
#ifndef MDASSEMBLE
static int validate_geometry1(struct supertype *st, int level,
int layout, int raiddisks,
- int chunk, unsigned long long size,
+ int *chunk, unsigned long long size,
char *subdev, unsigned long long *freesize,
int verbose)
{
@@ -1664,6 +1680,9 @@ static int validate_geometry1(struct supertype *st, int level,
fprintf(stderr, Name ": 1.x metadata does not support containers\n");
return 0;
}
+ if (chunk && *chunk == UnSet)
+ *chunk = DEFAULT_CHUNK;
+
if (!subdev)
return 1;
@@ -1701,6 +1720,7 @@ struct superswitch super1 = {
.match_home = match_home1,
.uuid_from_super = uuid_from_super1,
.getinfo_super = getinfo_super1,
+ .container_content = container_content1,
.update_super = update_super1,
.init_super = init_super1,
.store_super = store_super1,