Find super from fd on an array.

We used to use the major/minor numbers, but that isn't sufficient
any more, so pass the fd, and possibly check 'text' version.
This commit is contained in:
Neil Brown 2007-12-14 20:14:38 +11:00
parent 3da92f272d
commit 1686dc25ec
5 changed files with 53 additions and 21 deletions

View File

@ -88,7 +88,7 @@ int Detail(char *dev, int brief, int export, int test, char *homehost)
close(fd);
return rv;
}
st = super_by_version(array.major_version, array.minor_version);
st = super_by_fd(fd);
if (fstat(fd, &stb) != 0 && !S_ISBLK(stb.st_mode))
stb.st_rdev = 0;

8
Grow.c
View File

@ -58,7 +58,7 @@ int Grow_Add_device(char *devname, int fd, char *newdev)
return 1;
}
st = super_by_version(info.array.major_version, info.array.minor_version);
st = super_by_fd(fd);
if (!st) {
fprintf(stderr, Name ": cannot handle arrays with superblock version %d\n", info.array.major_version);
return 1;
@ -277,7 +277,7 @@ int Grow_addbitmap(char *devname, int fd, char *file, int chunk, int delay, int
bitmapsize = bitmapsize * array.raid_disks / ncopies;
}
st = super_by_version(array.major_version, array.minor_version);
st = super_by_fd(fd);
if (!st) {
fprintf(stderr, Name ": Cannot understand version %d.%d\n",
array.major_version, array.minor_version);
@ -519,8 +519,8 @@ int Grow_reshape(char *devname, int fd, int quiet, char *backup_file,
case 4:
case 5:
case 6:
st = super_by_version(array.major_version,
array.minor_version);
st = super_by_fd(fd);
/* size can be changed independently.
* layout/chunksize/raid_disks/level can be changed
* though the kernel may not support it all.

View File

@ -202,8 +202,7 @@ int Manage_subdevs(char *devname, int fd,
return 1;
}
tst = super_by_version(array.major_version,
array.minor_version);
tst = super_by_fd(fd);
if (!tst) {
fprintf(stderr, Name ": unsupport array - version %d.%d\n",
array.major_version, array.minor_version);
@ -308,8 +307,7 @@ int Manage_subdevs(char *devname, int fd,
}
remove_partitions(tfd);
st = super_by_version(array.major_version,
array.minor_version);
st = dup_super(tst);
if (array.not_persistent==0)
st->ss->load_super(st, tfd, NULL);

View File

@ -381,7 +381,7 @@ struct supertype {
void *sb;
};
extern struct supertype *super_by_version(int vers, int minor);
extern struct supertype *super_by_fd(int fd);
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);

56
util.c
View File

@ -723,29 +723,63 @@ int dev_open(char *dev, int flags)
struct superswitch *superlist[] = { &super0, &super1, NULL };
struct supertype *super_by_version(int vers, int minor)
struct supertype *super_by_fd(int fd)
{
struct supertype *st = malloc(sizeof(*st));
if (!st) return st;
if (vers == 0) {
st->ss = &super0;
st->max_devs = MD_SB_DISKS;
mdu_array_info_t array;
int vers;
int minor;
struct supertype *st = NULL;
struct sysarray *sra;
char *verstr = NULL;
char version[20];
int i;
sra = sysfs_read(fd, 0, GET_VERSION);
if (sra) {
vers = sra->major_version;
minor = sra->minor_version;
} else {
if (ioctl(fd, GET_ARRAY_INFO, &array))
array.major_version = array.minor_version = 0;
vers = array.major_version;
minor = array.minor_version;
}
if (vers == 1) {
st->ss = &super1;
st->max_devs = 384;
if (vers != -1) {
sprintf(version, "%d.%d", vers, minor);
verstr = version;
}
st->minor_version = minor;
for (i = 0; st == NULL && superlist[i] ; i++)
st = superlist[i]->match_metadata_desc(verstr);
if (sra)
sysfs_free(sra);
st->sb = NULL;
return st;
}
struct supertype *dup_super(struct supertype *st)
{
struct supertype *stnew = NULL;
char *verstr = NULL;
char version[20];
int i;
if (!st)
return st;
return super_by_version(st->ss->major, st->minor_version);
if (st->minor_version == -1)
sprintf(version, "%d", st->ss->major);
else
sprintf(version, "%d.%d", st->ss->major, st->minor_version);
verstr = version;
for (i = 0; stnew == NULL && superlist[i] ; i++)
stnew = superlist[i]->match_metadata_desc(verstr);
stnew->sb = NULL;
return stnew;
}
struct supertype *guess_super(int fd)