unsigned long long newcsum;
int size = sizeof(*sb) + __le32_to_cpu(sb->max_dev)*2;
unsigned int *isuper = (unsigned int*)sb;
- int i;
/* make sure I can count... */
if (offsetof(struct mdp_superblock_1,data_offset) != 128 ||
disk_csum = sb->sb_csum;
sb->sb_csum = 0;
newcsum = 0;
- for (i=0; size>=4; size -= 4 ) {
+ for (; size>=4; size -= 4 ) {
newcsum += __le32_to_cpu(*isuper);
isuper++;
}
printf("\n");
}
if (sb->devflags) {
- printf(" Flags :");
+ printf(" Flags :");
if (sb->devflags & WriteMostly1)
printf(" write-mostly");
printf("\n");
printf(" Array State : ");
for (d=0; d<__le32_to_cpu(sb->raid_disks) + delta_extra; d++) {
int cnt = 0;
- int me = 0;
unsigned int i;
for (i=0; i< __le32_to_cpu(sb->max_dev); i++) {
unsigned int role = __le16_to_cpu(sb->dev_roles[i]);
- if (role == d) {
- if (i == __le32_to_cpu(sb->dev_number))
- me = 1;
+ if (role == d)
cnt++;
- }
}
if (cnt > 1) printf("?");
else if (cnt == 1) printf("A");
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;
+ memset(info, 0, sizeof(*info));
info->array.major_version = 1;
info->array.minor_version = st->minor_version;
info->array.patch_version = 0;
} else
info->reshape_active = 0;
+ info->recovery_blocked = info->reshape_active;
+
+ 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,
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'.
*/
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)
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);
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) {
}
} else if (strcmp(update, "no-bitmap") == 0) {
sb->feature_map &= ~__cpu_to_le32(MD_FEATURE_BITMAP_OFFSET);
- }
- if (strcmp(update, "homehost") == 0 &&
- homehost) {
+ } else if (strcmp(update, "homehost") == 0 &&
+ homehost) {
char *c;
update = "name";
c = strchr(sb->set_name, ':');
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));
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 */
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 if (strcmp(update, "writemostly")==0)
+ sb->devflags |= WriteMostly1;
+ else if (strcmp(update, "readwrite")==0)
+ sb->devflags &= ~WriteMostly1;
+ else
+ rv = -1;
sb->sb_csum = calc_sb_1_csum(sb);
return rv;
sb->max_dev = __cpu_to_le32(dk->number+1);
sb->dev_number = __cpu_to_le32(dk->number);
+ sb->devflags = 0; /* don't copy another disks flags */
sb->sb_csum = calc_sb_1_csum(sb);
dip = (struct devinfo **)&st->info;
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;
sb->dev_number = __cpu_to_le32(di->disk.number);
if (di->disk.state & (1<<MD_DISK_WRITEMOSTLY))
sb->devflags |= __cpu_to_le32(WriteMostly1);
+ else
+ sb->devflags &= ~(__cpu_to_le32(WriteMostly1));
if ((rfd = open("/dev/urandom", O_RDONLY)) < 0 ||
read(rfd, sb->device_uuid, 16) != 16) {
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) {
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;
return 0;
}
-static void free_super1(struct supertype *st);
-
static int load_super1(struct supertype *st, int fd, char *devname)
{
unsigned long long dsize;
free_super1(st);
- if (st->subarray[0])
- return 1;
-
if (st->ss == NULL || st->minor_version == -1) {
int bestvers = -1;
struct supertype tst;
if (!st) return st;
memset(st, 0, sizeof(*st));
+ st->container_dev = NoMdDev;
st->ss = &super1;
st->max_devs = 384;
st->sb = NULL;
int room = 0;
struct mdp_superblock_1 *sb = st->sb;
bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + 1024);
+ int uuid[4];
switch(st->minor_version) {
case 0:
memset(bms, 0, sizeof(*bms));
bms->magic = __cpu_to_le32(BITMAP_MAGIC);
bms->version = __cpu_to_le32(major);
- uuid_from_super1(st, (int*)bms->uuid);
+ uuid_from_super1(st, uuid);
+ memcpy(bms->uuid, uuid, 16);
bms->chunksize = __cpu_to_le32(chunk);
bms->daemon_sleep = __cpu_to_le32(delay);
bms->sync_size = __cpu_to_le64(size);
{
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)
{
fprintf(stderr, Name ": 1.x metadata does not support containers\n");
return 0;
}
+ if (chunk && *chunk == UnSet)
+ *chunk = DEFAULT_CHUNK;
+
if (!subdev)
return 1;
.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,