X-Git-Url: http://git.ipfire.org/?a=blobdiff_plain;f=super-ddf.c;h=fca8edd742e472060f0219050731abcf399488a1;hb=b9b004ebc7abd5a4d8ddafef1fbf08409f24b330;hp=5ad89c25a84c427a6da3899f73832afe6a90c029;hpb=fa09d4961e5c72da3c7f78d53a7d64f5196110a3;p=thirdparty%2Fmdadm.git diff --git a/super-ddf.c b/super-ddf.c index 5ad89c25..fca8edd7 100644 --- a/super-ddf.c +++ b/super-ddf.c @@ -396,7 +396,7 @@ struct ddf_super { 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 { @@ -406,7 +406,7 @@ struct ddf_super { 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 */ }; }; @@ -440,7 +440,7 @@ struct ddf_super { #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; @@ -522,12 +522,12 @@ static void *load_section(int fd, struct ddf_super *super, void *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; @@ -642,10 +642,10 @@ static int load_ddf_local(int fd, struct ddf_super *super, 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 */ @@ -673,11 +673,11 @@ static int load_ddf_local(int fd, struct ddf_super *super, 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; @@ -762,6 +762,9 @@ static int load_ddf_local(int fd, struct ddf_super *super, static int load_super_ddf_all(struct supertype *st, int fd, void **sbp, char *devname, int keep_fd); #endif + +static void free_super_ddf(struct supertype *st); + static int load_super_ddf(struct supertype *st, int fd, char *devname) { @@ -780,6 +783,10 @@ static int load_super_ddf(struct supertype *st, int fd, 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) @@ -798,6 +805,8 @@ static int load_super_ddf(struct supertype *st, int fd, 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)); @@ -835,6 +844,26 @@ static int load_super_ddf(struct supertype *st, int fd, return rv; } + if (st->subarray[0]) { + unsigned long val; + struct vcl *v; + char *ep; + + val = strtoul(st->subarray, &ep, 10); + if (*ep != '\0') { + free(super); + return 1; + } + + for (v = super->conflist; v; v = v->next) + if (v->vcnum == val) + super->currentconf = v; + if (!super->currentconf) { + free(super); + return 1; + } + } + /* Should possibly check the sections .... */ st->sb = super; @@ -1025,7 +1054,7 @@ static void examine_vd(int n, struct ddf_super *sb, char *guid) 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) @@ -1036,7 +1065,7 @@ static void examine_vd(int n, struct ddf_super *sb, char *guid) /* 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; jsb; struct mdinfo info; - int i; + unsigned int i; char nbuf[64]; getinfo_super_ddf(st, &info); 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]; @@ -1186,7 +1227,6 @@ static void brief_examine_super_ddf(struct supertype *st, int verbose) printf("ARRAY container=%s member=%d UUID=%s\n", nbuf+5, i, nbuf1+5); } - printf("ARRAY metadata=ddf UUID=%s\n", nbuf + 5); } static void export_examine_super_ddf(struct supertype *st) @@ -1232,7 +1272,11 @@ static int match_home_ddf(struct supertype *st, char *homehost) * 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) && @@ -1241,7 +1285,7 @@ static int match_home_ddf(struct supertype *st, char *homehost) } #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; @@ -1257,8 +1301,8 @@ static int find_phys(struct ddf_super *ddf, __u32 phys_refnum) /* 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; @@ -1321,6 +1365,7 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info) (ddf->anchor.guid+16)); info->array.utime = 0; info->array.chunk_size = 0; + info->container_enough = 1; info->disk.major = 0; @@ -1338,9 +1383,10 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info) 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; @@ -1376,7 +1422,7 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info) 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]; @@ -1399,13 +1445,15 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info) 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); @@ -1467,45 +1515,30 @@ static int update_super_ddf(struct supertype *st, struct mdinfo *info, 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; + } 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; + } if (strcmp(update, "_reshape_progress") == 0) { /* We don't support reshape yet */ - } + } 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; @@ -1572,13 +1605,8 @@ static int init_super_ddf(struct supertype *st, 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__); @@ -1587,6 +1615,12 @@ static int init_super_ddf(struct supertype *st, 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. @@ -1721,7 +1755,7 @@ static int init_super_ddf(struct supertype *st, 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); @@ -1871,7 +1905,7 @@ FIXME ignore DDF_Legacy devices? */ struct extent *rv; int n = 0; - int i, j; + unsigned int i, j; rv = malloc(sizeof(struct extent) * (ddf->max_part + 2)); if (!rv) @@ -1881,7 +1915,7 @@ FIXME ignore DDF_Legacy devices? 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]); @@ -1909,7 +1943,7 @@ static int init_super_ddf_bvd(struct supertype *st, * 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; @@ -2030,8 +2064,8 @@ static void add_to_super_ddf_bvd(struct supertype *st, 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; @@ -2076,7 +2110,7 @@ static void add_to_super_ddf_bvd(struct supertype *st, 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) @@ -2093,7 +2127,7 @@ static void add_to_super_ddf_bvd(struct supertype *st, */ 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++; @@ -2127,7 +2161,7 @@ static int add_to_super_ddf(struct supertype *st, 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) { @@ -2163,11 +2197,11 @@ static int add_to_super_ddf(struct supertype *st, 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; @@ -2310,7 +2344,7 @@ static int __write_init_super_ddf(struct supertype *st, int do_close) 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; @@ -2345,15 +2379,19 @@ 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; + 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)); @@ -2372,20 +2410,24 @@ static int write_init_super_ddf(struct supertype *st) 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 + } 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, 1); + } } #endif @@ -2533,8 +2575,12 @@ static int validate_geometry_ddf(struct supertype *st, 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) { @@ -2582,7 +2628,7 @@ static int validate_geometry_ddf(struct supertype *st, 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; } @@ -2674,8 +2720,11 @@ static int validate_geometry_ddf_bvd(struct supertype *st, 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; @@ -2724,8 +2773,8 @@ static int validate_geometry_ddf_bvd(struct supertype *st, 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) { @@ -2762,14 +2811,8 @@ static int load_super_ddf_all(struct supertype *st, int fd, 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 || @@ -2826,14 +2869,25 @@ static int load_super_ddf_all(struct supertype *st, int fd, return 1; } if (st->subarray[0]) { + unsigned long val; struct vcl *v; + char *ep; + + val = strtoul(st->subarray, &ep, 10); + if (*ep != '\0') { + free(super); + return 1; + } for (v = super->conflist; v; v = v->next) - if (v->vcnum == atoi(st->subarray)) + if (v->vcnum == val) super->currentconf = v; - if (!super->currentconf) + if (!super->currentconf) { + free(super); return 1; + } } + *sbp = super; if (st->ss == NULL) { st->ss = &super_ddf; @@ -2862,8 +2916,8 @@ static struct mdinfo *container_content_ddf(struct supertype *st) for (vc = ddf->conflist ; vc ; vc=vc->next) { - int i; - int j; + unsigned int i; + unsigned int j; struct mdinfo *this; this = malloc(sizeof(*this)); memset(this, 0, sizeof(*this)); @@ -2892,7 +2946,7 @@ static struct mdinfo *container_content_ddf(struct supertype *st) 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; @@ -2913,7 +2967,7 @@ static struct mdinfo *container_content_ddf(struct supertype *st) 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; @@ -2939,6 +2993,7 @@ static struct mdinfo *container_content_ddf(struct supertype *st) dev->disk.minor = d->minor; dev->disk.raid_disk = i; dev->disk.state = (1<recovery_start = MaxSector; dev->events = __be32_to_cpu(ddf->primary.seq); dev->data_offset = __be64_to_cpu(vc->lba_offset[i]); @@ -2950,12 +3005,22 @@ static struct mdinfo *container_content_ddf(struct supertype *st) 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; @@ -3027,7 +3092,7 @@ static int ddf_set_array_state(struct active_array *a, int consistent) 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) @@ -3039,9 +3104,9 @@ static int ddf_set_array_state(struct active_array *a, int 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; @@ -3049,7 +3114,7 @@ static int ddf_set_array_state(struct active_array *a, int consistent) ddf->updates_pending = 1; dprintf("ddf mark %d %s %llu\n", inst, consistent?"clean":"dirty", - a->resync_start); + a->info.resync_start); return consistent; } @@ -3070,7 +3135,7 @@ static int ddf_set_array_state(struct active_array *a, int 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; @@ -3211,8 +3276,8 @@ static void ddf_process_update(struct supertype *st, 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); @@ -3271,7 +3336,7 @@ static void ddf_process_update(struct supertype *st, 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) @@ -3298,8 +3363,8 @@ static void ddf_process_update(struct supertype *st, } /* 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] == @@ -3434,7 +3499,7 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, 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 && @@ -3508,6 +3573,7 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, 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; @@ -3587,6 +3653,7 @@ 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, @@ -3605,7 +3672,7 @@ struct superswitch 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,