]> git.ipfire.org Git - thirdparty/mdadm.git/commitdiff
DDF: load_ddf_local: store VD conf for other BVDs
authormwilck@arcor.de <mwilck@arcor.de>
Fri, 1 Mar 2013 22:28:26 +0000 (23:28 +0100)
committerNeilBrown <neilb@suse.de>
Mon, 4 Mar 2013 05:03:44 +0000 (16:03 +1100)
Store VD config for other BVDs in the other_bvds array.
This allows handling secondary RAID levels in container_content_ddf.

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

index 5763c7264019a8d74dcceb9d4e1c8914ec9d856c..3f16aa65aff75ddc494a26953f7a8b87b5d0cfa3 100644 (file)
@@ -636,6 +636,36 @@ static int load_ddf_global(int fd, struct ddf_super *super, char *devname)
        return 0;
 }
 
+static void add_other_bvd(struct vcl *vcl, struct vd_config *vd,
+                         unsigned int len)
+{
+       int i;
+       for (i = 0; i < vcl->conf.sec_elmnt_count-1; i++)
+               if (vcl->other_bvds[i] != NULL &&
+                   vcl->other_bvds[i]->sec_elmnt_seq == vd->sec_elmnt_seq)
+                       break;
+
+       if (i < vcl->conf.sec_elmnt_count-1) {
+               if (vd->seqnum <= vcl->other_bvds[i]->seqnum)
+                       return;
+       } else {
+               for (i = 0; i < vcl->conf.sec_elmnt_count-1; i++)
+                       if (vcl->other_bvds[i] == NULL)
+                               break;
+               if (i == vcl->conf.sec_elmnt_count-1) {
+                       pr_err("no space for sec level config %u, count is %u\n",
+                              vd->sec_elmnt_seq, vcl->conf.sec_elmnt_count);
+                       return;
+               }
+               if (posix_memalign((void **)&vcl->other_bvds[i], 512, len)
+                   != 0) {
+                       pr_err("%s could not allocate vd buf\n", __func__);
+                       return;
+               }
+       }
+       memcpy(vcl->other_bvds[i], vd, len);
+}
+
 static int load_ddf_local(int fd, struct ddf_super *super,
                          char *devname, int keep)
 {
@@ -731,6 +761,11 @@ static int load_ddf_local(int fd, struct ddf_super *super,
 
                if (vcl) {
                        dl->vlist[vnum++] = vcl;
+                       if (vcl->other_bvds != NULL &&
+                           vcl->conf.sec_elmnt_seq != vd->sec_elmnt_seq) {
+                               add_other_bvd(vcl, vd, super->conf_rec_len*512);
+                               continue;
+                       }
                        if (__be32_to_cpu(vd->seqnum) <=
                            __be32_to_cpu(vcl->conf.seqnum))
                                continue;
@@ -867,8 +902,13 @@ static void free_super_ddf(struct supertype *st)
                ddf->conflist = v->next;
                if (v->block_sizes)
                        free(v->block_sizes);
-               if (v->other_bvds)
+               if (v->other_bvds) {
+                       int i;
+                       for (i = 0; i < v->conf.sec_elmnt_count-1; i++)
+                               if (v->other_bvds[i] != NULL)
+                                       free(v->other_bvds[i]);
                        free(v->other_bvds);
+               }
                free(v);
        }
        while (ddf->dlist) {