]> git.ipfire.org Git - thirdparty/mdadm.git/blobdiff - super0.c
Disk removal support for Raid10->Raid0 takeover
[thirdparty/mdadm.git] / super0.c
index 5db118ca39c2c40bd391c7147cd7d8d2e55e9780..1fcdd24c37526e4adf1da065435458d39bc66b14 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -339,11 +339,12 @@ static void uuid_from_super0(struct supertype *st, int uuid[4])
        }
 }
 
-static void getinfo_super0(struct supertype *st, struct mdinfo *info)
+static void getinfo_super0(struct supertype *st, struct mdinfo *info, char *map)
 {
        mdp_super_t *sb = st->sb;
        int working = 0;
        int i;
+       int map_disks = info->array.raid_disks;
 
        info->array.major_version = sb->major_version;
        info->array.minor_version = sb->minor_version;
@@ -389,13 +390,28 @@ static void getinfo_super0(struct supertype *st, struct mdinfo *info)
        /* work_disks is calculated rather than read directly */
        for (i=0; i < MD_SB_DISKS; i++)
                if ((sb->disks[i].state & (1<<MD_DISK_SYNC)) &&
-                   (sb->disks[i].raid_disk < info->array.raid_disks) &&
+                   (sb->disks[i].raid_disk < (unsigned)info->array.raid_disks) &&
                    (sb->disks[i].state & (1<<MD_DISK_ACTIVE)) &&
-                   !(sb->disks[i].state & (1<<MD_DISK_FAULTY)))
+                   !(sb->disks[i].state & (1<<MD_DISK_FAULTY))) {
                        working ++;
+                       if (map && i < map_disks)
+                               map[i] = 1;
+               } else if (map && i < map_disks)
+                       map[i] = 0;
        info->array.working_disks = working;
 }
 
+static struct mdinfo *container_content0(struct supertype *st, char *subarray)
+{
+       struct mdinfo *info;
+
+       if (subarray)
+               return NULL;
+
+       info = malloc(sizeof(*info));
+       getinfo_super0(st, info, NULL);
+       return info;
+}
 
 static int update_super0(struct supertype *st, struct mdinfo *info,
                         char *update,
@@ -419,15 +435,13 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
                if (verbose >= 0)
                        fprintf (stderr, Name ": adjusting superblock of %s for 2.2/sparc compatability.\n",
                                 devname);
-       }
-       if (strcmp(update, "super-minor") ==0) {
+       } else if (strcmp(update, "super-minor") ==0) {
                sb->md_minor = info->array.md_minor;
                if (verbose > 0)
                        fprintf(stderr, Name ": updating superblock of %s with minor number %d\n",
                                devname, info->array.md_minor);
-       }
-       if (strcmp(update, "summaries") == 0) {
-               int i;
+       } else if (strcmp(update, "summaries") == 0) {
+               unsigned int i;
                /* set nr_disks, active_disks, working_disks,
                 * failed_disks, spare_disks based on disks[]
                 * array in superblock.
@@ -453,8 +467,7 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
                                        sb->spare_disks++;
                        } else if (i >= sb->raid_disks && sb->disks[i].number == 0)
                                sb->disks[i].state = 0;
-       }
-       if (strcmp(update, "force-one")==0) {
+       } else if (strcmp(update, "force-one")==0) {
                /* Not enough devices for a working array, so
                 * bring this one up-to-date.
                 */
@@ -464,8 +477,7 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
                if (sb->events_hi != ehi ||
                    sb->events_lo != elo)
                        rv = 1;
-       }
-       if (strcmp(update, "force-array")==0) {
+       } else if (strcmp(update, "force-array")==0) {
                /* degraded array and 'force' requested, so
                 * maybe need to mark it 'clean'
                 */
@@ -475,8 +487,7 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
                        sb->state |= (1 << MD_SB_CLEAN);
                        rv = 1;
                }
