On Wed, 3 Jul 2013 22:27:47 +0200 mwilck@xxxxxxxx wrote: > If secondary RAID level is taken into account, translation between > the md RAID member (raid_disk) and the index of a physical disk > in a BVD becomes more complex. > > Also, take into account that the member list can have unused entries > (this is independent of secondary RAID level). > > Adapt usage of find_vdcr() accordingly > > Signed-off-by: Martin Wilck <mwilck@xxxxxxxx> > --- > super-ddf.c | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++-------- > 1 files changed, 87 insertions(+), 13 deletions(-) > > diff --git a/super-ddf.c b/super-ddf.c > index ae24bb9..c448bff 100644 > --- a/super-ddf.c > +++ b/super-ddf.c > @@ -1441,13 +1441,76 @@ static int match_home_ddf(struct supertype *st, char *homehost) > } > > #ifndef MDASSEMBLE > -static struct vd_config *find_vdcr(struct ddf_super *ddf, unsigned int inst) > +static int find_index_in_bvd(const struct ddf_super *ddf, > + const struct vd_config *conf, unsigned int n, > + unsigned int *n_bvd) > +{ > + /* > + * Find the index of the n-th valid physical disk in this BVD > + */ > + unsigned int i, j; > + for (i = 0, j = 0; i < ddf->mppe && > + j < __be16_to_cpu(conf->prim_elmnt_count); i++) { > + if (conf->phys_refnum[i] != 0xffffffff) { Should that 0xffffffff be DDF_NOTFOUND? (I glazed over reading the rest of this patch .. sorry. Maybe I'll try again another day) NeilBrown > + if (n == j) { > + *n_bvd = i; > + return 1; > + } > + j++; > + } > + } > + dprintf("%s: couldn't find BVD member %u (total %u)\n", > + __func__, n, __be16_to_cpu(conf->prim_elmnt_count)); > + return 0; > +} > + > +static struct vd_config *find_vdcr(struct ddf_super *ddf, unsigned int inst, > + unsigned int n, > + unsigned int *n_bvd, struct vcl **vcl) > { > struct vcl *v; > > - for (v = ddf->conflist; v; v = v->next) > - if (inst == v->vcnum) > - return &v->conf; > + for (v = ddf->conflist; v; v = v->next) { > + unsigned int nsec, ibvd; > + struct vd_config *conf; > + if (inst != v->vcnum) > + continue; > + conf = &v->conf; > + if (conf->sec_elmnt_count == 1) { > + if (find_index_in_bvd(ddf, conf, n, n_bvd)) { > + *vcl = v; > + return conf; > + } else > + goto bad; > + } > + if (v->other_bvds == NULL) { > + pr_err("%s: BUG: other_bvds is NULL, nsec=%u\n", > + __func__, conf->sec_elmnt_count); > + goto bad; > + } > + nsec = n / __be16_to_cpu(conf->prim_elmnt_count); > + if (conf->sec_elmnt_seq != nsec) { > + for (ibvd = 1; ibvd < conf->sec_elmnt_count; ibvd++) { > + if (v->other_bvds[ibvd-1] == NULL) > + continue; > + if (v->other_bvds[ibvd-1]->sec_elmnt_seq > + == nsec) > + break; > + } > + if (ibvd == conf->sec_elmnt_count) > + goto bad; > + conf = v->other_bvds[ibvd-1]; > + } > + if (!find_index_in_bvd(ddf, conf, > + n - nsec*conf->sec_elmnt_count, n_bvd)) > + goto bad; > + dprintf("%s: found disk %u as member %u in bvd %d of array %u\n" > + , __func__, n, *n_bvd, ibvd-1, inst); > + *vcl = v; > + return conf; > + } > +bad: > + pr_err("%s: Could't find disk %d in array %u\n", __func__, n, inst); > return NULL; > } > #endif > @@ -3769,9 +3832,11 @@ 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; > - unsigned int inst = a->info.container_member; > - struct vd_config *vc = find_vdcr(ddf, inst); > - int pd = find_phys(ddf, vc->phys_refnum[n]); > + unsigned int inst = a->info.container_member, n_bvd; > + struct vcl *vcl; > + struct vd_config *vc = find_vdcr(ddf, inst, (unsigned int)n, > + &n_bvd, &vcl); > + int pd; > int i, st, working; > struct mdinfo *mdi; > struct dl *dl; > @@ -3796,15 +3861,21 @@ static void ddf_set_disk(struct active_array *a, int n, int state) > if (!dl) > return; > > + pd = find_phys(ddf, vc->phys_refnum[n_bvd]); > if (pd < 0 || pd != dl->pdnum) { > /* disk doesn't currently exist or has changed. > * If it is now in_sync, insert it. */ > + dprintf("%s: phys disk not found for %d: %d/%d ref %08x\n", > + __func__, dl->pdnum, dl->major, dl->minor, > + dl->disk.refnum); > + dprintf("%s: array %u disk %u ref %08x pd %d\n", > + __func__, inst, n_bvd, vc->phys_refnum[n_bvd], pd); > if ((state & DS_INSYNC) && ! (state & DS_FAULTY)) { > - struct vcl *vcl; > - pd = dl->pdnum; > - vc->phys_refnum[n] = dl->disk.refnum; > - vcl = container_of(vc, struct vcl, conf); > - vcl->lba_offset[n] = mdi->data_offset; > + __u64 *lba_offset; > + pd = dl->pdnum; /* FIXME: is this really correct ? */ > + vc->phys_refnum[n_bvd] = dl->disk.refnum; > + lba_offset = (__u64 *)&vc->phys_refnum[ddf->mppe]; > + lba_offset[n_bvd] = mdi->data_offset; > ddf->phys->entries[pd].type &= > ~__cpu_to_be16(DDF_Global_Spare); > ddf->phys->entries[pd].type |= > @@ -4187,8 +4258,10 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, > struct metadata_update *mu; > struct dl *dl; > int i; > + struct vcl *vcl; > struct vd_config *vc; > __u64 *lba; > + unsigned int n_bvd; > > for (d = a->info.devs ; d ; d = d->next) { > if ((d->curr_state & DS_FAULTY) && > @@ -4353,7 +4426,8 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a, > mu->space = NULL; > mu->space_list = NULL; > mu->next = *updates; > - vc = find_vdcr(ddf, a->info.container_member); > + vc = find_vdcr(ddf, a->info.container_member, di->disk.raid_disk, > + &n_bvd, &vcl); > memcpy(mu->buf, vc, ddf->conf_rec_len * 512); > > vc = (struct vd_config*)mu->buf;
Attachment:
signature.asc
Description: PGP signature