/*
* mdadm - manage Linux "md" devices aka RAID arrays.
*
- * Copyright (C) 2006-2007 Neil Brown <neilb@suse.de>
+ * Copyright (C) 2006-2009 Neil Brown <neilb@suse.de>
*
*
* This program is free software; you can redistribute it and/or modify
struct phys_disk *phys;
struct virtual_disk *virt;
int pdsize, vdsize;
- int max_part, mppe, conf_rec_len;
+ unsigned int max_part, mppe, conf_rec_len;
int currentdev;
int updates_pending;
struct vcl {
struct vcl *next;
__u64 *lba_offset; /* location in 'conf' of
* the lba table */
- int vcnum; /* index into ->virt */
+ unsigned int vcnum; /* index into ->virt */
__u64 *block_sizes; /* NULL if all the same */
};
};
#endif
-static int calc_crc(void *buf, int len)
+static unsigned int calc_crc(void *buf, int len)
{
/* crcs are always at the same place as in the ddf_header */
struct ddf_header *ddf = buf;
else
offset += __be64_to_cpu(super->active->secondary_lba);
- if (lseek64(fd, offset<<9, 0) != (offset<<9)) {
+ if ((unsigned long long)lseek64(fd, offset<<9, 0) != (offset<<9)) {
if (dofree)
free(buf);
return NULL;
}
- if (read(fd, buf, len<<9) != (len<<9)) {
+ if ((unsigned long long)read(fd, buf, len<<9) != (len<<9)) {
if (dofree)
free(buf);
return NULL;
struct dl *dl;
struct stat stb;
char *conf;
- int i;
- int confsec;
+ unsigned int i;
+ unsigned int confsec;
int vnum;
- int max_virt_disks = __be16_to_cpu(super->active->max_vd_entries);
+ unsigned int max_virt_disks = __be16_to_cpu(super->active->max_vd_entries);
unsigned long long dsize;
/* First the local disk info */
if (get_dev_size(fd, devname, &dsize))
dl->size = dsize >> 9;
dl->spare = NULL;
- for (i=0 ; i < super->max_part ; i++)
+ for (i = 0 ; i < super->max_part ; i++)
dl->vlist[i] = NULL;
super->dlist = dl;
dl->pdnum = -1;
- for (i=0; i < __be16_to_cpu(super->active->max_pd_entries); i++)
+ for (i = 0; i < __be16_to_cpu(super->active->max_pd_entries); i++)
if (memcmp(super->phys->entries[i].guid,
dl->disk.guid, DDF_GUID_LEN) == 0)
dl->pdnum = i;
#ifndef MDASSEMBLE
static int load_super_ddf_all(struct supertype *st, int fd,
- void **sbp, char *devname, int keep_fd);
+ void **sbp, char *devname);
#endif
+
+static void free_super_ddf(struct supertype *st);
+
static int load_super_ddf(struct supertype *st, int fd,
char *devname)
{
struct ddf_super *super;
int rv;
-#ifndef MDASSEMBLE
- /* if 'fd' is a container, load metadata from all the devices */
- if (load_super_ddf_all(st, fd, &st->sb, devname, 1) == 0)
- return 0;
-#endif
- if (st->subarray[0])
- return 1; /* FIXME Is this correct */
-
if (get_dev_size(fd, devname, &dsize) == 0)
return 1;
+ if (test_partition(fd))
+ /* DDF is not allowed on partitions */
+ return 1;
+
/* 32M is a lower bound */
if (dsize <= 32*1024*1024) {
if (devname)
return 1;
}
+ free_super_ddf(st);
+
if (posix_memalign((void**)&super, 512, sizeof(*super))!= 0) {
fprintf(stderr, Name ": malloc of %zu failed.\n",
sizeof(*super));
st->minor_version = 0;
st->max_devs = 512;
}
- st->loaded_container = 0;
return 0;
}
st = malloc(sizeof(*st));
memset(st, 0, sizeof(*st));
+ st->container_dev = NoMdDev;
st->ss = &super_ddf;
st->max_devs = 512;
st->minor_version = 0;
struct vcl *vcl;
for (vcl = sb->conflist ; vcl ; vcl = vcl->next) {
- int i;
+ unsigned int i;
struct vd_config *vc = &vcl->conf;
if (calc_crc(vc, crl*512) != vc->crc)
/* Ok, we know about this VD, let's give more details */
printf(" Raid Devices[%d] : %d (", n,
__be16_to_cpu(vc->prim_elmnt_count));
- for (i=0; i<__be16_to_cpu(vc->prim_elmnt_count); i++) {
+ for (i = 0; i < __be16_to_cpu(vc->prim_elmnt_count); i++) {
int j;
int cnt = __be16_to_cpu(sb->phys->used_pdes);
for (j=0; j<cnt; j++)
examine_pds(sb);
}
-static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info);
+static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *map);
static void uuid_from_super_ddf(struct supertype *st, int uuid[4]);
{
/* We just write a generic DDF ARRAY entry
*/
- struct ddf_super *ddf = st->sb;
struct mdinfo info;
- int i;
char nbuf[64];
- getinfo_super_ddf(st, &info);
+ getinfo_super_ddf(st, &info, NULL);
fname_from_uuid(st, &info, nbuf, ':');
+
printf("ARRAY metadata=ddf UUID=%s\n", nbuf + 5);
+}
+
+static void brief_examine_subarrays_ddf(struct supertype *st, int verbose)
+{
+ /* We just write a generic DDF ARRAY entry
+ */
+ struct ddf_super *ddf = st->sb;
+ struct mdinfo info;
+ unsigned int i;
+ char nbuf[64];
+ getinfo_super_ddf(st, &info, NULL);
+ fname_from_uuid(st, &info, nbuf, ':');
- for (i=0; i<__be16_to_cpu(ddf->virt->max_vdes); i++) {
+ for (i = 0; i < __be16_to_cpu(ddf->virt->max_vdes); i++) {
struct virtual_entry *ve = &ddf->virt->entries[i];
struct vcl vcl;
char nbuf1[64];
{
struct mdinfo info;
char nbuf[64];
- getinfo_super_ddf(st, &info);
+ getinfo_super_ddf(st, &info, NULL);
fname_from_uuid(st, &info, nbuf, ':');
printf("MD_METADATA=ddf\n");
printf("MD_LEVEL=container\n");
// struct ddf_super *ddf = st->sb;
struct mdinfo info;
char nbuf[64];
- getinfo_super_ddf(st, &info);
+ getinfo_super_ddf(st, &info, NULL);
fname_from_uuid(st, &info, nbuf,':');
printf(" UUID=%s", nbuf + 5);
}
* the hostname
*/
struct ddf_super *ddf = st->sb;
- int len = strlen(homehost);
+ unsigned int len;
+
+ if (!homehost)
+ return 0;
+ len = strlen(homehost);
return (memcmp(ddf->controller.guid, T10, 8) == 0 &&
len < sizeof(ddf->controller.vendor_data) &&
}
#ifndef MDASSEMBLE
-static struct vd_config *find_vdcr(struct ddf_super *ddf, int inst)
+static struct vd_config *find_vdcr(struct ddf_super *ddf, unsigned int inst)
{
struct vcl *v;
/* Find the entry in phys_disk which has the given refnum
* and return it's index
*/
- int i;
- for (i=0; i < __be16_to_cpu(ddf->phys->max_pdes); i++)
+ unsigned int i;
+ for (i = 0; i < __be16_to_cpu(ddf->phys->max_pdes); i++)
if (ddf->phys->entries[i].refnum == phys_refnum)
return i;
return -1;
memcpy(uuid, buf, 4*4);
}
-static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info);
+static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, char *map);
-static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info)
+static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *map)
{
struct ddf_super *ddf = st->sb;
+ int map_disks = info->array.raid_disks;
if (ddf->currentconf) {
- getinfo_super_ddf_bvd(st, info);
+ getinfo_super_ddf_bvd(st, info, map);
return;
}
(ddf->anchor.guid+16));
info->array.utime = 0;
info->array.chunk_size = 0;
+ info->container_enough = 1;
info->disk.major = 0;
info->disk.raid_disk = -1;
// info->disk.raid_disk = find refnum in the table and use index;
}
- info->disk.state = (1 << MD_DISK_SYNC);
+ info->disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
+ info->recovery_start = MaxSector;
info->reshape_active = 0;
info->name[0] = 0;
uuid_from_super_ddf(st, info->uuid);
+ if (map) {
+ int i;
+ for (i = 0 ; i < map_disks; i++) {
+ if (i < info->array.raid_disks &&
+ (__be16_to_cpu(ddf->phys->entries[i].state) & DDF_Online) &&
+ !(__be16_to_cpu(ddf->phys->entries[i].state) & DDF_Failed))
+ map[i] = 1;
+ else
+ map[i] = 0;
+ }
+ }
}
static int rlq_to_layout(int rlq, int prl, int raiddisks);
-static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info)
+static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, char *map)
{
struct ddf_super *ddf = st->sb;
struct vcl *vc = ddf->currentconf;
int cd = ddf->currentdev;
int j;
struct dl *dl;
+ int map_disks = info->array.raid_disks;
/* FIXME this returns BVD info - what if we want SVD ?? */
info->array.chunk_size = 512 << vc->conf.chunk_shift;
info->custom_array_size = 0;
- if (cd >= 0 && cd < ddf->mppe) {
+ if (cd >= 0 && (unsigned)cd < ddf->mppe) {
info->data_offset = __be64_to_cpu(vc->lba_offset[cd]);
if (vc->block_sizes)
info->component_size = vc->block_sizes[cd];
info->container_member = ddf->currentconf->vcnum;
+ info->recovery_start = MaxSector;
info->resync_start = 0;
+ info->reshape_active = 0;
if (!(ddf->virt->entries[info->container_member].state
& DDF_state_inconsistent) &&
(ddf->virt->entries[info->container_member].init_state
& DDF_initstate_mask)
== DDF_init_full)
- info->resync_start = ~0ULL;
+ info->resync_start = MaxSector;
uuid_from_super_ddf(st, info->uuid);
- info->container_member = atoi(st->subarray);
info->array.major_version = -1;
info->array.minor_version = -2;
- sprintf(info->text_version, "/%s/%s",
+ sprintf(info->text_version, "/%s/%d",
devnum2devname(st->container_dev),
- st->subarray);
+ info->container_member);
info->safe_mode_delay = 200;
memcpy(info->name, ddf->virt->entries[info->container_member].name, 16);
for(j=0; j<16; j++)
if (info->name[j] == ' ')
info->name[j] = 0;
+
+ if (map)
+ for (j = 0; j < map_disks; j++) {
+ map[j] = 0;
+ if (j < info->array.raid_disks) {
+ int i = find_phys(ddf, vc->conf.phys_refnum[j]);
+ if (i >= 0 &&
+ (__be16_to_cpu(ddf->phys->entries[i].state) & DDF_Online) &&
+ !(__be16_to_cpu(ddf->phys->entries[i].state) & DDF_Failed))
+ map[i] = 1;
+ }
+ }
}
if (strcmp(update, "grow") == 0) {
/* FIXME */
- }
- if (strcmp(update, "resync") == 0) {
+ } else if (strcmp(update, "resync") == 0) {
// info->resync_checkpoint = 0;
- }
- /* We ignore UUID updates as they make even less sense
- * with DDF
- */
- if (strcmp(update, "homehost") == 0) {
+ } else if (strcmp(update, "homehost") == 0) {
/* homehost is stored in controller->vendor_data,
* or it is when we are the vendor
*/
// if (info->vendor_is_local)
// strcpy(ddf->controller.vendor_data, homehost);
- }
- if (strcmp(update, "name") == 0) {
+ rv = -1;
+ } else if (strcmp(update, "name") == 0) {
/* name is stored in virtual_entry->name */
// memset(ve->name, ' ', 16);
// strncpy(ve->name, info->name, 16);
- }
- if (strcmp(update, "_reshape_progress") == 0) {
+ rv = -1;
+ } else if (strcmp(update, "_reshape_progress") == 0) {
/* We don't support reshape yet */
- }
+ } else if (strcmp(update, "assemble") == 0 ) {
+ /* Do nothing, just succeed */
+ rv = 0;
+ } else
+ rv = -1;
// update_all_csum(ddf);
return rv;
}
-__u32 random32(void)
-{
- __u32 rv;
- int rfd = open("/dev/urandom", O_RDONLY);
- if (rfd < 0 || read(rfd, &rv, 4) != 4)
- rv = random();
- if (rfd >= 0)
- close(rfd);
- return rv;
-}
-
static void make_header_guid(char *guid)
{
__u32 stamp;
struct phys_disk *pd;
struct virtual_disk *vd;
- if (!info) {
- st->sb = NULL;
- 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);
if (posix_memalign((void**)&ddf, 512, sizeof(*ddf)) != 0) {
fprintf(stderr, Name ": %s could not allocate superblock\n", __func__);
memset(ddf, 0, sizeof(*ddf));
ddf->dlist = NULL; /* no physical disks yet */
ddf->conflist = NULL; /* No virtual disks yet */
+ st->sb = ddf;
+
+ if (info == NULL) {
+ /* zeroing superblock */
+ return 0;
+ }
/* At least 32MB *must* be reserved for the ddf. So let's just
* start 32MB from the end, and put the primary header there.
memset(pd, 0xff, pdsize);
memset(pd, 0, sizeof(*pd));
- pd->magic = DDF_PHYS_DATA_MAGIC;
+ pd->magic = DDF_PHYS_RECORDS_MAGIC;
pd->used_pdes = __cpu_to_be16(0);
pd->max_pdes = __cpu_to_be16(max_phys_disks);
memset(pd->pad, 0xff, 52);
*/
struct extent *rv;
int n = 0;
- int i, j;
+ unsigned int i, j;
rv = malloc(sizeof(struct extent) * (ddf->max_part + 2));
if (!rv)
struct vcl *v = dl->vlist[i];
if (v == NULL)
continue;
- for (j=0; j < v->conf.prim_elmnt_count; j++)
+ for (j = 0; j < v->conf.prim_elmnt_count; j++)
if (v->conf.phys_refnum[j] == dl->disk.refnum) {
/* This device plays role 'j' in 'v'. */
rv[n].start = __be64_to_cpu(v->lba_offset[j]);
* We need to create a new vd_config and a new virtual_entry
*/
struct ddf_super *ddf = st->sb;
- int venum;
+ unsigned int venum;
struct virtual_entry *ve;
struct vcl *vcl;
struct vd_config *vc;
return 0;
}
+ if (name)
+ for (venum = 0; venum < __be16_to_cpu(ddf->virt->max_vdes); venum++)
+ if (!all_ff(ddf->virt->entries[venum].guid)) {
+ char *n = ddf->virt->entries[venum].name;
+
+ if (strncmp(name, n, 16) == 0) {
+ fprintf(stderr, Name ": This ddf already"
+ " has an array called %s\n",
+ name);
+ return 0;
+ }
+ }
+
for (venum = 0; venum < __be16_to_cpu(ddf->virt->max_vdes); venum++)
if (all_ff(ddf->virt->entries[venum].guid))
break;
}
vcl->lba_offset = (__u64*) &vcl->conf.phys_refnum[ddf->mppe];
vcl->vcnum = venum;
- sprintf(st->subarray, "%d", venum);
vcl->block_sizes = NULL; /* FIXME not for CONCAT */
vc = &vcl->conf;
struct ddf_super *ddf = st->sb;
struct vd_config *vc;
__u64 *lba_offset;
- int working;
- int i;
+ unsigned int working;
+ unsigned int i;
unsigned long long blocks, pos, esize;
struct extent *ex;
vc->phys_refnum[dk->raid_disk] = dl->disk.refnum;
lba_offset[dk->raid_disk] = __cpu_to_be64(pos);
- for (i=0; i < ddf->max_part ; i++)
+ for (i = 0; i < ddf->max_part ; i++)
if (dl->vlist[i] == NULL)
break;
if (i == ddf->max_part)
*/
working = 0;
- for (i=0; i < __be16_to_cpu(vc->prim_elmnt_count); i++)
+ for (i = 0; i < __be16_to_cpu(vc->prim_elmnt_count); i++)
if (vc->phys_refnum[i] != 0xffffffff)
working++;
struct tm *tm;
unsigned long long size;
struct phys_disk_entry *pde;
- int n, i;
+ unsigned int n, i;
struct stat stb;
if (ddf->currentconf) {
do {
/* Cannot be bothered finding a CRC of some irrelevant details*/
dd->disk.refnum = random32();
- for (i = __be16_to_cpu(ddf->active->max_pd_entries) - 1;
- i >= 0; i--)
- if (ddf->phys->entries[i].refnum == dd->disk.refnum)
+ for (i = __be16_to_cpu(ddf->active->max_pd_entries);
+ i > 0; i--)
+ if (ddf->phys->entries[i-1].refnum == dd->disk.refnum)
break;
- } while (i >= 0);
+ } while (i > 0);
dd->disk.forced_ref = 1;
dd->disk.forced_guid = 1;
static unsigned char null_conf[4096+512];
-static int __write_init_super_ddf(struct supertype *st, int do_close)
+static int __write_init_super_ddf(struct supertype *st)
{
struct ddf_super *ddf = st->sb;
char *null_aligned = (char*)((((unsigned long)null_conf)+511)&~511UL);
if (null_conf[0] != 0xff)
memset(null_conf, 0xff, sizeof(null_conf));
- int togo = conf_size;
+ unsigned int togo = conf_size;
while (togo > sizeof(null_conf)-512) {
if (write(fd, null_aligned, sizeof(null_conf)-512) < 0)
break;
successes++;
}
- if (do_close)
- for (d = ddf->dlist; d; d=d->next) {
- close(d->fd);
- d->fd = -1;
- }
-
return attempts != successes;
}
static int write_init_super_ddf(struct supertype *st)
{
+ struct ddf_super *ddf = st->sb;
+ struct vcl *currentconf = ddf->currentconf;
+
+ /* we are done with currentconf reset it to point st at the container */
+ ddf->currentconf = NULL;
if (st->update_tail) {
/* queue the virtual_disk and vd_config as metadata updates */
struct virtual_disk *vd;
struct vd_config *vc;
- struct ddf_super *ddf = st->sb;
int len;
- if (!ddf->currentconf) {
+ if (!currentconf) {
int len = (sizeof(struct phys_disk) +
sizeof(struct phys_disk_entry));
len = sizeof(struct virtual_disk) + sizeof(struct virtual_entry);
vd = malloc(len);
*vd = *ddf->virt;
- vd->entries[0] = ddf->virt->entries[ddf->currentconf->vcnum];
- vd->populated_vdes = __cpu_to_be16(ddf->currentconf->vcnum);
+ vd->entries[0] = ddf->virt->entries[currentconf->vcnum];
+ vd->populated_vdes = __cpu_to_be16(currentconf->vcnum);
append_metadata_update(st, vd, len);
/* Then the vd_config */
len = ddf->conf_rec_len * 512;
vc = malloc(len);
- memcpy(vc, &ddf->currentconf->conf, len);
+ memcpy(vc, ¤tconf->conf, len);
append_metadata_update(st, vc, len);
/* FIXME I need to close the fds! */
return 0;
- } else
- return __write_init_super_ddf(st, 1);
+ } else {
+ struct dl *d;
+ for (d = ddf->dlist; d; d=d->next)
+ while (Kill(d->devname, NULL, 0, 1, 1) == 0);
+ return __write_init_super_ddf(st);
+ }
}
#endif
for (i=0; ddf_level_num[i].num1 != MAXINT; i++)
if (ddf_level_num[i].num2 == level)
break;
- if (ddf_level_num[i].num1 == MAXINT)
+ if (ddf_level_num[i].num1 == MAXINT) {
+ if (verbose)
+ fprintf(stderr, Name ": DDF does not support level %d arrays\n",
+ level);
return 0;
+ }
/* Should check layout? etc */
if (st->sb && freesize) {
if (verbose)
fprintf(stderr,
Name ": ddf: Cannot create this array "
- "on device %s\n",
+ "on device %s - a container is required.\n",
dev);
return 0;
}
* and try to create a bvd
*/
struct ddf_super *ddf;
- if (load_super_ddf_all(st, cfd, (void **)&ddf, NULL, 1) == 0) {
+ if (load_super_ddf_all(st, cfd, (void **)&ddf, NULL) == 0) {
st->sb = ddf;
st->container_dev = fd2devnum(cfd);
close(cfd);
struct extent *e;
int i;
/* ddf/bvd supports lots of things, but not containers */
- if (level == LEVEL_CONTAINER)
+ if (level == LEVEL_CONTAINER) {
+ if (verbose)
+ fprintf(stderr, Name ": DDF cannot create a container within an container\n");
return 0;
+ }
/* We must have the container info already read in. */
if (!ddf)
return 0;
if ((S_IFMT & stb.st_mode) != S_IFBLK)
return 0;
for (dl = ddf->dlist ; dl ; dl = dl->next) {
- if (dl->major == major(stb.st_rdev) &&
- dl->minor == minor(stb.st_rdev))
+ if (dl->major == (int)major(stb.st_rdev) &&
+ dl->minor == (int)minor(stb.st_rdev))
break;
}
if (!dl) {
}
static int load_super_ddf_all(struct supertype *st, int fd,
- void **sbp, char *devname, int keep_fd)
+ void **sbp, char *devname)
{
struct mdinfo *sra;
struct ddf_super *super;
int seq;
char nm[20];
int dfd;
- int devnum = fd2devnum(fd);
- enum sysfs_read_flags flags;
- flags = GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE;
- if (mdmon_running(devnum))
- flags |= SKIP_GONE_DEVS;
-
- sra = sysfs_read(fd, 0, flags);
+ sra = sysfs_read(fd, 0, GET_LEVEL|GET_VERSION|GET_DEVS|GET_STATE);
if (!sra)
return 1;
if (sra->array.major_version != -1 ||
int rv;
sprintf(nm, "%d:%d", sd->disk.major, sd->disk.minor);
- dfd = dev_open(nm, keep_fd? O_RDWR : O_RDONLY);
+ dfd = dev_open(nm, O_RDWR);
if (dfd < 0)
return 2;
rv = load_ddf_headers(dfd, super, NULL);
if (rv == 0)
- rv = load_ddf_local(dfd, super, NULL, keep_fd);
- if (!keep_fd) close(dfd);
+ rv = load_ddf_local(dfd, super, NULL, 1);
if (rv)
return 1;
}
- if (st->subarray[0]) {
- struct vcl *v;
- for (v = super->conflist; v; v = v->next)
- if (v->vcnum == atoi(st->subarray))
- super->currentconf = v;
- if (!super->currentconf)
- return 1;
- }
*sbp = super;
if (st->ss == NULL) {
st->ss = &super_ddf;
st->minor_version = 0;
st->max_devs = 512;
- st->container_dev = fd2devnum(fd);
}
- st->loaded_container = 1;
+ st->container_dev = fd2devnum(fd);
return 0;
}
+
+static int load_container_ddf(struct supertype *st, int fd,
+ char *devname)
+{
+ return load_super_ddf_all(st, fd, &st->sb, devname);
+}
+
#endif /* MDASSEMBLE */
-static struct mdinfo *container_content_ddf(struct supertype *st)
+static struct mdinfo *container_content_ddf(struct supertype *st, char *subarray)
{
/* Given a container loaded by load_super_ddf_all,
* extract information about all the arrays into
for (vc = ddf->conflist ; vc ; vc=vc->next)
{
- int i;
- int j;
+ unsigned int i;
+ unsigned int j;
struct mdinfo *this;
+ char *ep;
+
+ if (subarray &&
+ (strtoul(subarray, &ep, 10) != vc->vcnum ||
+ *ep != '\0'))
+ continue;
+
this = malloc(sizeof(*this));
memset(this, 0, sizeof(*this));
this->next = rest;
this->resync_start = 0;
} else {
this->array.state = 1;
- this->resync_start = ~0ULL;
+ this->resync_start = MaxSector;
}
memcpy(this->name, ddf->virt->entries[i].name, 16);
this->name[16]=0;
devnum2devname(st->container_dev),
this->container_member);
- for (i=0 ; i < ddf->mppe ; i++) {
+ for (i = 0 ; i < ddf->mppe ; i++) {
struct mdinfo *dev;
struct dl *d;
dev->disk.minor = d->minor;
dev->disk.raid_disk = i;
dev->disk.state = (1<<MD_DISK_SYNC)|(1<<MD_DISK_ACTIVE);
+ dev->recovery_start = MaxSector;
dev->events = __be32_to_cpu(ddf->primary.seq);
dev->data_offset = __be64_to_cpu(vc->lba_offset[i]);
return rest;
}
-static int store_zero_ddf(struct supertype *st, int fd)
+static int store_super_ddf(struct supertype *st, int fd)
{
+ struct ddf_super *ddf = st->sb;
unsigned long long dsize;
void *buf;
int rc;
+ if (!ddf)
+ return 1;
+
+ /* ->dlist and ->conflist will be set for updates, currently not
+ * supported
+ */
+ if (ddf->dlist || ddf->conflist)
+ return 1;
+
if (!get_dev_size(fd, NULL, &dsize))
return 1;
if (consistent == 2) {
/* Should check if a recovery should be started FIXME */
consistent = 1;
- if (!is_resync_complete(a))
+ if (!is_resync_complete(&a->info))
consistent = 0;
}
if (consistent)
old = ddf->virt->entries[inst].init_state;
ddf->virt->entries[inst].init_state &= ~DDF_initstate_mask;
- if (is_resync_complete(a))
+ if (is_resync_complete(&a->info))
ddf->virt->entries[inst].init_state |= DDF_init_full;
- else if (a->resync_start == 0)
+ else if (a->info.resync_start == 0)
ddf->virt->entries[inst].init_state |= DDF_init_not;
else
ddf->virt->entries[inst].init_state |= DDF_init_quick;
ddf->updates_pending = 1;
dprintf("ddf mark %d %s %llu\n", inst, consistent?"clean":"dirty",
- a->resync_start);
+ a->info.resync_start);
return consistent;
}
static void ddf_set_disk(struct active_array *a, int n, int state)
{
struct ddf_super *ddf = a->container->sb;
- int inst = a->info.container_member;
+ unsigned int inst = a->info.container_member;
struct vd_config *vc = find_vdcr(ddf, inst);
int pd = find_phys(ddf, vc->phys_refnum[n]);
int i, st, working;
if (!ddf->updates_pending)
return;
ddf->updates_pending = 0;
- __write_init_super_ddf(st, 0);
+ __write_init_super_ddf(st);
dprintf("ddf: sync_metadata\n");
}
struct vd_config *vc;
struct vcl *vcl;
struct dl *dl;
- int mppe;
- int ent;
+ unsigned int mppe;
+ unsigned int ent;
dprintf("Process update %x\n", *magic);
dprintf("len %d %d\n", update->len, ddf->conf_rec_len);
mppe = __be16_to_cpu(ddf->anchor.max_primary_element_entries);
- if (update->len != ddf->conf_rec_len * 512)
+ if ((unsigned)update->len != ddf->conf_rec_len * 512)
return;
vc = (struct vd_config*)update->buf;
for (vcl = ddf->conflist; vcl ; vcl = vcl->next)
}
/* Now make sure vlist is correct for each dl. */
for (dl = ddf->dlist; dl; dl = dl->next) {
- int dn;
- int vn = 0;
+ unsigned int dn;
+ unsigned int vn = 0;
for (vcl = ddf->conflist; vcl ; vcl = vcl->next)
for (dn=0; dn < ddf->mppe ; dn++)
if (vcl->conf.phys_refnum[dn] ==
int is_global = 0;
int is_dedicated = 0;
struct extent *ex;
- int j;
+ unsigned int j;
/* If in this array, skip */
for (d2 = a->info.devs ; d2 ; d2 = d2->next)
if (d2->disk.major == dl->major &&
di->disk.major = dl->major;
di->disk.minor = dl->minor;
di->disk.state = 0;
+ di->recovery_start = 0;
di->data_offset = pos;
di->component_size = a->info.component_size;
di->container_member = dl->pdnum;
}
}
+static void default_geometry_ddf(struct supertype *st, int *level, int *layout, int *chunk)
+{
+ if (level && *level == UnSet)
+ *level = LEVEL_CONTAINER;
+
+ if (level && layout && *layout == UnSet)
+ *layout = ddf_level_to_layout(*level);
+}
+
struct superswitch super_ddf = {
#ifndef MDASSEMBLE
.examine_super = examine_super_ddf,
.brief_examine_super = brief_examine_super_ddf,
+ .brief_examine_subarrays = brief_examine_subarrays_ddf,
.export_examine_super = export_examine_super_ddf,
.detail_super = detail_super_ddf,
.brief_detail_super = brief_detail_super_ddf,
.validate_geometry = validate_geometry_ddf,
.write_init_super = write_init_super_ddf,
.add_to_super = add_to_super_ddf,
+ .load_container = load_container_ddf,
#endif
.match_home = match_home_ddf,
.uuid_from_super= uuid_from_super_ddf,
.load_super = load_super_ddf,
.init_super = init_super_ddf,
- .store_super = store_zero_ddf,
+ .store_super = store_super_ddf,
.free_super = free_super_ddf,
.match_metadata_desc = match_metadata_desc_ddf,
.container_content = container_content_ddf,
- .default_layout = ddf_level_to_layout,
+ .default_geometry = default_geometry_ddf,
.external = 1,