]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - super-ddf.c
Release 3.2.6 - stability release
[thirdparty/mdadm.git] / super-ddf.c
index 21a917e4fc965f09a4155f983cd652d88092aa66..2b0dabf4cbbebd86b805907e2804ec8de2b3892a 100644 (file)
@@ -1336,6 +1336,7 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m
 {
        struct ddf_super *ddf = st->sb;
        int map_disks = info->array.raid_disks;
+       __u32 *cptr;
 
        if (ddf->currentconf) {
                getinfo_super_ddf_bvd(st, info, map);
@@ -1347,8 +1348,9 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m
        info->array.level         = LEVEL_CONTAINER;
        info->array.layout        = 0;
        info->array.md_minor      = -1;
-       info->array.ctime         = DECADE + __be32_to_cpu(*(__u32*)
-                                                        (ddf->anchor.guid+16));
+       cptr = (__u32 *)(ddf->anchor.guid + 16);
+       info->array.ctime         = DECADE + __be32_to_cpu(*cptr);
+
        info->array.utime         = 0;
        info->array.chunk_size    = 0;
        info->container_enough    = 1;
@@ -1374,6 +1376,7 @@ static void getinfo_super_ddf(struct supertype *st, struct mdinfo *info, char *m
 
        info->recovery_start = MaxSector;
        info->reshape_active = 0;
+       info->recovery_blocked = 0;
        info->name[0] = 0;
 
        info->array.major_version = -1;
@@ -1406,6 +1409,7 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, cha
        int j;
        struct dl *dl;
        int map_disks = info->array.raid_disks;
+       __u32 *cptr;
 
        memset(info, 0, sizeof(*info));
        /* FIXME this returns BVD info - what if we want SVD ?? */
@@ -1415,8 +1419,8 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, cha
        info->array.layout        = rlq_to_layout(vc->conf.rlq, vc->conf.prl,
                                                  info->array.raid_disks);
        info->array.md_minor      = -1;
-       info->array.ctime         = DECADE +
-               __be32_to_cpu(*(__u32*)(vc->conf.guid+16));
+       cptr = (__u32 *)(vc->conf.guid + 16);
+       info->array.ctime         = DECADE + __be32_to_cpu(*cptr);
        info->array.utime         = DECADE + __be32_to_cpu(vc->conf.timestamp);
        info->array.chunk_size    = 512 << vc->conf.chunk_shift;
        info->custom_array_size   = 0;
@@ -1430,23 +1434,26 @@ static void getinfo_super_ddf_bvd(struct supertype *st, struct mdinfo *info, cha
        }
 
        for (dl = ddf->dlist; dl ; dl = dl->next)
-               if (dl->raiddisk == info->disk.raid_disk)
+               if (dl->raiddisk == ddf->currentdev)
                        break;
+
        info->disk.major = 0;
        info->disk.minor = 0;
+       info->disk.state = 0;
        if (dl) {
                info->disk.major = dl->major;
                info->disk.minor = dl->minor;
+               info->disk.raid_disk = dl->raiddisk;
+               info->disk.number = dl->pdnum;
+               info->disk.state = (1<<MD_DISK_SYNC)|(1<<MD_DISK_ACTIVE);
        }
-//     info->disk.number = __be32_to_cpu(ddf->disk.refnum);
-//     info->disk.raid_disk = find refnum in the table and use index;
-//     info->disk.state = ???;
 
        info->container_member = ddf->currentconf->vcnum;
 
        info->recovery_start = MaxSector;
        info->resync_start = 0;
        info->reshape_active = 0;
+       info->recovery_blocked = 0;
        if (!(ddf->virt->entries[info->container_member].state
              & DDF_state_inconsistent)  &&
            (ddf->virt->entries[info->container_member].init_state
@@ -2188,6 +2195,7 @@ static int add_to_super_ddf(struct supertype *st,
        struct phys_disk_entry *pde;
        unsigned int n, i;
        struct stat stb;
+       __u32 *tptr;
 
        if (ddf->currentconf) {
                add_to_super_ddf_bvd(st, dk, fd, devname);
@@ -2216,8 +2224,9 @@ static int add_to_super_ddf(struct supertype *st,
        tm = localtime(&now);
        sprintf(dd->disk.guid, "%8s%04d%02d%02d",
                T10, tm->tm_year+1900, tm->tm_mon+1, tm->tm_mday);
-       *(__u32*)(dd->disk.guid + 16) = random32();
-       *(__u32*)(dd->disk.guid + 20) = random32();
+       tptr = (__u32 *)(dd->disk.guid + 16);
+       *tptr++ = random32();
+       *tptr = random32();
 
        do {
                /* Cannot be bothered finding a CRC of some irrelevant details*/
@@ -2317,8 +2326,7 @@ static int remove_from_super_ddf(struct supertype *st, mdu_disk_info_t *dk)
  * called when creating a container or adding another device to a
  * container.
  */
-
-static unsigned char null_conf[4096+512];
+#define NULL_CONF_SZ   4096
 
 static int __write_init_super_ddf(struct supertype *st)
 {
@@ -2331,6 +2339,12 @@ static int __write_init_super_ddf(struct supertype *st)
        int attempts = 0;
        int successes = 0;
        unsigned long long size, sector;
+       char *null_aligned;
+
+       if (posix_memalign((void**)&null_aligned, 4096, NULL_CONF_SZ) != 0) {
+               return -ENOMEM;
+       }
+       memset(null_aligned, 0xff, NULL_CONF_SZ);
 
        /* try to write updated metadata,
         * if we catch a failure move on to the next disk
@@ -2400,14 +2414,11 @@ static int __write_init_super_ddf(struct supertype *st)
                                if (write(fd, &c->conf, conf_size) < 0)
                                        break;
                        } else {
-                               char *null_aligned = (char*)((((unsigned long)null_conf)+511)&~511UL);
-                               if (null_conf[0] != 0xff)
-                                       memset(null_conf, 0xff, sizeof(null_conf));
                                unsigned int togo = conf_size;
-                               while (togo > sizeof(null_conf)-512) {
-                                       if (write(fd, null_aligned, sizeof(null_conf)-512) < 0)
+                               while (togo > NULL_CONF_SZ) {
+                                       if (write(fd, null_aligned, NULL_CONF_SZ) < 0)
                                                break;
-                                       togo -= sizeof(null_conf)-512;
+                                       togo -= NULL_CONF_SZ;
                                }
                                if (write(fd, null_aligned, togo) < 0)
                                        break;
@@ -2426,6 +2437,7 @@ static int __write_init_super_ddf(struct supertype *st)
                        continue;
                successes++;
        }
+       free(null_aligned);
 
        return attempts != successes;
 }
@@ -2553,7 +2565,7 @@ static int reserve_space(struct supertype *st, int raiddisks,
                                continue;
                        /* This is bigger than 'size', see if there are enough */
                        cnt = 0;
-                       for (dl2 = dl; dl2 ; dl2=dl2->next)
+                       for (dl2 = ddf->dlist; dl2 ; dl2=dl2->next)
                                if (dl2->esize >= dl->esize)
                                        cnt++;
                        if (cnt >= raiddisks)
@@ -2617,7 +2629,7 @@ static int validate_geometry_ddf(struct supertype *st,
        if (chunk && *chunk == UnSet)
                *chunk = DEFAULT_CHUNK;
 
-
+       if (level == -1000000) level = LEVEL_CONTAINER;
        if (level == LEVEL_CONTAINER) {
                /* Must be a fresh device to add to a container */
                return validate_geometry_ddf_container(st, level, layout,
@@ -2963,6 +2975,7 @@ static struct mdinfo *container_content_ddf(struct supertype *st, char *subarray
                unsigned int j;
                struct mdinfo *this;
                char *ep;
+               __u32 *cptr;
 
                if (subarray &&
                    (strtoul(subarray, &ep, 10) != vc->vcnum ||
@@ -2982,8 +2995,8 @@ static struct mdinfo *container_content_ddf(struct supertype *st, char *subarray
                this->array.md_minor      = -1;
                this->array.major_version = -1;
                this->array.minor_version = -2;
-               this->array.ctime         = DECADE +
-                       __be32_to_cpu(*(__u32*)(vc->conf.guid+16));
+               cptr = (__u32 *)(vc->conf.guid + 16);
+               this->array.ctime         = DECADE + __be32_to_cpu(*cptr);
                this->array.utime         = DECADE +
                        __be32_to_cpu(vc->conf.timestamp);
                this->array.chunk_size    = 512 << vc->conf.chunk_shift;
@@ -3705,6 +3718,10 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a,
                        } else if (ddf->phys->entries[dl->pdnum].type &
                                   __cpu_to_be16(DDF_Global_Spare)) {
                                is_global = 1;
+                       } else if (!(ddf->phys->entries[dl->pdnum].state &
+                                    __cpu_to_be16(DDF_Failed))) {
+                               /* we can possibly use some of this */
+                               is_global = 1;
                        }
                        if ( ! (is_dedicated ||
                                (is_global && global_ok))) {