]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
DDF: get_extents: support secondary RAID level
authormwilck@arcor.de <mwilck@arcor.de>
Wed, 3 Jul 2013 20:27:57 +0000 (22:27 +0200)
committerNeilBrown <neilb@suse.de>
Mon, 8 Jul 2013 06:49:23 +0000 (16:49 +1000)
Use get_pd_index_from_refnum() in get_extents to determine
matching VD. This will ensure RAID 10 (secondary RAID level)
support, too.

This also fixes a bug in the previous get_extents() code (missing
__be16_to_cpu for conf.prim_elmnt_count).

DDF test case (10ddf-create) verified.

Signed-off-by: Martin Wilck <mwilck@arcor.de>
Signed-off-by: NeilBrown <neilb@suse.de>
super-ddf.c

index 3346adff2bb3be3d67736090ae7715f975331ef2..617f83f5d3feeba22551e2c1061ca74e7aab783f 100644 (file)
@@ -467,6 +467,11 @@ static void pr_state(const struct ddf_super *ddf, const char *msg) {}
 #define ddf_set_updates_pending(x) \
        do { (x)->updates_pending = 1; pr_state(x, __func__); } while (0)
 
+static unsigned int get_pd_index_from_refnum(const struct vcl *vc,
+                                            __u32 refnum, unsigned int nmax,
+                                            const struct vd_config **bvd,
+                                            unsigned int *idx);
+
 static unsigned int calc_crc(void *buf, int len)
 {
        /* crcs are always at the same place as in the ddf_header */
@@ -2292,23 +2297,21 @@ static struct extent *get_extents(struct ddf_super *ddf, struct dl *dl)
         */
        struct extent *rv;
        int n = 0;
-       unsigned int i, j;
+       unsigned int i;
 
        rv = xmalloc(sizeof(struct extent) * (ddf->max_part + 2));
 
        for (i = 0; i < ddf->max_part; i++) {
+               const struct vd_config *bvd;
+               unsigned int ibvd;
                struct vcl *v = dl->vlist[i];
-               if (v == NULL)
+               if (v == NULL ||
+                   get_pd_index_from_refnum(v, dl->disk.refnum, ddf->mppe,
+                                            &bvd, &ibvd) == DDF_NOTFOUND)
                        continue;
-               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(
-                                       LBA_OFFSET(ddf, &v->conf)[j]);
-                               rv[n].size = __be64_to_cpu(v->conf.blocks);
-                               n++;
-                               break;
-                       }
+               rv[n].start = __be64_to_cpu(LBA_OFFSET(ddf, bvd)[ibvd]);
+               rv[n].size = __be64_to_cpu(bvd->blocks);
+               n++;
        }
        qsort(rv, n, sizeof(*rv), cmp_extent);
 
@@ -2685,11 +2688,6 @@ static int remove_from_super_ddf(struct supertype *st, mdu_disk_info_t *dk)
  */
 #define NULL_CONF_SZ   4096
 
-static unsigned int get_pd_index_from_refnum(const struct vcl *vc,
-                                            __u32 refnum, unsigned int nmax,
-                                            const struct vd_config **bvd,
-                                            unsigned int *idx);
-
 static int __write_ddf_structure(struct dl *d, struct ddf_super *ddf, __u8 type,
                                 char *null_aligned)
 {