-       }
-       if (strcmp(update, "assemble")==0) {
+       } else if (strcmp(update, "assemble")==0) {
                int d = info->disk.number;
                int wonly = sb->disks[d].state & (1<<MD_DISK_WRITEMOSTLY);
                int mask = (1<<MD_DISK_WRITEMOSTLY);
@@ -487,12 +498,11 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
                         */
                        add = (1<<MD_DISK_SYNC);
                if (((sb->disks[d].state & ~mask) | add)
-                   != info->disk.state) {
+                   != (unsigned)info->disk.state) {
                        sb->disks[d].state = info->disk.state | wonly;
                        rv = 1;
                }
-       }
-       if (strcmp(update, "linear-grow-new") == 0) {
+       } else if (strcmp(update, "linear-grow-new") == 0) {
                memset(&sb->disks[info->disk.number], 0, sizeof(sb->disks[0]));
                sb->disks[info->disk.number].number = info->disk.number;
                sb->disks[info->disk.number].major = info->disk.major;
@@ -500,8 +510,7 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
                sb->disks[info->disk.number].raid_disk = info->disk.raid_disk;
                sb->disks[info->disk.number].state = info->disk.state;
                sb->this_disk = sb->disks[info->disk.number];
-       }
-       if (strcmp(update, "linear-grow-update") == 0) {
+       } else if (strcmp(update, "linear-grow-update") == 0) {
                sb->raid_disks = info->array.raid_disks;
                sb->nr_disks = info->array.nr_disks;
                sb->active_disks = info->array.active_disks;
@@ -512,20 +521,17 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
                sb->disks[info->disk.number].minor = info->disk.minor;
                sb->disks[info->disk.number].raid_disk = info->disk.raid_disk;
                sb->disks[info->disk.number].state = info->disk.state;
-       }
-       if (strcmp(update, "resync") == 0) {
+       } else if (strcmp(update, "resync") == 0) {
                /* make sure resync happens */
                sb->state &= ~(1<<MD_SB_CLEAN);
                sb->recovery_cp = 0;
-       }
-       if (strcmp(update, "homehost") == 0 &&
+       } else if (strcmp(update, "homehost") == 0 &&
            homehost) {
                uuid_set = 0;
                update = "uuid";
                info->uuid[0] = sb->set_uuid0;
                info->uuid[1] = sb->set_uuid1;
-       }
-       if (strcmp(update, "uuid") == 0) {
+       } else if (strcmp(update, "uuid") == 0) {
                if (!uuid_set && homehost) {
                        char buf[20];
                        char *hash = sha1_buffer(homehost,
@@ -542,9 +548,10 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
                        bm = (struct bitmap_super_s*)(sb+1);
                        uuid_from_super0(st, (int*)bm->uuid);
                }
-       }
-       if (strcmp(update, "_reshape_progress")==0)
+       } else if (strcmp(update, "_reshape_progress")==0)
                sb->reshape_position = info->reshape_progress;
+       else
+               rv = -1;
 
        sb->sb_csum = calc_sb0_csum(sb);
        return rv;
@@ -593,7 +600,7 @@ static int init_super0(struct supertype *st, mdu_array_info_t *info,
        sb->gvalid_words = 0; /* ignored */
        sb->ctime = time(0);
        sb->level = info->level;
-       if (size != info->size)
+       if (size != (unsigned long long)info->size)
                return 0;
        sb->size = info->size;
        sb->nr_disks = info->nr_disks;
@@ -813,9 +820,6 @@ static int load_super0(struct supertype *st, int fd, char *devname)
 
        free_super0(st);
 
-       if (st->subarray[0])
-               return 1;
-
        if (!get_dev_size(fd, devname, &dsize))
                return 1;
 
@@ -913,6 +917,7 @@ static struct supertype *match_metadata_desc0(char *arg)
        if (!st) return st;
 
        memset(st, 0, sizeof(*st));
+       st->container_dev = NoMdDev;
        st->ss = &super0;
        st->info = NULL;
        st->minor_version = 90;
@@ -982,7 +987,7 @@ static int add_internal_bitmap0(struct supertype *st, int *chunkp,
                chunk = min_chunk;
                if (chunk < 64*1024*1024)
                        chunk = 64*1024*1024;
-       } else if (chunk < min_chunk)
+       } else if ((unsigned long long)chunk < min_chunk)
                return 0; /* chunk size too small */
 
        sb->state |= (1<<MD_SB_BITMAP_PRESENT);
@@ -1140,6 +1145,7 @@ struct superswitch super0 = {
        .match_home = match_home0,
        .uuid_from_super = uuid_from_super0,
        .getinfo_super = getinfo_super0,
+       .container_content = container_content0,
        .update_super = update_super0,
        .init_super = init_super0,
        .store_super = store_super0,