From 3da92f272d017b1817b13f37f41c1ed4d6117291 Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Fri, 14 Dec 2007 20:14:33 +1100 Subject: [PATCH] Drop the superblock arg from all metadata methods. It is now in the 'supertype' --- Assemble.c | 117 +++++++++++++++++++++++++----------------------- Create.c | 16 +++---- Detail.c | 34 +++++++------- Examine.c | 23 +++++----- Grow.c | 61 ++++++++++++------------- Incremental.c | 53 +++++++++------------- Kill.c | 9 ++-- Manage.c | 54 +++++++++++++---------- Query.c | 5 +-- bitmap.c | 2 +- mdadm.h | 40 +++++++++-------- super0.c | 94 ++++++++++++++++++++------------------- super1.c | 120 ++++++++++++++++++++++++++------------------------ util.c | 27 +++++++----- 14 files changed, 330 insertions(+), 325 deletions(-) diff --git a/Assemble.c b/Assemble.c index 98e49764..f78ca067 100644 --- a/Assemble.c +++ b/Assemble.c @@ -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; iss->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 && iss->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; iss->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); diff --git a/Create.c b/Create.c index 77aaf8e6..6cf509aa 100644 --- 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) { diff --git a/Detail.c b/Detail.c index cebba6ee..2bde9fab 100644 --- 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<sb) && + (disk.state & (1<=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"); diff --git a/Examine.c b/Examine.c index 806c5524..276e0fa9 100644 --- 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 0aa7287b..e07e2c06 100644 --- 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= 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); iss->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; jarray.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; jarray.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! */ diff --git a/Incremental.c b/Incremental.c index fdd8fb40..d3ab72f7 100644 --- a/Incremental.c +++ b/Incremental.c @@ -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<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 d7e52f50..0a2763ea 100644 --- 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); diff --git a/Manage.c b/Manage.c index 5219e6eb..09d397b7 100644 --- 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; jmax_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 19b2ce5e..08029642 100644 --- 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; diff --git a/bitmap.c b/bitmap.c index db2342bd..fdf8884d 100644 --- 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 ad108d40..0156e370 100644 --- 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); diff --git a/super0.c b/super0.c index 873fd95c..0cff1ef0 100644 --- 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<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<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 = { diff --git a/super1.c b/super1.c index 9bf5912a..887db10c 100644 --- 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 0662c4e2..811627e8 100644 --- 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; } } -- 2.39.2