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:
parent
3da92f272d
commit
1686dc25ec
2
Detail.c
2
Detail.c
|
@ -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
8
Grow.c
|
@ -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.
|
||||
|
|
6
Manage.c
6
Manage.c
|
@ -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);
|
||||
|
|
2
mdadm.h
2
mdadm.h
|
@ -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
56
util.c
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue