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;
char *devname = tmpdev->devname;
int dfd;
struct stat stb;
- struct supertype *tst = st;
+ struct supertype *tst = dup_super(st);
if (tmpdev->used > 1) continue;
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);
* 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) {
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 */
}
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) {
*/
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))
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);
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;
int dfd;
/* prepare useful information in info structures */
struct stat stb2;
+ struct supertype *tst;
fstat(mdfd, &stb2);
if (strcmp(update, "uuid")==0 &&
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;
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)
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);
}
best[i] = devcnt;
}
devcnt++;
-
- if (super)
- st->ss->free_super(st, super);
- super = NULL;
}
if (update && strcmp(update, "byteorder")==0)
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.
* 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++) {
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);
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);
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
* 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;
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);
}
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;
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)
!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;
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);
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;
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) {
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");
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,
}
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;
}
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) {
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;
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);
}
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;
}
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,
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");
}
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");
* 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;
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);
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) {
}
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++;
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) {
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");
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");
*/
struct mdinfo info;
- void *super = NULL;
struct stat stb;
int nfd, fd2;
int d, nd;
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;
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);
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;
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;
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);
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++) {
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);
int d, i, spares;
int nrdisks;
int err;
- void *super = NULL;
struct sysarray *sra;
struct sysdev *sd;
}
/* 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;
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);
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];
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)
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");
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! */
* 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];
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 */
/* 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");
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 ||
}
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);
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) {
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;
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 ||
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;
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) {
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;
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;
}
int ok;
struct supertype *st;
char *path;
- void *super;
struct mdinfo info;
sprintf(dn, "%d:%d", sd->major, sd->minor);
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
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;
}
}
* Definitely not safe.
*/
- void *super;
int fd, rv = 0;
struct supertype *st;
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);
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];
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];
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);
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;
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);
/* 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;
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;
}
* 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 :-(
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;
* 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;
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.
*/
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))
int superror, superrno;
struct mdinfo info;
mdu_array_info_t array;
- void *super;
struct supertype *st = NULL;
unsigned long long larray_size;
}
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;
/* 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;
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[];
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);
#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;
}
}
-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];
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,
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,
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,
}
#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),
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;
}
}
-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;
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;
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)
{
* 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
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)
*/
-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)
{
st->sb = sb;
if (info->major_version == -1) {
/* zeroing the superblock */
- *sbp = sb;
return 0;
}
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;
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;
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;
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)
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 ||
}
-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:
int uuid[4];
struct bitmap_super_s *bsb;
+ free_super0(st);
+
if (!get_dev_size(fd, devname, &dsize))
return 1;
return 2;
}
st->sb = super;
- *sbp = super;
+
if (st->ss == NULL) {
st->ss = &super0;
st->minor_version = 90;
!= 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)
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)
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);
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);
}
-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;
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;
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 = {
}
#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;
}
-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;
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;
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])
}
}
-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;
#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 &&
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;
}
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)
{
* 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,
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);
}
}
__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(
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) +
st->sb = sb;
if (info->major_version == -1) {
/* zeroing superblock */
- *sbp = sb;
return 0;
}
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);
*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;
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;
}
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)
{
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;
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) {
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;
}
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;
struct bitmap_super_s *bsb;
struct misc_dev_info *misc;
+ free_super1(st);
if (st->ss == NULL || st->minor_version == -1) {
int bestvers = -1;
__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 */
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;
return 2;
}
st->sb = super;
- *sbp = super;
bsb = (struct bitmap_super_s *)(((char*)super)+1024);
* 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;
}
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)
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) {
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);
}
-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);
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))
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 = {
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-";
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,
struct supertype *st;
unsigned long besttime = 0;
int bestsuper = -1;
-
- void *sbp = NULL;
int i;
st = malloc(sizeof(*st));
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;
}
}