Drop the superblock arg from all metadata methods.
authorNeil Brown <neilb@suse.de>
Fri, 14 Dec 2007 09:14:33 +0000 (20:14 +1100)
committerNeil Brown <neilb@suse.de>
Fri, 14 Dec 2007 09:14:33 +0000 (20:14 +1100)
It is now in the 'supertype'

14 files changed:
Assemble.c
Create.c
Detail.c
Examine.c
Grow.c
Incremental.c
Kill.c
Manage.c
Query.c
bitmap.c
mdadm.h
super0.c
super1.c
util.c

index 98e4976..f78ca06 100644 (file)
@@ -115,7 +115,6 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
        int must_close = 0;
        int old_linux = 0;
        int vers = 0; /* Keep gcc quite - it really is initialised */
-       void *first_super = NULL, *super = NULL;
        struct {
                char *devname;
                unsigned int major, minor;
@@ -215,7 +214,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                char *devname = tmpdev->devname;
                int dfd;
                struct stat stb;
-               struct supertype *tst = st;
+               struct supertype *tst = dup_super(st);
 
                if (tmpdev->used > 1) continue;
 
@@ -246,55 +245,60 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                fprintf(stderr, Name ": no recogniseable superblock on %s\n",
                                        devname);
                        tmpdev->used = 2;
-               } else if (tst->ss->load_super(tst,dfd, &super, NULL)) {
+               } else if (tst->ss->load_super(tst,dfd, NULL)) {
                        if ((inargv && verbose >= 0) || verbose > 0)
                                fprintf( stderr, Name ": no RAID superblock on %s\n",
                                         devname);
                } else {
-                       tst->ss->getinfo_super(tst, &info, super);
+                       tst->ss->getinfo_super(tst, &info);
                }
                if (dfd >= 0) close(dfd);
 
                if (ident->uuid_set && (!update || strcmp(update, "uuid")!= 0) &&
-                   (!super || same_uuid(info.uuid, ident->uuid, tst->ss->swapuuid)==0)) {
+                   (!tst || !tst->sb ||
+                    same_uuid(info.uuid, ident->uuid, tst->ss->swapuuid)==0)) {
                        if ((inargv && verbose >= 0) || verbose > 0)
                                fprintf(stderr, Name ": %s has wrong uuid.\n",
                                        devname);
                        goto loop;
                }
                if (ident->name[0] && (!update || strcmp(update, "name")!= 0) &&
-                   (!super || name_matches(info.name, ident->name, homehost)==0)) {
+                   (!tst || !tst->sb ||
+                    name_matches(info.name, ident->name, homehost)==0)) {
                        if ((inargv && verbose >= 0) || verbose > 0)
                                fprintf(stderr, Name ": %s has wrong name.\n",
                                        devname);
                        goto loop;
                }
                if (ident->super_minor != UnSet &&
-                   (!super || ident->super_minor != info.array.md_minor)) {
+                   (!tst || !tst->sb ||
+                    ident->super_minor != info.array.md_minor)) {
                        if ((inargv && verbose >= 0) || verbose > 0)
                                fprintf(stderr, Name ": %s has wrong super-minor.\n",
                                        devname);
                        goto loop;
                }
                if (ident->level != UnSet &&
-                   (!super|| ident->level != info.array.level)) {
+                   (!tst || !tst->sb ||
+                    ident->level != info.array.level)) {
                        if ((inargv && verbose >= 0) || verbose > 0)
                                fprintf(stderr, Name ": %s has wrong raid level.\n",
                                        devname);
                        goto loop;
                }
                if (ident->raid_disks != UnSet &&
-                   (!super || ident->raid_disks!= info.array.raid_disks)) {
+                   (!tst || !tst->sb ||
+                    ident->raid_disks!= info.array.raid_disks)) {
                        if ((inargv && verbose >= 0) || verbose > 0)
                                fprintf(stderr, Name ": %s requires wrong number of drives.\n",
                                        devname);
                        goto loop;
                }
                if (mdfd < 0) {
-                       if (tst == NULL || super == NULL)
+                       if (tst == NULL || tst->sb == NULL)
                                continue;
                        if (update == NULL &&
-                           tst->ss->match_home(tst, super, homehost)==0) {
+                           tst->ss->match_home(tst, homehost)==0) {
                                if ((inargv && verbose >= 0) || verbose > 0)
                                        fprintf(stderr, Name ": %s is not built for host %s.\n",
                                                devname, homehost);
@@ -311,15 +315,17 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                 * the other isn't that can disambiguate.
                 */
 
-               if (!super) {
+               if (!tst || !tst->sb) {
                        fprintf(stderr, Name ": %s has no superblock - assembly aborted\n",
                                devname);
-                       st->ss->free_super(st, first_super);
+                       st->ss->free_super(st);
                        return 1;
                }
 
                if (st == NULL)
-                       st = tst;
+                       st = dup_super(tst);
+               if (st->minor_version == -1)
+                       st->minor_version = tst->minor_version;
                if (st->ss != tst->ss ||
                    st->minor_version != tst->minor_version ||
                    st->ss->compare_super(st, tst) != 0) {
@@ -331,10 +337,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                        if (mdfd < 0)
                                goto loop;
                        if (homehost) {
-                               int first = st->ss->match_home(st, first_super,
-                                                              homehost);
-                               int last = tst->ss->match_home(tst, super,
-                                                              homehost);
+                               int first = st->ss->match_home(st, homehost);
+                               int last = tst->ss->match_home(tst, homehost);
                                if (first+last == 1) {
                                        /* We can do something */
                                        if (first) {/* just ignore this one */
@@ -357,17 +361,15 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                        }
                        fprintf(stderr, Name ": superblock on %s doesn't match others - assembly aborted\n",
                                devname);
-                       tst->ss->free_super(tst, super);
-                       st->ss->free_super(st, first_super);
+                       tst->ss->free_super(tst);
+                       st->ss->free_super(st);
                        return 1;
                }
 
                tmpdev->used = 1;
 
        loop:
-               if (super)
-                       tst->ss->free_super(tst, super);
-               super = NULL;
+               tst->ss->free_super(tst);
        }
 
        if (mdfd < 0) {
@@ -377,10 +379,10 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                 */
                mdu_array_info_t inf;
                char *c;
-               if (!first_super) {
+               if (!st->sb) {
                        return 2;
                }
-               st->ss->getinfo_super(st, &info, first_super);
+               st->ss->getinfo_super(st, &info);
                c = strchr(info.name, ':');
                if (c) c++; else c= info.name;
                if (isdigit(*c) && ((ident->autof & 7)==4 || (ident->autof&7)==6))
@@ -390,9 +392,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                        asprintf(&mddev, "/dev/md/%s", c);
                mdfd = open_mddev(mddev, ident->autof);
                if (mdfd < 0) {
-                       st->ss->free_super(st, first_super);
+                       st->ss->free_super(st);
                        free(devices);
-                       first_super = NULL;
                        goto try_again;
                }
                vers = md_get_version(mdfd);
@@ -407,9 +408,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                        mddev, tmpdev->devname);
                        close(mdfd);
                        mdfd = -1;
-                       st->ss->free_super(st, first_super);
+                       st->ss->free_super(st);
                        free(devices);
-                       first_super = NULL;
                        goto try_again;
                }
                must_close = 1;
@@ -426,6 +426,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                        int dfd;
                        /* prepare useful information in info structures */
                        struct stat stb2;
+                       struct supertype *tst;
                        fstat(mdfd, &stb2);
 
                        if (strcmp(update, "uuid")==0 &&
@@ -444,16 +445,17 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
 
                        remove_partitions(dfd);
 
-                       st->ss->load_super(st, dfd, &super, NULL);
-                       st->ss->getinfo_super(st, &info, super);
+                       tst = dup_super(st);
+                       tst->ss->load_super(tst, dfd, NULL);
+                       tst->ss->getinfo_super(tst, &info);
 
                        memcpy(info.uuid, ident->uuid, 16);
                        strcpy(info.name, ident->name);
                        info.array.md_minor = minor(stb2.st_rdev);
 
-                       st->ss->update_super(st, &info, super, update,
-                                            devname, verbose,
-                                            ident->uuid_set, homehost);
+                       tst->ss->update_super(tst, &info, update,
+                                             devname, verbose,
+                                             ident->uuid_set, homehost);
                        if (strcmp(update, "uuid")==0 &&
                            !ident->uuid_set) {
                                ident->uuid_set = 1;
@@ -462,7 +464,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                        if (dfd < 0)
                                fprintf(stderr, Name ": Cannot open %s for superblock update\n",
                                        devname);
-                       else if (st->ss->store_super(st, dfd, super))
+                       else if (tst->ss->store_super(tst, dfd))
                                fprintf(stderr, Name ": Could not re-write superblock on %s.\n",
                                        devname);
                        if (dfd >= 0)
@@ -470,21 +472,26 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
 
                        if (strcmp(update, "uuid")==0 &&
                            ident->bitmap_fd >= 0 && !bitmap_done) {
-                               if (bitmap_update_uuid(ident->bitmap_fd, info.uuid, st->ss->swapuuid) != 0)
+                               if (bitmap_update_uuid(ident->bitmap_fd,
+                                                      info.uuid,
+                                                      tst->ss->swapuuid) != 0)
                                        fprintf(stderr, Name ": Could not update uuid on external bitmap.\n");
                                else
                                        bitmap_done = 1;
                        }
+                       tst->ss->free_super(tst);
                } else
 #endif
                {
+                       struct supertype *tst = dup_super(st);;
                        int dfd;
                        dfd = dev_open(devname, O_RDWR|O_EXCL);
 
                        remove_partitions(dfd);
 
-                       st->ss->load_super(st, dfd, &super, NULL);
-                       st->ss->getinfo_super(st, &info, super);
+                       tst->ss->load_super(tst, dfd, NULL);
+                       tst->ss->getinfo_super(tst, &info);
+                       tst->ss->free_super(tst);
                        close(dfd);
                }
 
@@ -563,10 +570,6 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                                best[i] = devcnt;
                }
                devcnt++;
-
-               if (super)
-                       st->ss->free_super(st, super);
-               super = NULL;
        }
 
        if (update && strcmp(update, "byteorder")==0)
@@ -575,12 +578,12 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
        if (devcnt == 0) {
                fprintf(stderr, Name ": no devices found for %s\n",
                        mddev);
-               st->ss->free_super(st, first_super);
+               st->ss->free_super(st);
                if (must_close) close(mdfd);
                return 1;
        }
 
-       st->ss->getinfo_super(st, &info, first_super);
+       st->ss->getinfo_super(st, &info);
        clean = info.array.state & 1;
 
        /* now we have some devices that might be suitable.
@@ -623,6 +626,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                 * and add it.
                 */
                int fd;
+               struct supertype *tst;
                long long current_events;
                chosen_drive = -1;
                for (i=0; i<info.array.raid_disks && i < bestcnt; i++) {
@@ -650,7 +654,8 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                        devices[chosen_drive].events = 0;
                        continue;
                }
-               if (st->ss->load_super(st,fd, &super, NULL)) {
+               tst = dup_super(st);
+               if (tst->ss->load_super(st,fd, NULL)) {
                        close(fd);
                        fprintf(stderr, Name ": RAID superblock disappeared from %s - not updating.\n",
                                devices[chosen_drive].devname);
@@ -658,16 +663,16 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                        continue;
                }
                info.events = devices[most_recent].events;
-               st->ss->update_super(st, &info, super, "force-one",
+               tst->ss->update_super(tst, &info, "force-one",
                                     devices[chosen_drive].devname, verbose,
                                     0, NULL);
 
-               if (st->ss->store_super(st, fd, super)) {
+               if (tst->ss->store_super(tst, fd)) {
                        close(fd);
                        fprintf(stderr, Name ": Could not re-write superblock on %s\n",
                                devices[chosen_drive].devname);
                        devices[chosen_drive].events = 0;
-                       st->ss->free_super(st, super);
+                       tst->ss->free_super(tst);
                        continue;
                }
                close(fd);
@@ -675,7 +680,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                devices[chosen_drive].uptodate = 1;
                avail[chosen_drive] = 1;
                okcnt++;
-               st->ss->free_super(st, super);
+               tst->ss->free_super(tst);
 
                /* If there are any other drives of the same vintage,
                 * add them in as well.  We can't lose and we might gain
@@ -699,7 +704,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
         * superblock.
         */
        chosen_drive = -1;
-       super = NULL;
+       st->ss->free_super(st);
        for (i=0; chosen_drive < 0 && i<bestcnt; i++) {
                int j = best[i];
                int fd;
@@ -715,7 +720,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                        if (must_close) close(mdfd);
                        return 1;
                }
-               if (st->ss->load_super(st,fd, &super, NULL)) {
+               if (st->ss->load_super(st,fd, NULL)) {
                        close(fd);
                        fprintf(stderr, Name ": RAID superblock has disappeared from %s\n",
                                devices[j].devname);
@@ -724,12 +729,12 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                }
                close(fd);
        }
-       if (super == NULL) {
+       if (st->sb == NULL) {
                fprintf(stderr, Name ": No suitable drives found for %s\n", mddev);
                if (must_close) close(mdfd);
                return 1;
        }
-       st->ss->getinfo_super(st, &info, super);
+       st->ss->getinfo_super(st, &info);
        for (i=0; i<bestcnt; i++) {
                int j = best[i];
                unsigned int desired_state;
@@ -748,7 +753,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                info.disk.state = desired_state;
 
                if (devices[j].uptodate &&
-                   st->ss->update_super(st, &info, super, "assemble", NULL,
+                   st->ss->update_super(st, &info, "assemble", NULL,
                                         verbose, 0, NULL)) {
                        if (force) {
                                if (verbose >= 0)
@@ -775,7 +780,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
            !enough(info.array.level, info.array.raid_disks,
                    info.array.layout, clean,
                    avail, okcnt)) {
-               change += st->ss->update_super(st, &info, super, "force-array",
+               change += st->ss->update_super(st, &info, "force-array",
                                        devices[chosen_drive].devname, verbose,
                                               0, NULL);
                clean = 1;
@@ -790,7 +795,7 @@ int Assemble(struct supertype *st, char *mddev, int mdfd,
                        if (must_close) close(mdfd);
                        return 1;
                }
-               if (st->ss->store_super(st, fd, super)) {
+               if (st->ss->store_super(st, fd)) {
                        close(fd);
                        fprintf(stderr, Name ": Could not re-write superblock on %s\n",
                                devices[chosen_drive].devname);
index 77aaf8e..6cf509a 100644 (file)
--- a/Create.c
+++ b/Create.c
@@ -65,7 +65,6 @@ int Create(struct supertype *st, char *mddev, int mdfd,
        int first_missing = subdevs * 2;
        int missing_disks = 0;
        int insert_point = subdevs * 2; /* where to insert a missing drive */
-       void *super;
        int pass;
        int vers;
        int rv;
@@ -434,7 +433,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                                name += 2;
                }
        }
-       if (!st->ss->init_super(st, &super, &array, size, name, homehost, uuid))
+       if (!st->ss->init_super(st, &array, size, name, homehost, uuid))
                return 1;
 
        if (bitmap_file && vers < 9003) {
@@ -450,7 +449,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                        fprintf(stderr, Name ": internal bitmaps not supported by this kernel.\n");
                        return 1;
                }
-               if (!st->ss->add_internal_bitmap(st, super, &bitmap_chunk,
+               if (!st->ss->add_internal_bitmap(st, &bitmap_chunk,
                                                 delay, write_behind,
                                                 bitmapsize, 1, major_num)) {
                        fprintf(stderr, Name ": Given bitmap chunk size not supported.\n");
@@ -478,7 +477,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
        if (bitmap_file) {
                int uuid[4];
 
-               st->ss->uuid_from_super(st, uuid, super);
+               st->ss->uuid_from_super(st, uuid);
                if (CreateBitmap(bitmap_file, force, (char*)uuid, bitmap_chunk,
                                 delay, write_behind,
                                 bitmapsize,
@@ -542,18 +541,19 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                        }
                        switch(pass){
                        case 1:
-                               st->ss->add_to_super(st, super, &disk);
+                               st->ss->add_to_super(st, &disk);
                                break;
                        case 2:
                                if (disk.state == 1) break;
                                Kill(dv->devname, 0, 1); /* Just be sure it is clean */
                                Kill(dv->devname, 0, 1); /* and again, there could be two superblocks */
-                               st->ss->write_init_super(st, super, &disk, dv->devname);
+                               st->ss->write_init_super(st, &disk,
+                                                        dv->devname);
 
                                if (ioctl(mdfd, ADD_NEW_DISK, &disk)) {
                                        fprintf(stderr, Name ": ADD_NEW_DISK for %s failed: %s\n",
                                                dv->devname, strerror(errno));
-                                       st->ss->free_super(st, super);
+                                       st->ss->free_super(st);
                                        return 1;
                                }
 
@@ -562,7 +562,7 @@ int Create(struct supertype *st, char *mddev, int mdfd,
                        if (dv == moved_disk && dnum != insert_point) break;
                }
        }
-       st->ss->free_super(st, super);
+       st->ss->free_super(st);
 
        /* param is not actually used */
        if (runstop == 1 || subdevs >= raiddisks) {
index cebba6e..2bde9fa 100644 (file)
--- a/Detail.c
+++ b/Detail.c
@@ -56,7 +56,6 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
        int max_disks = MD_SB_DISKS; /* just a default */
        struct mdinfo info;
 
-       void *super = NULL;
        int rv = test ? 4 : 1;
        int avail_disks = 0;
        char *avail;
@@ -109,19 +108,18 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
                    disk.minor == 0)
                        continue;
                if ((dv=map_dev(disk.major, disk.minor, 1))) {
-                       if (!super && (disk.state & (1<<MD_DISK_ACTIVE))) {
+                       if ((!st || !st->sb) &&
+                           (disk.state & (1<<MD_DISK_ACTIVE))) {
                                /* try to read the superblock from this device
                                 * to get more info
                                 */
                                int fd2 = dev_open(dv, O_RDONLY);
                                if (fd2 >=0 && st &&
-                                   st->ss->load_super(st, fd2, &super, NULL) == 0) {
-                                       st->ss->getinfo_super(st, &info, super);
+                                   st->ss->load_super(st, fd2, NULL) == 0) {
+                                       st->ss->getinfo_super(st, &info);
                                        if (info.array.ctime != array.ctime ||
-                                           info.array.level != array.level) {
-                                               st->ss->free_super(st, super);
-                                               super = NULL;
-                                       }
+                                           info.array.level != array.level)
+                                               st->ss->free_super(st);
                                }
                                if (fd2 >= 0) close(fd2);
                        }
@@ -137,8 +135,8 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
                printf("MD_DEVICES=%d\n", array.raid_disks);
                printf("MD_METADATA=%d.%d\n", array.major_version,
                       array.minor_version);
-               if (super)
-                       st->ss->export_super(st, super);
+               if (st && st->sb)
+                       st->ss->export_super(st);
                goto out;
        }
 
@@ -236,13 +234,14 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
 
                if (e && e->percent >= 0) {
                        printf(" Re%s Status : %d%% complete\n",
-                              (super && info.reshape_active)? "shape":"build",
+                              (st && st->sb && info.reshape_active)?
+                                 "shape":"build",
                               e->percent);
                        is_rebuilding = 1;
                }
                free_mdstat(ms);
 
-               if (super && info.reshape_active) {
+               if (st->sb && info.reshape_active) {
 #if 0
 This is pretty boring
                        printf("  Reshape pos'n : %llu%s\n", (unsigned long long) info.reshape_progress<<9,
@@ -277,8 +276,8 @@ This is pretty boring
                        printf("\n");
                } else if (e && e->percent >= 0)
                        printf("\n");
-               if (super && st)
-                       st->ss->detail_super(st, super, homehost);
+               if (st && st->sb)
+                       st->ss->detail_super(st, homehost);
 
                printf("    Number   Major   Minor   RaidDevice State\n");
        }
@@ -376,10 +375,9 @@ This is pretty boring
                if (!brief) printf("\n");
        }
        if (spares && brief) printf(" spares=%d", spares);
-       if (super && brief && st)
-               st->ss->brief_detail_super(st, super);
-       if (super)
-               st->ss->free_super(st, super);
+       if (brief && st && st->sb)
+               st->ss->brief_detail_super(st);
+       st->ss->free_super(st);
 
        if (brief > 1 && devices) printf("\n   devices=%s", devices);
        if (brief) printf("\n");
index 806c552..276e0fa 100644 (file)
--- a/Examine.c
+++ b/Examine.c
@@ -56,12 +56,10 @@ int Examine(mddev_dev_t devlist, int brief, int scan,
         * if devlist==NULL, use conf_get_devs()
         */
        int fd;
-       void *super = NULL;
        int rv = 0;
        int err = 0;
 
        struct array {
-               void *super;
                struct supertype *st;
                struct mdinfo info;
                void *devs;
@@ -85,7 +83,9 @@ int Examine(mddev_dev_t devlist, int brief, int scan,
                        if (!st)
                                st = guess_super(fd);
                        if (st)
-                               err = st->ss->load_super(st, fd, &super, (brief||scan)?NULL:devlist->devname);
+                               err = st->ss->load_super(st, fd,
+                                                        (brief||scan) ? NULL
+                                                          :devlist->devname);
                        else {
                                if (!brief) {
                                        fprintf(stderr, Name ": No md superblock detected on %s.\n", devlist->devname);
@@ -99,7 +99,7 @@ int Examine(mddev_dev_t devlist, int brief, int scan,
                        continue;
 
                if (SparcAdjust)
-                       st->ss->update_super(st, NULL, super, "sparc2.2",
+                       st->ss->update_super(st, NULL, "sparc2.2",
                                             devlist->devname, 0, 0, NULL);
                /* Ok, its good enough to try, though the checksum could be wrong */
                if (brief) {
@@ -112,16 +112,15 @@ int Examine(mddev_dev_t devlist, int brief, int scan,
                        }
                        if (!ap) {
                                ap = malloc(sizeof(*ap));
-                               ap->super = super;
                                ap->devs = dl_head();
                                ap->next = arrays;
                                ap->spares = 0;
                                ap->st = st;
                                arrays = ap;
-                               st->ss->getinfo_super(st, &ap->info, super);
+                               st->ss->getinfo_super(st, &ap->info);
                        } else {
-                               st->ss->getinfo_super(st, &ap->info, super);
-                               st->ss->free_super(st, super);
+                               st->ss->getinfo_super(st, &ap->info);
+                               st->ss->free_super(st);
                        }
                        if (!(ap->info.disk.state & MD_DISK_SYNC))
                                ap->spares++;
@@ -129,8 +128,8 @@ int Examine(mddev_dev_t devlist, int brief, int scan,
                        dl_add(ap->devs, d);
                } else {
                        printf("%s:\n",devlist->devname);
-                       st->ss->examine_super(st, super, homehost);
-                       st->ss->free_super(st, super);
+                       st->ss->examine_super(st, homehost);
+                       st->ss->free_super(st);
                }
        }
        if (brief) {
@@ -138,7 +137,7 @@ int Examine(mddev_dev_t devlist, int brief, int scan,
                for (ap=arrays; ap; ap=ap->next) {
                        char sep='=';
                        char *d;
-                       ap->st->ss->brief_examine_super(ap->st, ap->super);
+                       ap->st->ss->brief_examine_super(ap->st);
                        if (ap->spares) printf("   spares=%d", ap->spares);
                        if (brief > 1) {
                                printf("   devices");
@@ -147,7 +146,7 @@ int Examine(mddev_dev_t devlist, int brief, int scan,
                                        sep=',';
                                }
                        }
-                       ap->st->ss->free_super(ap->st, ap->super);
+                       ap->st->ss->free_super(ap->st);
                        /* FIXME free ap */
                        if (ap->spares || brief > 1)
                                printf("\n");
diff --git a/Grow.c b/Grow.c
index 0aa7287..e07e2c0 100644 (file)
--- a/Grow.c
+++ b/Grow.c
@@ -47,7 +47,6 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
         */
        struct mdinfo info;
 
-       void *super = NULL;
        struct stat stb;
        int nfd, fd2;
        int d, nd;
@@ -103,10 +102,9 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
                        fprintf(stderr, Name ": cannot open device file %s\n", dv);
                        return 1;
                }
-               if (super)
-                       st->ss->free_super(st, super);
-               super= NULL;
-               if (st->ss->load_super(st, fd2, &super, NULL)) {
+               st->ss->free_super(st);
+
+               if (st->ss->load_super(st, fd2, NULL)) {
                        fprintf(stderr, Name ": cannot find super block on %s\n", dv);
                        close(fd2);
                        return 1;
@@ -122,10 +120,10 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
        info.disk.minor = minor(stb.st_rdev);
        info.disk.raid_disk = d;
        info.disk.state = (1 << MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE);
-       st->ss->update_super(st, &info, super, "linear-grow-new", newdev,
+       st->ss->update_super(st, &info, "linear-grow-new", newdev,
                             0, 0, NULL);
 
-       if (st->ss->store_super(st, nfd, super)) {
+       if (st->ss->store_super(st, nfd)) {
                fprintf(stderr, Name ": Cannot store new superblock on %s\n",
                        newdev);
                close(nfd);
@@ -168,7 +166,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
                        fprintf(stderr, Name ": cannot open device file %s\n", dv);
                        return 1;
                }
-               if (st->ss->load_super(st, fd2, &super, NULL)) {
+               if (st->ss->load_super(st, fd2, NULL)) {
                        fprintf(stderr, Name ": cannot find super block on %s\n", dv);
                        close(fd);
                        return 1;
@@ -178,10 +176,10 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
                info.array.active_disks = nd+1;
                info.array.working_disks = nd+1;
 
-               st->ss->update_super(st, &info, super, "linear-grow-update", dv,
+               st->ss->update_super(st, &info, "linear-grow-update", dv,
                                     0, 0, NULL);
 
-               if (st->ss->store_super(st, fd2, super)) {
+               if (st->ss->store_super(st, fd2)) {
                        fprintf(stderr, Name ": Cannot store new superblock on %s\n", dv);
                        close(fd2);
                        return 1;
@@ -303,17 +301,16 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
                                continue;
                        dv = map_dev(disk.major, disk.minor, 1);
                        if (dv) {
-                               void *super;
                                int fd2 = dev_open(dv, O_RDWR);
                                if (fd2 < 0)
                                        continue;
-                               if (st->ss->load_super(st, fd2, &super, NULL)==0) {
+                               if (st->ss->load_super(st, fd2, NULL)==0) {
                                        if (st->ss->add_internal_bitmap(
-                                                   st, super,
+                                                   st,
                                                    &chunk, delay, write_behind,
                                                    bitmapsize, 0, major)
                                                )
-                                               st->ss->write_bitmap(st, fd2, super);
+                                               st->ss->write_bitmap(st, fd2);
                                        else {
                                                fprintf(stderr, Name ": failed to create internal bitmap - chunksize problem.\n");
                                                close(fd2);
@@ -333,7 +330,6 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
                int bitmap_fd;
                int d;
                int max_devs = st->max_devs;
-               void *super = NULL;
 
                /* try to load a superblock */
                for (d=0; d<max_devs; d++) {
@@ -350,9 +346,9 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
                        if (!dv) continue;
                        fd2 = dev_open(dv, O_RDONLY);
                        if (fd2 >= 0 &&
-                           st->ss->load_super(st, fd2, &super, NULL) == 0) {
+                           st->ss->load_super(st, fd2, NULL) == 0) {
                                close(fd2);
-                               st->ss->uuid_from_super(st, uuid, super);
+                               st->ss->uuid_from_super(st, uuid);
                                break;
                        }
                        close(fd2);
@@ -438,7 +434,6 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
        int d, i, spares;
        int nrdisks;
        int err;
-       void *super = NULL;
 
        struct sysarray *sra;
        struct sysdev *sd;
@@ -704,7 +699,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
                }
 
                /* Find a superblock */
-               if (st->ss->load_super(st, fdlist[0], &super, NULL)) {
+               if (st->ss->load_super(st, fdlist[0], NULL)) {
                        fprintf(stderr, Name ": %s: Cannot find a superblock\n",
                                devname);
                        goto abort;
@@ -712,7 +707,7 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
 
 
                memcpy(bsb.magic, "md_backup_data-1", 16);
-               st->ss->uuid_from_super(st, (int*)&bsb.set_uuid, super);
+               st->ss->uuid_from_super(st, (int*)&bsb.set_uuid);
                bsb.mtime = __cpu_to_le64(time(0));
                bsb.arraystart = 0;
                bsb.length = __cpu_to_le64(last_block);
@@ -882,7 +877,6 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
        old_disks = info->array.raid_disks - info->delta_disks;
 
        for (i=old_disks-(backup_file?1:0); i<cnt; i++) {
-               void *super = NULL;
                struct mdinfo dinfo;
                struct mdp_backup_super bsb;
                char buf[4096];
@@ -903,12 +897,12 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
                        fd = fdlist[i];
                        if (fd < 0)
                                continue;
-                       if (st->ss->load_super(st, fd, &super, NULL))
+                       if (st->ss->load_super(st, fd, NULL))
                                continue;
 
-                       st->ss->getinfo_super(st, &dinfo, super);
-                       st->ss->free_super(st, super);
-                       super = NULL;
+                       st->ss->getinfo_super(st, &dinfo);
+                       st->ss->free_super(st);
+
                        if (lseek64(fd,
                                    (dinfo.data_offset + dinfo.component_size - 8) <<9,
                                    0) < 0)
@@ -946,12 +940,11 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
                for(j=0; j<info->array.raid_disks; j++) {
                        if (fdlist[j] < 0)
                                continue;
-                       if (st->ss->load_super(st, fdlist[j], &super, NULL))
+                       if (st->ss->load_super(st, fdlist[j], NULL))
                                /* FIXME should be this be an error */
                                continue;
-                       st->ss->getinfo_super(st, &dinfo, super);
-                       st->ss->free_super(st, super);
-                       super = NULL;
+                       st->ss->getinfo_super(st, &dinfo);
+                       st->ss->free_super(st);
                        offsets[j] = dinfo.data_offset;
                }
                printf(Name ": restoring critical section\n");
@@ -971,15 +964,15 @@ int Grow_restart(struct supertype *st, struct mdinfo *info, int *fdlist, int cnt
 
                for (j=0; j<info->array.raid_disks; j++) {
                        if (fdlist[j] < 0) continue;
-                       if (st->ss->load_super(st, fdlist[j], &super, NULL))
+                       if (st->ss->load_super(st, fdlist[j], NULL))
                                continue;
-                       st->ss->getinfo_super(st, &dinfo, super);
+                       st->ss->getinfo_super(st, &dinfo);
                        dinfo.reshape_progress = __le64_to_cpu(bsb.length);
-                       st->ss->update_super(st, &dinfo, super,
+                       st->ss->update_super(st, &dinfo,
                                             "_reshape_progress",
                                             NULL,0, 0, NULL);
-                       st->ss->store_super(st, fdlist[j], super);
-                       st->ss->free_super(st, super);
+                       st->ss->store_super(st, fdlist[j]);
+                       st->ss->free_super(st);
                }
 
                /* And we are done! */
index fdd8fb4..d3ab72f 100644 (file)
@@ -74,7 +74,6 @@ int Incremental(char *devname, int verbose, int runstop,
         *   start the array (auto-readonly).
         */
        struct stat stb;
-       void *super, *super2;
        struct mdinfo info, info2;
        struct mddev_ident_s *array_list, *match;
        char chosen_name[1024];
@@ -134,14 +133,14 @@ int Incremental(char *devname, int verbose, int runstop,
                close(dfd);
                return 1;
        }
-       if (st->ss->load_super(st, dfd, &super, NULL)) {
+       if (st->ss->load_super(st, dfd, NULL)) {
                if (verbose >= 0)
                        fprintf(stderr, Name ": no RAID superblock on %s.\n",
                                devname);
                close(dfd);
                return 1;
        }
-       st->ss->getinfo_super(st, &info, super);
+       st->ss->getinfo_super(st, &info);
        close (dfd);
 
        /* 3/ Check if there is a match in mdadm.conf */
@@ -207,7 +206,7 @@ int Incremental(char *devname, int verbose, int runstop,
        /* 3a/ if not, check for homehost match.  If no match, reject. */
        if (!match) {
                if (homehost == NULL ||
-                   st->ss->match_home(st, super, homehost) == 0) {
+                   st->ss->match_home(st, homehost) == 0) {
                        if (verbose >= 0)
                                fprintf(stderr, Name
              ": not found in mdadm.conf and not identified by homehost.\n");
@@ -330,6 +329,7 @@ int Incremental(char *devname, int verbose, int runstop,
                mdu_disk_info_t disk;
                int err;
                struct sysarray *sra;
+               struct supertype *st2;
                sra = sysfs_read(mdfd, devnum, (GET_VERSION | GET_DEVS |
                                                GET_STATE));
                if (sra->major_version != st->ss->major ||
@@ -345,7 +345,8 @@ int Incremental(char *devname, int verbose, int runstop,
                }
                sprintf(dn, "%d:%d", sra->devs->major, sra->devs->minor);
                dfd2 = dev_open(dn, O_RDONLY);
-               if (st->ss->load_super(st, dfd2,&super2, NULL)) {
+               st2 = dup_super(st);
+               if (st2->ss->load_super(st2, dfd2, NULL)) {
                        fprintf(stderr, Name
                                ": Strange error loading metadata for %s.\n",
                                chosen_name);
@@ -354,7 +355,8 @@ int Incremental(char *devname, int verbose, int runstop,
                        return 2;
                }
                close(dfd2);
-               st->ss->getinfo_super(st, &info2, super2);
+               st2->ss->getinfo_super(st2, &info2);
+               st2->ss->free_super(st2);
                if (info.array.level != info2.array.level ||
                    memcmp(info.uuid, info2.uuid, 16) != 0 ||
                    info.array.raid_disks != info2.array.raid_disks) {
@@ -478,7 +480,7 @@ static void find_reject(int mdfd, struct supertype *st, struct sysarray *sra,
                        int number, __u64 events, int verbose,
                        char *array_name)
 {
-       /* Find an device attached to this array with a disk.number of number
+       /* Find a device attached to this array with a disk.number of number
         * and events less than the passed events, and remove the device.
         */
        struct sysdev *d;
@@ -491,18 +493,17 @@ static void find_reject(int mdfd, struct supertype *st, struct sysarray *sra,
        for (d = sra->devs; d ; d = d->next) {
                char dn[10];
                int dfd;
-               void *super;
                struct mdinfo info;
                sprintf(dn, "%d:%d", d->major, d->minor);
                dfd = dev_open(dn, O_RDONLY);
                if (dfd < 0)
                        continue;
-               if (st->ss->load_super(st, dfd, &super, NULL)) {
+               if (st->ss->load_super(st, dfd, NULL)) {
                        close(dfd);
                        continue;
                }
-               st->ss->getinfo_super(st, &info, super);
-               st->ss->free_super(st, super);
+               st->ss->getinfo_super(st, &info);
+               st->ss->free_super(st);
                close(dfd);
 
                if (info.disk.number != number ||
@@ -526,14 +527,12 @@ static int count_active(struct supertype *st, int mdfd, char **availp,
        struct sysdev *d;
        int cnt = 0, cnt1 = 0;
        __u64 max_events = 0;
-       void *best_super = NULL;
        struct sysarray *sra = sysfs_read(mdfd, -1, GET_DEVS | GET_STATE);
        char *avail = NULL;
 
        for (d = sra->devs ; d ; d = d->next) {
                char dn[30];
                int dfd;
-               void *super;
                int ok;
                struct mdinfo info;
 
@@ -541,11 +540,11 @@ static int count_active(struct supertype *st, int mdfd, char **availp,
                dfd = dev_open(dn, O_RDONLY);
                if (dfd < 0)
                        continue;
-               ok =  st->ss->load_super(st, dfd, &super, NULL);
+               ok =  st->ss->load_super(st, dfd, NULL);
                close(dfd);
                if (ok != 0)
                        continue;
-               st->ss->getinfo_super(st, &info, super);
+               st->ss->getinfo_super(st, &info);
                if (info.disk.state & (1<<MD_DISK_SYNC))
                {
                        if (avail == NULL) {
@@ -556,7 +555,7 @@ static int count_active(struct supertype *st, int mdfd, char **availp,
                                cnt++;
                                max_events = info.events;
                                avail[info.disk.raid_disk] = 2;
-                               best_super = super; super = NULL;
+                               st->ss->getinfo_super(st, bestinfo);
                        } else if (info.events == max_events) {
                                cnt++;
                                avail[info.disk.raid_disk] = 2;
@@ -574,24 +573,15 @@ static int count_active(struct supertype *st, int mdfd, char **availp,
                                        if (avail[i])
                                                avail[i]--;
                                avail[info.disk.raid_disk] = 2;
-                               st->ss->free_super(st, best_super);
-                               best_super = super;
-                               super = NULL;
+                               st->ss->getinfo_super(st, bestinfo);
                        } else { /* info.events much bigger */
                                cnt = 1; cnt1 = 0;
                                memset(avail, 0, info.disk.raid_disk);
                                max_events = info.events;
-                               st->ss->free_super(st, best_super);
-                               best_super = super;
-                               super = NULL;
+                               st->ss->getinfo_super(st, bestinfo);
                        }
                }
-               if (super)
-                       st->ss->free_super(st, super);
-       }
-       if (best_super) {
-               st->ss->getinfo_super(st, bestinfo,best_super);
-               st->ss->free_super(st, best_super);
+               st->ss->free_super(st);
        }
        return cnt + cnt1;
 }
@@ -613,7 +603,6 @@ void RebuildMap(void)
                        int ok;
                        struct supertype *st;
                        char *path;
-                       void *super;
                        struct mdinfo info;
 
                        sprintf(dn, "%d:%d", sd->major, sd->minor);
@@ -624,11 +613,11 @@ void RebuildMap(void)
                        if ( st == NULL)
                                ok = -1;
                        else
-                               ok = st->ss->load_super(st, dfd, &super, NULL);
+                               ok = st->ss->load_super(st, dfd, NULL);
                        close(dfd);
                        if (ok != 0)
                                continue;
-                       st->ss->getinfo_super(st, &info, super);
+                       st->ss->getinfo_super(st, &info);
                        if (md->devnum > 0)
                                path = map_dev(MD_MAJOR, md->devnum, 0);
                        else
@@ -636,7 +625,7 @@ void RebuildMap(void)
                        map_add(&map, md->devnum, st->ss->major,
                                st->minor_version,
                                info.uuid, path ? : "/unknown");
-                       st->ss->free_super(st, super);
+                       st->ss->free_super(st);
                        break;
                }
        }
diff --git a/Kill.c b/Kill.c
index d7e52f5..0a2763e 100644 (file)
--- a/Kill.c
+++ b/Kill.c
@@ -41,7 +41,6 @@ int Kill(char *dev, int force, int quiet)
         * Definitely not safe.
         */
 
-       void *super;
        int fd, rv = 0;
        struct supertype *st;
 
@@ -60,15 +59,15 @@ int Kill(char *dev, int force, int quiet)
                close(fd);
                return 1;
        }
-       rv = st->ss->load_super(st, fd, &super, dev);
+       rv = st->ss->load_super(st, fd, dev);
        if (force && rv >= 2)
                rv = 0; /* ignore bad data in superblock */
        if (rv== 0 || (force && rv >= 2)) {
                mdu_array_info_t info;
                info.major_version = -1; /* zero superblock */
-               st->ss->free_super(st, super);
-               st->ss->init_super(st, &super, &info, 0, "", NULL, NULL);
-               if (st->ss->store_super(st, fd, super)) {
+               st->ss->free_super(st);
+               st->ss->init_super(st, &info, 0, "", NULL, NULL);
+               if (st->ss->store_super(st, fd)) {
                        if (!quiet)
                                fprintf(stderr, Name ": Could not zero superblock on %s\n",
                                        dev);
index 5219e6e..09d397b 100644 (file)
--- a/Manage.c
+++ b/Manage.c
@@ -192,9 +192,7 @@ int Manage_subdevs(char *devname, int fd,
        struct stat stb;
        int j, jnext = 0;
        int tfd;
-       struct supertype *st;
-       void *dsuper = NULL;
-       void *osuper = NULL; /* original super */
+       struct supertype *st, *tst;
        int duuid[4];
        int ouuid[4];
 
@@ -203,6 +201,15 @@ int Manage_subdevs(char *devname, int fd,
                        devname);
                return 1;
        }
+
+       tst = super_by_version(array.major_version,
+                              array.minor_version);
+       if (!tst) {
+               fprintf(stderr, Name ": unsupport array - version %d.%d\n",
+                       array.major_version, array.minor_version);
+               return 1;
+       }
+
        for (dv = devlist, j=0 ; dv; dv = next, j = jnext) {
                unsigned long long ldsize;
                char dvname[20];
@@ -291,13 +298,6 @@ int Manage_subdevs(char *devname, int fd,
                        return 1;
                case 'a':
                        /* add the device */
-                       st = super_by_version(array.major_version,
-                                             array.minor_version);
-                       if (!st) {
-                               fprintf(stderr, Name ": unsupport array - version %d.%d\n",
-                                       array.major_version, array.minor_version);
-                               return 1;
-                       }
 
                        /* Make sure it isn't in use (in 2.6 or later) */
                        tfd = open(dv->devname, O_RDONLY|O_EXCL);
@@ -307,9 +307,13 @@ int Manage_subdevs(char *devname, int fd,
                                return 1;
                        }
                        remove_partitions(tfd);
+
+                       st = super_by_version(array.major_version,
+                                             array.minor_version);
+
                        if (array.not_persistent==0)
-                               st->ss->load_super(st, tfd, &osuper, NULL);
-                       /* will use osuper later */
+                               st->ss->load_super(st, tfd, NULL);
+
                        if (!get_dev_size(tfd, dv->devname, &ldsize)) {
                                close(tfd);
                                return 1;
@@ -334,7 +338,7 @@ int Manage_subdevs(char *devname, int fd,
                        if (array.not_persistent == 0) {
 
                                /* Make sure device is large enough */
-                               if (st->ss->avail_size(st, ldsize/512) <
+                               if (tst->ss->avail_size(tst, ldsize/512) <
                                    array.size) {
                                        fprintf(stderr, Name ": %s not large enough to join array\n",
                                                dv->devname);
@@ -344,7 +348,7 @@ int Manage_subdevs(char *devname, int fd,
                                /* need to find a sample superblock to copy, and
                                 * a spare slot to use
                                 */
-                               for (j=0; j<st->max_devs; j++) {
+                               for (j = 0; j < tst->max_devs; j++) {
                                        char *dev;
                                        int dfd;
                                        disc.number = j;
@@ -358,14 +362,15 @@ int Manage_subdevs(char *devname, int fd,
                                        if (!dev) continue;
                                        dfd = dev_open(dev, O_RDONLY);
                                        if (dfd < 0) continue;
-                                       if (st->ss->load_super(st, dfd, &dsuper, NULL)) {
+                                       if (tst->ss->load_super(tst, dfd,
+                                                               NULL)) {
                                                close(dfd);
                                                continue;
                                        }
                                        close(dfd);
                                        break;
                                }
-                               if (!dsuper) {
+                               if (!tst->sb) {
                                        fprintf(stderr, Name ": cannot find valid superblock in this array - HELP\n");
                                        return 1;
                                }
@@ -373,7 +378,7 @@ int Manage_subdevs(char *devname, int fd,
                                 * and was temporarily removed, and is now being re-added.
                                 * If so, we can simply re-add it.
                                 */
-                               st->ss->uuid_from_super(st, duuid, dsuper);
+                               tst->ss->uuid_from_super(tst, duuid);
 
                                /* re-add doesn't work for version-1 superblocks
                                 * before 2.6.18 :-(
@@ -381,15 +386,15 @@ int Manage_subdevs(char *devname, int fd,
                                if (array.major_version == 1 &&
                                    get_linux_version() <= 2006018)
                                        ;
-                               else if (osuper) {
-                                       st->ss->uuid_from_super(st, ouuid, osuper);
+                               else if (st->sb) {
+                                       st->ss->uuid_from_super(st, ouuid);
                                        if (memcmp(duuid, ouuid, sizeof(ouuid))==0) {
                                                /* looks close enough for now.  Kernel
                                                 * will worry about whether a bitmap
                                                 * based reconstruction is possible.
                                                 */
                                                struct mdinfo mdi;
-                                               st->ss->getinfo_super(st, &mdi, osuper);
+                                               st->ss->getinfo_super(st, &mdi);
                                                disc.major = major(stb.st_rdev);
                                                disc.minor = minor(stb.st_rdev);
                                                disc.number = mdi.disk.number;
@@ -420,7 +425,7 @@ int Manage_subdevs(char *devname, int fd,
                         * we must choose the same free number, which requires
                         * starting at 'raid_disks' and counting up
                         */
-                       for (j = array.raid_disks; j< st->max_devs; j++) {
+                       for (j = array.raid_disks; j< tst->max_devs; j++) {
                                disc.number = j;
                                if (ioctl(fd, GET_DISK_INFO, &disc))
                                        break;
@@ -436,8 +441,9 @@ int Manage_subdevs(char *devname, int fd,
                        if (array.not_persistent==0) {
                                if (dv->writemostly)
                                        disc.state |= 1 << MD_DISK_WRITEMOSTLY;
-                               st->ss->add_to_super(st, dsuper, &disc);
-                               if (st->ss->write_init_super(st, dsuper, &disc, dv->devname))
+                               tst->ss->add_to_super(tst, &disc);
+                               if (tst->ss->write_init_super(tst, &disc,
+                                                             dv->devname))
                                        return 1;
                        } else if (dv->re_add) {
                                /*  this had better be raid1.
@@ -446,7 +452,7 @@ int Manage_subdevs(char *devname, int fd,
                                 */
                                char *used = malloc(array.raid_disks);
                                memset(used, 0, array.raid_disks);
-                               for (j=0; j< st->max_devs; j++) {
+                               for (j=0; j< tst->max_devs; j++) {
                                        mdu_disk_info_t disc2;
                                        disc2.number = j;
                                        if (ioctl(fd, GET_DISK_INFO, &disc2))
diff --git a/Query.c b/Query.c
index 19b2ce5..0802964 100644 (file)
--- a/Query.c
+++ b/Query.c
@@ -43,7 +43,6 @@ int Query(char *dev)
        int superror, superrno;
        struct mdinfo info;
        mdu_array_info_t array;
-       void *super;
        struct supertype *st = NULL;
 
        unsigned long long larray_size;
@@ -89,14 +88,14 @@ int Query(char *dev)
        }
        st = guess_super(fd);
        if (st) {
-               superror = st->ss->load_super(st, fd, &super, dev);
+               superror = st->ss->load_super(st, fd, dev);
                superrno = errno;
        } else
                superror = -1;
        close(fd);
        if (superror == 0) {
                /* array might be active... */
-               st->ss->getinfo_super(st, &info, super);
+               st->ss->getinfo_super(st, &info);
                if (st->ss->major == 0) {
                        mddev = get_md_name(info.array.md_minor);
                        disc.number = info.disk.number;
index db2342b..fdf8884 100644 (file)
--- a/bitmap.c
+++ b/bitmap.c
@@ -220,7 +220,7 @@ bitmap_info_t *bitmap_file_read(char *filename, int brief, struct supertype **st
                        /* just look at device... */
                        lseek(fd, 0, 0);
                } else {
-                       st->ss->locate_bitmap(st, fd, NULL);
+                       st->ss->locate_bitmap(st, fd);
                }
                ioctl(fd, BLKFLSBUF, 0); /* make sure we read current data */
                *stp = st;
diff --git a/mdadm.h b/mdadm.h
index ad108d4..0156e37 100644 (file)
--- a/mdadm.h
+++ b/mdadm.h
@@ -341,32 +341,35 @@ extern char *map_dev(int major, int minor, int create);
 
 
 extern struct superswitch {
-       void (*examine_super)(struct supertype *st, void *sbv, char *homehost);
-       void (*brief_examine_super)(struct supertype *st, void *sbv);
-       void (*detail_super)(struct supertype *st, void *sbv, char *homehost);
-       void (*export_super)(struct supertype *st, void *sbv);
-       void (*brief_detail_super)(struct supertype *st, void *sbv);
-       void (*uuid_from_super)(struct supertype *st, int uuid[4], void *sbv);
-       void (*getinfo_super)(struct supertype *st, struct mdinfo *info, void *sbv);
-       int (*match_home)(struct supertype *st, void *sbv, char *homehost);
+       void (*examine_super)(struct supertype *st, char *homehost);
+       void (*brief_examine_super)(struct supertype *st);
+       void (*detail_super)(struct supertype *st, char *homehost);
+       void (*export_super)(struct supertype *st);
+       void (*brief_detail_super)(struct supertype *st);
+       void (*uuid_from_super)(struct supertype *st, int uuid[4]);
+       void (*getinfo_super)(struct supertype *st, struct mdinfo *info);
+       int (*match_home)(struct supertype *st, char *homehost);
        int (*update_super)(struct supertype *st, struct mdinfo *info,
-                           void *sbv, char *update,
+                           char *update,
                            char *devname, int verbose,
                            int uuid_set, char *homehost);
-       int (*init_super)(struct supertype *st, void **sbp, mdu_array_info_t *info, unsigned long long size, char *name, char *homehost, int *uuid);
-       void (*add_to_super)(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo);
-       int (*store_super)(struct supertype *st, int fd, void *sbv);
-       int (*write_init_super)(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname);
+       int (*init_super)(struct supertype *st, mdu_array_info_t *info,
+                         unsigned long long size, char *name,
+                         char *homehost, int *uuid);
+       void (*add_to_super)(struct supertype *st, mdu_disk_info_t *dinfo);
+       int (*store_super)(struct supertype *st, int fd);
+       int (*write_init_super)(struct supertype *st, mdu_disk_info_t *dinfo,
+                               char *devname);
        int (*compare_super)(struct supertype *st, struct supertype *tst);
-       int (*load_super)(struct supertype *st, int fd, void **sbp, char *devname);
+       int (*load_super)(struct supertype *st, int fd, char *devname);
        struct supertype * (*match_metadata_desc)(char *arg);
        __u64 (*avail_size)(struct supertype *st, __u64 size);
-       int (*add_internal_bitmap)(struct supertype *st, void *sbv, int *chunkp,
+       int (*add_internal_bitmap)(struct supertype *st, int *chunkp,
                                   int delay, int write_behind,
                                   unsigned long long size, int may_change, int major);
-       void (*locate_bitmap)(struct supertype *st, int fd, void *sbv);
-       int (*write_bitmap)(struct supertype *st, int fd, void *sbv);
-       void (*free_super)(struct supertype *st, void *super);
+       void (*locate_bitmap)(struct supertype *st, int fd);
+       int (*write_bitmap)(struct supertype *st, int fd);
+       void (*free_super)(struct supertype *st);
        int major;
        int swapuuid; /* true if uuid is bigending rather than hostendian */
 } super0, super1, *superlist[];
@@ -380,6 +383,7 @@ struct supertype {
 
 extern struct supertype *super_by_version(int vers, int minor);
 extern struct supertype *guess_super(int fd);
+extern struct supertype *dup_super(struct supertype *st);
 extern int get_dev_size(int fd, char *dname, unsigned long long *sizep);
 extern void get_one_disk(int mdfd, mdu_array_info_t *ainf,
                         mdu_disk_info_t *disk);
index 873fd95..0cff1ef 100644 (file)
--- a/super0.c
+++ b/super0.c
@@ -85,9 +85,9 @@ void super0_swap_endian(struct mdp_superblock_s *sb)
 
 #ifndef MDASSEMBLE
 
-static void examine_super0(struct supertype *st, void *sbv, char *homehost)
+static void examine_super0(struct supertype *st, char *homehost)
 {
-       mdp_super_t *sb = sbv;
+       mdp_super_t *sb = st->sb;
        time_t atime;
        int d;
        char *c;
@@ -231,9 +231,9 @@ static void examine_super0(struct supertype *st, void *sbv, char *homehost)
        }
 }
 
-static void brief_examine_super0(struct supertype *st, void *sbv)
+static void brief_examine_super0(struct supertype *st)
 {
-       mdp_super_t *sb = sbv;
+       mdp_super_t *sb = st->sb;
        char *c=map_num(pers, sb->level);
        char devname[20];
 
@@ -250,9 +250,9 @@ static void brief_examine_super0(struct supertype *st, void *sbv)
        printf("\n");
 }
 
-static void detail_super0(struct supertype *st, void *sbv, char *homehost)
+static void detail_super0(struct supertype *st, char *homehost)
 {
-       mdp_super_t *sb = sbv;
+       mdp_super_t *sb = st->sb;
        printf("           UUID : ");
        if (sb->minor_version >= 90)
                printf("%08x:%08x:%08x:%08x", sb->set_uuid0, sb->set_uuid1,
@@ -270,9 +270,9 @@ static void detail_super0(struct supertype *st, void *sbv, char *homehost)
        printf("\n         Events : %d.%d\n\n", sb->events_hi, sb->events_lo);
 }
 
-static void brief_detail_super0(struct supertype *st, void *sbv)
+static void brief_detail_super0(struct supertype *st)
 {
-       mdp_super_t *sb = sbv;
+       mdp_super_t *sb = st->sb;
        printf(" UUID=");
        if (sb->minor_version >= 90)
                printf("%08x:%08x:%08x:%08x", sb->set_uuid0, sb->set_uuid1,
@@ -281,9 +281,9 @@ static void brief_detail_super0(struct supertype *st, void *sbv)
                printf("%08x", sb->set_uuid0);
 }
 
-static void export_super0(struct supertype *st, void *sbv)
+static void export_super0(struct supertype *st)
 {
-       mdp_super_t *sb = sbv;
+       mdp_super_t *sb = st->sb;
        printf("MD_UUID=");
        if (sb->minor_version >= 90)
                printf("%08x:%08x:%08x:%08x", sb->set_uuid0, sb->set_uuid1,
@@ -294,9 +294,9 @@ static void export_super0(struct supertype *st, void *sbv)
 }
 #endif
 
-static int match_home0(struct supertype *st, void *sbv, char *homehost)
+static int match_home0(struct supertype *st, char *homehost)
 {
-       mdp_super_t *sb = sbv;
+       mdp_super_t *sb = st->sb;
        char buf[20];
        char *hash = sha1_buffer(homehost,
                                 strlen(homehost),
@@ -305,9 +305,9 @@ static int match_home0(struct supertype *st, void *sbv, char *homehost)
        return (memcmp(&sb->set_uuid2, hash, 8)==0);
 }
 
-static void uuid_from_super0(struct supertype *st, int uuid[4], void * sbv)
+static void uuid_from_super0(struct supertype *st, int uuid[4])
 {
-       mdp_super_t *super = sbv;
+       mdp_super_t *super = st->sb;
        uuid[0] = super->set_uuid0;
        if (super->minor_version >= 90) {
                uuid[1] = super->set_uuid1;
@@ -320,9 +320,9 @@ static void uuid_from_super0(struct supertype *st, int uuid[4], void * sbv)
        }
 }
 
-static void getinfo_super0(struct supertype *st, struct mdinfo *info, void *sbv)
+static void getinfo_super0(struct supertype *st, struct mdinfo *info)
 {
-       mdp_super_t *sb = sbv;
+       mdp_super_t *sb = st->sb;
        int working = 0;
        int i;
 
@@ -348,7 +348,7 @@ static void getinfo_super0(struct supertype *st, struct mdinfo *info, void *sbv)
        info->events = md_event(sb);
        info->data_offset = 0;
 
-       uuid_from_super0(st, info->uuid, sbv);
+       uuid_from_super0(st, info->uuid);
 
        if (sb->minor_version > 90 && (sb->reshape_position+1) != 0) {
                info->reshape_active = 1;
@@ -373,7 +373,7 @@ static void getinfo_super0(struct supertype *st, struct mdinfo *info, void *sbv)
 
 
 static int update_super0(struct supertype *st, struct mdinfo *info,
-                        void *sbv, char *update,
+                        char *update,
                         char *devname, int verbose,
                         int uuid_set, char *homehost)
 {
@@ -381,7 +381,7 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
         * For others, the return value is ignored.
         */
        int rv = 0;
-       mdp_super_t *sb = sbv;
+       mdp_super_t *sb = st->sb;
        if (strcmp(update, "sparc2.2")==0 ) {
                /* 2.2 sparc put the events in the wrong place
                 * So we copy the tail of the superblock
@@ -508,7 +508,7 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
                if (sb->state & (1<<MD_SB_BITMAP_PRESENT)) {
                        struct bitmap_super_s *bm;
                        bm = (struct bitmap_super_s*)(sb+1);
-                       uuid_from_super0(st, (int*)bm->uuid, sbv);
+                       uuid_from_super0(st, (int*)bm->uuid);
                }
        }
        if (strcmp(update, "_reshape_progress")==0)
@@ -527,7 +527,7 @@ static int update_super0(struct supertype *st, struct mdinfo *info,
  */
 
 
-static int init_super0(struct supertype *st, void **sbp, mdu_array_info_t *info,
+static int init_super0(struct supertype *st, mdu_array_info_t *info,
                       unsigned long long size, char *ignored_name, char *homehost,
                       int *uuid)
 {
@@ -538,7 +538,6 @@ static int init_super0(struct supertype *st, void **sbp, mdu_array_info_t *info,
        st->sb = sb;
        if (info->major_version == -1) {
                /* zeroing the superblock */
-               *sbp = sb;
                return 0;
        }
 
@@ -600,14 +599,13 @@ static int init_super0(struct supertype *st, void **sbp, mdu_array_info_t *info,
        sb->layout = info->layout;
        sb->chunk_size = info->chunk_size;
 
-       *sbp = sb;
        return 1;
 }
 
 /* Add a device to the superblock being created */
-static void add_to_super0(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo)
+static void add_to_super0(struct supertype *st, mdu_disk_info_t *dinfo)
 {
-       mdp_super_t *sb = sbv;
+       mdp_super_t *sb = st->sb;
        mdp_disk_t *dk = &sb->disks[dinfo->number];
 
        dk->number = dinfo->number;
@@ -617,11 +615,11 @@ static void add_to_super0(struct supertype *st, void *sbv, mdu_disk_info_t *dinf
        dk->state = dinfo->state;
 }
 
-static int store_super0(struct supertype *st, int fd, void *sbv)
+static int store_super0(struct supertype *st, int fd)
 {
        unsigned long long dsize;
        unsigned long long offset;
-       mdp_super_t *super = sbv;
+       mdp_super_t *super = st->sb;
 
        if (!get_dev_size(fd, NULL, &dsize))
                return 1;
@@ -650,9 +648,10 @@ static int store_super0(struct supertype *st, int fd, void *sbv)
        return 0;
 }
 
-static int write_init_super0(struct supertype *st, void *sbv, mdu_disk_info_t *dinfo, char *devname)
+static int write_init_super0(struct supertype *st,
+                            mdu_disk_info_t *dinfo, char *devname)
 {
-       mdp_super_t *sb = sbv;
+       mdp_super_t *sb = st->sb;
        int fd = open(devname, O_RDWR|O_EXCL);
        int rv;
 
@@ -665,10 +664,10 @@ static int write_init_super0(struct supertype *st, void *sbv, mdu_disk_info_t *d
 
        sb->this_disk = sb->disks[dinfo->number];
        sb->sb_csum = calc_sb0_csum(sb);
-       rv = store_super0(st, fd, sb);
+       rv = store_super0(st, fd);
 
        if (rv == 0 && (sb->state & (1<<MD_SB_BITMAP_PRESENT)))
-               rv = st->ss->write_bitmap(st, fd, sbv);
+               rv = st->ss->write_bitmap(st, fd);
 
        close(fd);
        if (rv)
@@ -698,8 +697,8 @@ static int compare_super0(struct supertype *st, struct supertype *tst)
                return 0;
        }
 
-       uuid_from_super0(NULL, uuid1, first);
-       uuid_from_super0(NULL, uuid2, second);
+       uuid_from_super0(st, uuid1);
+       uuid_from_super0(tst, uuid2);
        if (!same_uuid(uuid1, uuid2, 0))
                return 2;
        if (first->major_version != second->major_version ||
@@ -716,7 +715,9 @@ static int compare_super0(struct supertype *st, struct supertype *tst)
 }
 
 
-static int load_super0(struct supertype *st, int fd, void **sbp, char *devname)
+static void free_super0(struct supertype *st);
+
+static int load_super0(struct supertype *st, int fd, char *devname)
 {
        /* try to read in the superblock
         * Return:
@@ -730,6 +731,8 @@ static int load_super0(struct supertype *st, int fd, void **sbp, char *devname)
        int uuid[4];
        struct bitmap_super_s *bsb;
 
+       free_super0(st);
+
        if (!get_dev_size(fd, devname, &dsize))
                return 1;
 
@@ -783,7 +786,7 @@ static int load_super0(struct supertype *st, int fd, void **sbp, char *devname)
                return 2;
        }
        st->sb = super;
-       *sbp = super;
+
        if (st->ss == NULL) {
                st->ss = &super0;
                st->minor_version = 90;
@@ -801,7 +804,7 @@ static int load_super0(struct supertype *st, int fd, void **sbp, char *devname)
            != sizeof(struct bitmap_super_s))
                goto no_bitmap;
 
-       uuid_from_super0(st, uuid, super);
+       uuid_from_super0(st, uuid);
        bsb = (struct bitmap_super_s *)(super+1);
        if (__le32_to_cpu(bsb->magic) != BITMAP_MAGIC ||
            memcmp(bsb->uuid, uuid, 16) != 0)
@@ -844,7 +847,7 @@ static __u64 avail_size0(struct supertype *st, __u64 devsize)
        return MD_NEW_SIZE_SECTORS(devsize);
 }
 
-static int add_internal_bitmap0(struct supertype *st, void *sbv, int *chunkp,
+static int add_internal_bitmap0(struct supertype *st, int *chunkp,
                                int delay, int write_behind,
                                unsigned long long size, int may_change,
                                int major)
@@ -859,7 +862,7 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int *chunkp,
        unsigned long long max_bits = 60*1024*8;
        unsigned long long min_chunk;
        int chunk = *chunkp;
-       mdp_super_t *sb = sbv;
+       mdp_super_t *sb = st->sb;
        bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + MD_SB_BYTES);
 
 
@@ -879,7 +882,7 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int *chunkp,
        memset(bms, 0, sizeof(*bms));
        bms->magic = __cpu_to_le32(BITMAP_MAGIC);
        bms->version = __cpu_to_le32(major);
-       uuid_from_super0(st, (int*)bms->uuid, sb);
+       uuid_from_super0(st, (int*)bms->uuid);
        bms->chunksize = __cpu_to_le32(chunk);
        bms->daemon_sleep = __cpu_to_le32(delay);
        bms->sync_size = __cpu_to_le64(size);
@@ -889,7 +892,7 @@ static int add_internal_bitmap0(struct supertype *st, void *sbv, int *chunkp,
 }
 
 
-void locate_bitmap0(struct supertype *st, int fd, void *sbv)
+void locate_bitmap0(struct supertype *st, int fd)
 {
        unsigned long long dsize;
        unsigned long long offset;
@@ -909,11 +912,11 @@ void locate_bitmap0(struct supertype *st, int fd, void *sbv)
        lseek64(fd, offset, 0);
 }
 
-int write_bitmap0(struct supertype *st, int fd, void *sbv)
+int write_bitmap0(struct supertype *st, int fd)
 {
        unsigned long long dsize;
        unsigned long long offset;
-       mdp_super_t *sb = sbv;
+       mdp_super_t *sb = st->sb;
 
        int rv = 0;
 
@@ -957,10 +960,11 @@ int write_bitmap0(struct supertype *st, int fd, void *sbv)
        return rv;
 }
 
-static void free_super0(struct supertype *st, void *super)
+static void free_super0(struct supertype *st)
 {
-       if (super)
-               free(super);
+       if (st->sb)
+               free(st->sb);
+       st->sb = NULL;
 }
 
 struct superswitch super0 = {
index 9bf5912..887db10 100644 (file)
--- a/super1.c
+++ b/super1.c
@@ -142,9 +142,9 @@ static unsigned int calc_sb_1_csum(struct mdp_superblock_1 * sb)
 }
 
 #ifndef MDASSEMBLE
-static void examine_super1(struct supertype *st, void *sbv, char *homehost)
+static void examine_super1(struct supertype *st, char *homehost)
 {
-       struct mdp_superblock_1 *sb = sbv;
+       struct mdp_superblock_1 *sb = st->sb;
        time_t atime;
        int d;
        int faulty;
@@ -341,9 +341,9 @@ static void examine_super1(struct supertype *st, void *sbv, char *homehost)
 }
 
 
-static void brief_examine_super1(struct supertype *st, void *sbv)
+static void brief_examine_super1(struct supertype *st)
 {
-       struct mdp_superblock_1 *sb = sbv;
+       struct mdp_superblock_1 *sb = st->sb;
        int i;
        unsigned long long sb_offset;
        char *nm;
@@ -375,9 +375,9 @@ static void brief_examine_super1(struct supertype *st, void *sbv)
        printf("\n");
 }
 
-static void detail_super1(struct supertype *st, void *sbv, char *homehost)
+static void detail_super1(struct supertype *st, char *homehost)
 {
-       struct mdp_superblock_1 *sb = sbv;
+       struct mdp_superblock_1 *sb = st->sb;
        int i;
        int l = homehost ? strlen(homehost) : 0;
 
@@ -394,9 +394,9 @@ static void detail_super1(struct supertype *st, void *sbv, char *homehost)
        printf("\n         Events : %llu\n\n", (unsigned long long)__le64_to_cpu(sb->events));
 }
 
-static void brief_detail_super1(struct supertype *st, void *sbv)
+static void brief_detail_super1(struct supertype *st)
 {
-       struct mdp_superblock_1 *sb = sbv;
+       struct mdp_superblock_1 *sb = st->sb;
        int i;
 
        if (sb->set_name[0])
@@ -408,9 +408,9 @@ static void brief_detail_super1(struct supertype *st, void *sbv)
        }
 }
 
-static void export_super1(struct supertype *st, void *sbv)
+static void export_super1(struct supertype *st)
 {
-       struct mdp_superblock_1 *sb = sbv;
+       struct mdp_superblock_1 *sb = st->sb;
        int i;
        int len = 32;
 
@@ -432,9 +432,9 @@ static void export_super1(struct supertype *st, void *sbv)
 
 #endif
 
-static int match_home1(struct supertype *st, void *sbv, char *homehost)
+static int match_home1(struct supertype *st, char *homehost)
 {
-       struct mdp_superblock_1 *sb = sbv;
+       struct mdp_superblock_1 *sb = st->sb;
        int l = homehost ? strlen(homehost) : 0;
 
        return (l > 0 && l < 32 &&
@@ -442,18 +442,18 @@ static int match_home1(struct supertype *st, void *sbv, char *homehost)
                strncmp(sb->set_name, homehost, l) == 0);
 }
 
-static void uuid_from_super1(struct supertype *st, int uuid[4], void * sbv)
+static void uuid_from_super1(struct supertype *st, int uuid[4])
 {
-       struct mdp_superblock_1 *super = sbv;
+       struct mdp_superblock_1 *super = st->sb;
        char *cuuid = (char*)uuid;
        int i;
        for (i=0; i<16; i++)
                cuuid[i] = super->set_uuid[i];
 }
 
-static void getinfo_super1(struct supertype *st, struct mdinfo *info, void *sbv)
+static void getinfo_super1(struct supertype *st, struct mdinfo *info)
 {
-       struct mdp_superblock_1 *sb = sbv;
+       struct mdp_superblock_1 *sb = st->sb;
        int working = 0;
        int i;
        int role;
@@ -523,7 +523,7 @@ static void getinfo_super1(struct supertype *st, struct mdinfo *info, void *sbv)
 }
 
 static int update_super1(struct supertype *st, struct mdinfo *info,
-                        void *sbv, char *update,
+                        char *update,
                         char *devname, int verbose,
                         int uuid_set, char *homehost)
 {
@@ -531,7 +531,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
         * For others, the return value is ignored.
         */
        int rv = 0;
-       struct mdp_superblock_1 *sb = sbv;
+       struct mdp_superblock_1 *sb = st->sb;
 
        if (strcmp(update, "force-one")==0) {
                /* Not enough devices for a working array,
@@ -603,7 +603,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
 
                if (__le32_to_cpu(sb->feature_map)&MD_FEATURE_BITMAP_OFFSET) {
                        struct bitmap_super_s *bm;
-                       bm = (struct bitmap_super_s*)(sbv+1024);
+                       bm = (struct bitmap_super_s*)(st->sb+1024);
                        memcpy(bm->uuid, sb->set_uuid, 16);
                }
        }
@@ -636,7 +636,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
            __le64_to_cpu(sb->data_offset)) {
                /* set data_size to device size less data_offset */
                struct misc_dev_info *misc = (struct misc_dev_info*)
-                       (sbv + 1024 + sizeof(struct bitmap_super_s));
+                       (st->sb + 1024 + sizeof(struct bitmap_super_s));
                printf("Size was %llu\n", (unsigned long long)
                       __le64_to_cpu(sb->data_size));
                sb->data_size = __cpu_to_le64(
@@ -651,7 +651,7 @@ static int update_super1(struct supertype *st, struct mdinfo *info,
        return rv;
 }
 
-static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info,
+static int init_super1(struct supertype *st, mdu_array_info_t *info,
                       unsigned long long size, char *name, char *homehost, int *uuid)
 {
        struct mdp_superblock_1 *sb = malloc(1024 + sizeof(bitmap_super_t) +
@@ -664,7 +664,6 @@ static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info,
        st->sb = sb;
        if (info->major_version == -1) {
                /* zeroing superblock */
-               *sbp = sb;
                return 0;
        }
 
@@ -731,14 +730,13 @@ static int init_super1(struct supertype *st, void **sbp, mdu_array_info_t *info,
 
        memset(sb->dev_roles, 0xff, 1024 - sizeof(struct mdp_superblock_1));
 
-       *sbp = sb;
        return 1;
 }
 
 /* Add a device to the superblock being created */
-static void add_to_super1(struct supertype *st, void *sbv, mdu_disk_info_t *dk)
+static void add_to_super1(struct supertype *st, mdu_disk_info_t *dk)
 {
-       struct mdp_superblock_1 *sb = sbv;
+       struct mdp_superblock_1 *sb = st->sb;
        __u16 *rp = sb->dev_roles + dk->number;
        if ((dk->state & 6) == 6) /* active, sync */
                *rp = __cpu_to_le16(dk->raid_disk);
@@ -748,11 +746,11 @@ static void add_to_super1(struct supertype *st, void *sbv, mdu_disk_info_t *dk)
                *rp = 0xfffe;
 }
 
-static void locate_bitmap1(struct supertype *st, int fd, void *sbv);
+static void locate_bitmap1(struct supertype *st, int fd);
 
-static int store_super1(struct supertype *st, int fd, void *sbv)
+static int store_super1(struct supertype *st, int fd)
 {
-       struct mdp_superblock_1 *sb = sbv;
+       struct mdp_superblock_1 *sb = st->sb;
        unsigned long long sb_offset;
        int sbsize;
        unsigned long long dsize;
@@ -810,7 +808,7 @@ static int store_super1(struct supertype *st, int fd, void *sbv)
                struct bitmap_super_s *bm = (struct bitmap_super_s*)
                        (((char*)sb)+1024);
                if (__le32_to_cpu(bm->magic) == BITMAP_MAGIC) {
-                       locate_bitmap1(st, fd, sbv);
+                       locate_bitmap1(st, fd);
                        if (write(fd, bm, sizeof(*bm)) != sizeof(*bm))
                            return 5;
                }
@@ -819,7 +817,7 @@ static int store_super1(struct supertype *st, int fd, void *sbv)
        return 0;
 }
 
-static int load_super1(struct supertype *st, int fd, void **sbp, char *devname);
+static int load_super1(struct supertype *st, int fd, char *devname);
 
 static unsigned long choose_bm_space(unsigned long devsize)
 {
@@ -834,11 +832,11 @@ static unsigned long choose_bm_space(unsigned long devsize)
        return 4*2;
 }
 
-static int write_init_super1(struct supertype *st, void *sbv,
+static int write_init_super1(struct supertype *st,
                             mdu_disk_info_t *dinfo, char *devname)
 {
-       struct mdp_superblock_1 *sb = sbv;
-       void *refsbv = NULL;
+       struct mdp_superblock_1 *sb = st->sb;
+       struct supertype refst;
        int fd = open(devname, O_RDWR | O_EXCL);
        int rfd;
        int rv;
@@ -868,8 +866,10 @@ static int write_init_super1(struct supertype *st, void *sbv,
        if (rfd >= 0) close(rfd);
        sb->events = 0;
 
-       if (load_super1(st, fd, &refsbv, NULL)==0) {
-               struct mdp_superblock_1 *refsb = refsbv;
+       refst =*st;
+       refst.sb = NULL;
+       if (load_super1(&refst, fd, NULL)==0) {
+               struct mdp_superblock_1 *refsb = refst.sb;
 
                memcpy(sb->device_uuid, refsb->device_uuid, 16);
                if (memcmp(sb->set_uuid, refsb->set_uuid, 16)==0) {
@@ -938,12 +938,12 @@ static int write_init_super1(struct supertype *st, void *sbv,
 
 
        sb->sb_csum = calc_sb_1_csum(sb);
-       rv = store_super1(st, fd, sb);
+       rv = store_super1(st, fd);
        if (rv)
                fprintf(stderr, Name ": failed to write superblock to %s\n", devname);
 
        if (rv == 0 && (__le32_to_cpu(sb->feature_map) & 1))
-               rv = st->ss->write_bitmap(st, fd, sbv);
+               rv = st->ss->write_bitmap(st, fd);
        close(fd);
        return rv;
 }
@@ -986,7 +986,9 @@ static int compare_super1(struct supertype *st, struct supertype *tst)
        return 0;
 }
 
-static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
+static void free_super1(struct supertype *st);
+
+static int load_super1(struct supertype *st, int fd, char *devname)
 {
        unsigned long long dsize;
        unsigned long long sb_offset;
@@ -995,6 +997,7 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
        struct bitmap_super_s *bsb;
        struct misc_dev_info *misc;
 
+       free_super1(st);
 
        if (st->ss == NULL || st->minor_version == -1) {
                int bestvers = -1;
@@ -1002,16 +1005,17 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
                __u64 bestctime = 0;
                /* guess... choose latest ctime */
                tst.ss = &super1;
+               tst.sb = NULL;
                for (tst.minor_version = 0; tst.minor_version <= 2 ; tst.minor_version++) {
-                       switch(load_super1(&tst, fd, sbp, devname)) {
-                       case 0: super = *sbp;
+                       switch(load_super1(&tst, fd, devname)) {
+                       case 0: super = tst.sb;
                                if (bestvers == -1 ||
                                    bestctime < __le64_to_cpu(super->ctime)) {
                                        bestvers = tst.minor_version;
                                        bestctime = __le64_to_cpu(super->ctime);
                                }
                                free(super);
-                               *sbp = NULL;
+                               tst.sb = NULL;
                                break;
                        case 1: return 1; /*bad device */
                        case 2: break; /* bad, try next */
@@ -1022,7 +1026,7 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
                        tst.minor_version = bestvers;
                        tst.ss = &super1;
                        tst.max_devs = 384;
-                       rv = load_super1(&tst, fd, sbp, devname);
+                       rv = load_super1(&tst, fd, devname);
                        if (rv == 0)
                                *st = tst;
                        return rv;
@@ -1108,7 +1112,6 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
                return 2;
        }
        st->sb = super;
-       *sbp = super;
 
        bsb = (struct bitmap_super_s *)(((char*)super)+1024);
 
@@ -1122,12 +1125,12 @@ static int load_super1(struct supertype *st, int fd, void **sbp, char *devname)
         * valid.  If it doesn't clear the bit.  An --assemble --force
         * should get that written out.
         */
-       locate_bitmap1(st, fd, super);
+       locate_bitmap1(st, fd);
        if (read(fd, ((char*)super)+1024, sizeof(struct bitmap_super_s))
            != sizeof(struct bitmap_super_s))
                goto no_bitmap;
 
-       uuid_from_super1(st, uuid, super);
+       uuid_from_super1(st, uuid);
        if (__le32_to_cpu(bsb->magic) != BITMAP_MAGIC ||
            memcmp(bsb->uuid, uuid, 16) != 0)
                goto no_bitmap;
@@ -1198,7 +1201,7 @@ static __u64 avail_size1(struct supertype *st, __u64 devsize)
 }
 
 static int
-add_internal_bitmap1(struct supertype *st, void *sbv,
+add_internal_bitmap1(struct supertype *st,
                     int *chunkp, int delay, int write_behind,
                     unsigned long long size,
                     int may_change, int major)
@@ -1220,7 +1223,7 @@ add_internal_bitmap1(struct supertype *st, void *sbv,
        long offset;
        int chunk = *chunkp;
        int room = 0;
-       struct mdp_superblock_1 *sb = sbv;
+       struct mdp_superblock_1 *sb = st->sb;
        bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb) + 1024);
 
        switch(st->minor_version) {
@@ -1305,7 +1308,7 @@ add_internal_bitmap1(struct supertype *st, void *sbv,
        memset(bms, 0, sizeof(*bms));
        bms->magic = __cpu_to_le32(BITMAP_MAGIC);
        bms->version = __cpu_to_le32(major);
-       uuid_from_super1(st, (int*)bms->uuid, sb);
+       uuid_from_super1(st, (int*)bms->uuid);
        bms->chunksize = __cpu_to_le32(chunk);
        bms->daemon_sleep = __cpu_to_le32(delay);
        bms->sync_size = __cpu_to_le64(size);
@@ -1316,18 +1319,18 @@ add_internal_bitmap1(struct supertype *st, void *sbv,
 }
 
 
-static void locate_bitmap1(struct supertype *st, int fd, void *sbv)
+static void locate_bitmap1(struct supertype *st, int fd)
 {
        unsigned long long offset;
        struct mdp_superblock_1 *sb;
        int mustfree = 0;
 
-       if (!sbv) {
-               if (st->ss->load_super(st, fd, &sbv, NULL))
+       if (!st->sb) {
+               if (st->ss->load_super(st, fd, NULL))
                        return; /* no error I hope... */
                mustfree = 1;
        }
-       sb = sbv;
+       sb = st->sb;
 
        offset = __le64_to_cpu(sb->super_offset);
        offset += (int32_t) __le32_to_cpu(sb->bitmap_offset);
@@ -1336,16 +1339,16 @@ static void locate_bitmap1(struct supertype *st, int fd, void *sbv)
        lseek64(fd, offset<<9, 0);
 }
 
-static int write_bitmap1(struct supertype *st, int fd, void *sbv)
+static int write_bitmap1(struct supertype *st, int fd)
 {
-       struct mdp_superblock_1 *sb = sbv;
+       struct mdp_superblock_1 *sb = st->sb;
        bitmap_super_t *bms = (bitmap_super_t*)(((char*)sb)+1024);
        int rv = 0;
 
        int towrite, n;
        char buf[4096];
 
-       locate_bitmap1(st, fd, sbv);
+       locate_bitmap1(st, fd);
 
        if (write(fd, ((char*)sb)+1024, sizeof(bitmap_super_t)) !=
            sizeof(bitmap_super_t))
@@ -1370,10 +1373,11 @@ static int write_bitmap1(struct supertype *st, int fd, void *sbv)
        return rv;
 }
 
-static void free_super1(struct supertype *st, void *super)
+static void free_super1(struct supertype *st)
 {
-       if (super)
-               free(super);
+       if (st->sb)
+               free(st->sb);
+       st->sb = NULL;
 }
 
 struct superswitch super1 = {
diff --git a/util.c b/util.c
index 0662c4e..811627e 100644 (file)
--- a/util.c
+++ b/util.c
@@ -322,19 +322,18 @@ int check_reiser(int fd, char *name)
 
 int check_raid(int fd, char *name)
 {
-       void *super;
        struct mdinfo info;
        time_t crtime;
        char *level;
        struct supertype *st = guess_super(fd);
 
        if (!st) return 0;
-       st->ss->load_super(st, fd, &super, name);
+       st->ss->load_super(st, fd, name);
        /* Looks like a raid array .. */
        fprintf(stderr, Name ": %s appears to be part of a raid array:\n",
                name);
-       st->ss->getinfo_super(st, &info, super);
-       st->ss->free_super(st, super);
+       st->ss->getinfo_super(st, &info);
+       st->ss->free_super(st);
        crtime = info.array.ctime;
        level = map_num(pers, info.array.level);
        if (!level) level = "-unknown-";
@@ -738,9 +737,17 @@ struct supertype *super_by_version(int vers, int minor)
                st->max_devs = 384;
        }
        st->minor_version = minor;
+       st->sb = NULL;
        return st;
 }
 
+struct supertype *dup_super(struct supertype *st)
+{
+       if (!st)
+               return st;
+       return super_by_version(st->ss->major, st->minor_version);
+}
+
 struct supertype *guess_super(int fd)
 {
        /* try each load_super to find the best match,
@@ -750,8 +757,6 @@ struct supertype *guess_super(int fd)
        struct supertype *st;
        unsigned long besttime = 0;
        int bestsuper = -1;
-
-       void *sbp = NULL;
        int i;
 
        st = malloc(sizeof(*st));
@@ -760,24 +765,24 @@ struct supertype *guess_super(int fd)
                int rv;
                ss = superlist[i];
                st->ss = NULL;
-               rv = ss->load_super(st, fd, &sbp, NULL);
+               rv = ss->load_super(st, fd, NULL);
                if (rv == 0) {
                        struct mdinfo info;
-                       st->ss->getinfo_super(st, &info, sbp);
+                       st->ss->getinfo_super(st, &info);
                        if (bestsuper == -1 ||
                            besttime < info.array.ctime) {
                                bestsuper = i;
                                besttime = info.array.ctime;
                        }
-                       free(sbp);
+                       ss->free_super(st);
                }
        }
        if (bestsuper != -1) {
                int rv;
                st->ss = NULL;
-               rv = superlist[bestsuper]->load_super(st, fd, &sbp, NULL);
+               rv = superlist[bestsuper]->load_super(st, fd, NULL);
                if (rv == 0) {
-                       free(sbp);
+                       ss->free_super(st);
                        return st;
                }
        }