imsm: remove extra superswitches
Following the lead of 75ede16d. This incidentally fixes creation of a second array by gating call to getinfo_super_imsm_volume with a valid ->current_vol. Signed-off-by: Dan Williams <dan.j.williams@intel.com>
This commit is contained in:
parent
99e2926423
commit
bf5a934aff
521
super-intel.c
521
super-intel.c
|
@ -124,8 +124,6 @@ static unsigned int mpb_sectors(struct imsm_super *mpb)
|
|||
return sector_count(__le32_to_cpu(mpb->mpb_size));
|
||||
}
|
||||
|
||||
static struct superswitch super_imsm_volume;
|
||||
|
||||
/* internal representation of IMSM metadata */
|
||||
struct intel_super {
|
||||
union {
|
||||
|
@ -134,7 +132,7 @@ struct intel_super {
|
|||
};
|
||||
int updates_pending; /* count of pending updates for mdmon */
|
||||
int creating_imsm; /* flag to indicate container creation */
|
||||
int creating_dev; /* index of raid device undergoing creation */
|
||||
int current_vol; /* index of raid device undergoing creation */
|
||||
struct dl {
|
||||
struct dl *next;
|
||||
int index;
|
||||
|
@ -167,25 +165,6 @@ static struct supertype *match_metadata_desc_imsm(char *arg)
|
|||
return st;
|
||||
}
|
||||
|
||||
static struct supertype *match_metadata_desc_imsm_volume(char *arg)
|
||||
{
|
||||
struct supertype *st;
|
||||
|
||||
if (strcmp(arg, "imsm/volume") != 0 &&
|
||||
strcmp(arg, "raid") != 0 &&
|
||||
strcmp(arg, "default") != 0
|
||||
)
|
||||
return NULL;
|
||||
|
||||
st = malloc(sizeof(*st));
|
||||
memset(st, 0, sizeof(*st));
|
||||
st->ss = &super_imsm_volume;
|
||||
st->max_devs = IMSM_MAX_DEVICES;
|
||||
st->minor_version = 0;
|
||||
st->sb = NULL;
|
||||
return st;
|
||||
}
|
||||
|
||||
static __u8 *get_imsm_version(struct imsm_super *mpb)
|
||||
{
|
||||
return &mpb->sig[MPB_SIG_LEN];
|
||||
|
@ -494,53 +473,14 @@ static int imsm_level_to_layout(int level)
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info)
|
||||
{
|
||||
struct intel_super *super = st->sb;
|
||||
struct imsm_super *mpb = super->mpb;
|
||||
struct imsm_disk *disk;
|
||||
int sect = mpb_sectors(mpb);
|
||||
__u32 s;
|
||||
|
||||
info->array.raid_disks = mpb->num_disks;
|
||||
info->array.level = LEVEL_CONTAINER;
|
||||
info->array.layout = 0;
|
||||
info->array.md_minor = -1;
|
||||
info->array.ctime = 0; /* N/A for imsm */
|
||||
info->array.utime = 0;
|
||||
info->array.chunk_size = 0;
|
||||
|
||||
info->disk.major = 0;
|
||||
info->disk.minor = 0;
|
||||
info->disk.raid_disk = -1;
|
||||
info->reshape_active = 0;
|
||||
strcpy(info->text_version, "imsm");
|
||||
info->disk.number = -1;
|
||||
info->disk.state = 0;
|
||||
|
||||
info->data_offset = __le32_to_cpu(get_imsm_disk(super->mpb,
|
||||
super->disks->index)
|
||||
->total_blocks) - (2 + sect - 1);
|
||||
info->component_size = sect;
|
||||
|
||||
if (super->disks) {
|
||||
info->disk.number = super->disks->index;
|
||||
info->disk.raid_disk = super->disks->index;
|
||||
disk = get_imsm_disk(mpb, super->disks->index);
|
||||
s = __le32_to_cpu(disk->status);
|
||||
info->disk.state = s & CONFIGURED_DISK ? (1 << MD_DISK_ACTIVE) : 0;
|
||||
info->disk.state |= s & FAILED_DISK ? (1 << MD_DISK_FAULTY) : 0;
|
||||
info->disk.state |= s & USABLE_DISK ? (1 << MD_DISK_SYNC) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info)
|
||||
{
|
||||
struct intel_super *super = st->sb;
|
||||
struct imsm_super *mpb = super->mpb;
|
||||
struct imsm_dev *dev = get_imsm_dev(mpb, info->container_member);
|
||||
struct imsm_dev *dev = get_imsm_dev(mpb, super->current_vol);
|
||||
struct imsm_map *map = &dev->vol.map[0];
|
||||
|
||||
info->container_member = super->current_vol;
|
||||
info->array.raid_disks = map->num_members;
|
||||
info->array.level = get_imsm_raid_level(map);
|
||||
info->array.layout = imsm_level_to_layout(info->array.level);
|
||||
|
@ -560,6 +500,48 @@ static void getinfo_super_imsm_volume(struct supertype *st, struct mdinfo *info)
|
|||
info->container_member);
|
||||
}
|
||||
|
||||
|
||||
static void getinfo_super_imsm(struct supertype *st, struct mdinfo *info)
|
||||
{
|
||||
struct intel_super *super = st->sb;
|
||||
struct imsm_super *mpb = super->mpb;
|
||||
struct imsm_disk *disk;
|
||||
__u32 s;
|
||||
|
||||
if (super->current_vol >= 0) {
|
||||
getinfo_super_imsm_volume(st, info);
|
||||
return;
|
||||
}
|
||||
info->array.raid_disks = mpb->num_disks;
|
||||
info->array.level = LEVEL_CONTAINER;
|
||||
info->array.layout = 0;
|
||||
info->array.md_minor = -1;
|
||||
info->array.ctime = 0; /* N/A for imsm */
|
||||
info->array.utime = 0;
|
||||
info->array.chunk_size = 0;
|
||||
|
||||
info->disk.major = 0;
|
||||
info->disk.minor = 0;
|
||||
info->disk.raid_disk = -1;
|
||||
info->reshape_active = 0;
|
||||
strcpy(info->text_version, "imsm");
|
||||
info->disk.number = -1;
|
||||
info->disk.state = 0;
|
||||
|
||||
if (super->disks) {
|
||||
disk = get_imsm_disk(mpb, super->disks->index);
|
||||
info->disk.number = super->disks->index;
|
||||
info->disk.raid_disk = super->disks->index;
|
||||
info->data_offset = __le32_to_cpu(disk->total_blocks) -
|
||||
(MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS);
|
||||
info->component_size = MPB_SECTOR_CNT + IMSM_RESERVED_SECTORS;
|
||||
s = __le32_to_cpu(disk->status);
|
||||
info->disk.state = s & CONFIGURED_DISK ? (1 << MD_DISK_ACTIVE) : 0;
|
||||
info->disk.state |= s & FAILED_DISK ? (1 << MD_DISK_FAULTY) : 0;
|
||||
info->disk.state |= s & USABLE_DISK ? (1 << MD_DISK_SYNC) : 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int update_super_imsm(struct supertype *st, struct mdinfo *info,
|
||||
char *update, char *devname, int verbose,
|
||||
int uuid_set, char *homehost)
|
||||
|
@ -765,7 +747,6 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
|
|||
struct imsm_super *anchor;
|
||||
__u32 check_sum;
|
||||
|
||||
memset(super, 0, sizeof(*super));
|
||||
get_dev_size(fd, NULL, &dsize);
|
||||
|
||||
if (lseek64(fd, dsize - (512 * 2), SEEK_SET) < 0) {
|
||||
|
@ -844,8 +825,6 @@ static int load_imsm_mpb(int fd, struct intel_super *super, char *devname)
|
|||
return load_imsm_disk(fd, super, devname, 0);
|
||||
}
|
||||
|
||||
struct superswitch super_imsm_container;
|
||||
|
||||
static void free_imsm_disks(struct intel_super *super)
|
||||
{
|
||||
while (super->disks) {
|
||||
|
@ -887,7 +866,7 @@ static struct intel_super *alloc_super(int creating_imsm)
|
|||
if (super) {
|
||||
memset(super, 0, sizeof(*super));
|
||||
super->creating_imsm = creating_imsm;
|
||||
super->creating_dev = -1;
|
||||
super->current_vol = -1;
|
||||
}
|
||||
|
||||
return super;
|
||||
|
@ -979,12 +958,15 @@ static int load_super_imsm_all(struct supertype *st, int fd, void **sbp,
|
|||
}
|
||||
|
||||
if (st->subarray[0]) {
|
||||
/* FIXME */
|
||||
if (atoi(st->subarray) <= super->mpb->num_raid_devs)
|
||||
super->current_vol = atoi(st->subarray);
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
*sbp = super;
|
||||
if (st->ss == NULL) {
|
||||
st->ss = &super_imsm_container;
|
||||
st->ss = &super_imsm;
|
||||
st->minor_version = 0;
|
||||
st->max_devs = IMSM_MAX_DEVICES;
|
||||
st->container_dev = fd2devnum(fd);
|
||||
|
@ -1035,51 +1017,6 @@ static int load_super_imsm(struct supertype *st, int fd, char *devname)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int init_zero_imsm(struct supertype *st, mdu_array_info_t *info,
|
||||
unsigned long long size, char *name,
|
||||
char *homehost, int *uuid)
|
||||
{
|
||||
st->sb = NULL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int init_super_imsm(struct supertype *st, mdu_array_info_t *info,
|
||||
unsigned long long size, char *name,
|
||||
char *homehost, int *uuid)
|
||||
{
|
||||
/* This is primarily called by Create when creating a new array.
|
||||
* We will then get add_to_super called for each component, and then
|
||||
* write_init_super called to write it out to each device.
|
||||
* For IMSM, Create can create on fresh devices or on a pre-existing
|
||||
* array.
|
||||
* To create on a pre-existing array a different method will be called.
|
||||
* This one is just for fresh drives.
|
||||
*/
|
||||
struct intel_super *super;
|
||||
struct imsm_super *mpb;
|
||||
size_t mpb_size;
|
||||
|
||||
super = alloc_super(1);
|
||||
if (!super)
|
||||
return 0;
|
||||
mpb_size = disks_to_mpb_size(info->nr_disks);
|
||||
posix_memalign((void**)&mpb, 512, mpb_size);
|
||||
if (!mpb) {
|
||||
free(super);
|
||||
return 0;
|
||||
}
|
||||
memset(mpb, 0, mpb_size);
|
||||
|
||||
memcpy(mpb->sig, MPB_SIGNATURE, strlen(MPB_SIGNATURE));
|
||||
memcpy(mpb->sig + strlen(MPB_SIGNATURE), MPB_VERSION_RAID5,
|
||||
strlen(MPB_VERSION_RAID5));
|
||||
mpb->mpb_size = mpb_size;
|
||||
|
||||
super->mpb = mpb;
|
||||
st->sb = super;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
||||
unsigned long long size, char *name,
|
||||
char *homehost, int *uuid)
|
||||
|
@ -1104,7 +1041,8 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
|||
return 0;
|
||||
}
|
||||
|
||||
super->creating_dev = idx;
|
||||
super->current_vol = idx;
|
||||
sprintf(st->subarray, "%d", idx);
|
||||
mpb->num_raid_devs++;
|
||||
dev = get_imsm_dev(mpb, idx);
|
||||
strncpy((char *) dev->volume, name, MAX_RAID_SERIAL_LEN);
|
||||
|
@ -1147,6 +1085,78 @@ static int init_super_imsm_volume(struct supertype *st, mdu_array_info_t *info,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int init_super_imsm(struct supertype *st, mdu_array_info_t *info,
|
||||
unsigned long long size, char *name,
|
||||
char *homehost, int *uuid)
|
||||
{
|
||||
/* This is primarily called by Create when creating a new array.
|
||||
* We will then get add_to_super called for each component, and then
|
||||
* write_init_super called to write it out to each device.
|
||||
* For IMSM, Create can create on fresh devices or on a pre-existing
|
||||
* array.
|
||||
* To create on a pre-existing array a different method will be called.
|
||||
* This one is just for fresh drives.
|
||||
*/
|
||||
struct intel_super *super;
|
||||
struct imsm_super *mpb;
|
||||
size_t mpb_size;
|
||||
|
||||
if (!info) {
|
||||
st->sb = NULL;
|
||||
return 0;
|
||||
}
|
||||
if (st->sb)
|
||||
return init_super_imsm_volume(st, info, size, name, homehost,
|
||||
uuid);
|
||||
|
||||
super = alloc_super(1);
|
||||
if (!super)
|
||||
return 0;
|
||||
mpb_size = disks_to_mpb_size(info->nr_disks);
|
||||
if (posix_memalign((void**)&mpb, 512, mpb_size) != 0) {
|
||||
free(super);
|
||||
return 0;
|
||||
}
|
||||
memset(mpb, 0, mpb_size);
|
||||
|
||||
memcpy(mpb->sig, MPB_SIGNATURE, strlen(MPB_SIGNATURE));
|
||||
memcpy(mpb->sig + strlen(MPB_SIGNATURE), MPB_VERSION_RAID5,
|
||||
strlen(MPB_VERSION_RAID5));
|
||||
mpb->mpb_size = mpb_size;
|
||||
|
||||
super->mpb = mpb;
|
||||
st->sb = super;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
|
||||
int fd, char *devname)
|
||||
{
|
||||
struct intel_super *super = st->sb;
|
||||
struct imsm_super *mpb = super->mpb;
|
||||
struct dl *dl;
|
||||
struct imsm_dev *dev;
|
||||
struct imsm_map *map;
|
||||
struct imsm_disk *disk;
|
||||
__u32 status;
|
||||
|
||||
dev = get_imsm_dev(mpb, super->current_vol);
|
||||
map = &dev->vol.map[0];
|
||||
|
||||
for (dl = super->disks; dl ; dl = dl->next)
|
||||
if (dl->major == dk->major &&
|
||||
dl->minor == dk->minor)
|
||||
break;
|
||||
if (!dl || ! (dk->state & (1<<MD_DISK_SYNC)))
|
||||
return;
|
||||
|
||||
map->disk_ord_tbl[dk->number] = __cpu_to_le32(dl->index);
|
||||
|
||||
disk = get_imsm_disk(mpb, dl->index);
|
||||
status = CONFIGURED_DISK | USABLE_DISK;
|
||||
disk->status = __cpu_to_le32(status);
|
||||
}
|
||||
|
||||
static void add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
|
||||
int fd, char *devname)
|
||||
{
|
||||
|
@ -1159,6 +1169,11 @@ static void add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
|
|||
int rv;
|
||||
struct stat stb;
|
||||
|
||||
if (super->current_vol >= 0) {
|
||||
add_to_super_imsm_volume(st, dk, fd, devname);
|
||||
return;
|
||||
}
|
||||
|
||||
fstat(fd, &stb);
|
||||
dd = malloc(sizeof(*dd));
|
||||
if (!dd) {
|
||||
|
@ -1203,39 +1218,6 @@ static void add_to_super_imsm(struct supertype *st, mdu_disk_info_t *dk,
|
|||
super->disks = dd;
|
||||
}
|
||||
|
||||
static void add_to_super_imsm_volume(struct supertype *st, mdu_disk_info_t *dk,
|
||||
int fd, char *devname)
|
||||
{
|
||||
struct intel_super *super = st->sb;
|
||||
struct imsm_super *mpb = super->mpb;
|
||||
struct dl *dl;
|
||||
struct imsm_dev *dev;
|
||||
struct imsm_map *map;
|
||||
struct imsm_disk *disk;
|
||||
__u32 status;
|
||||
|
||||
if (super->creating_dev == -1) {
|
||||
fprintf(stderr, Name ": no active raid device\n");
|
||||
abort();
|
||||
}
|
||||
|
||||
dev = get_imsm_dev(mpb, super->creating_dev);
|
||||
map = &dev->vol.map[0];
|
||||
|
||||
for (dl = super->disks; dl ; dl = dl->next)
|
||||
if (dl->major == dk->major &&
|
||||
dl->minor == dk->minor)
|
||||
break;
|
||||
if (!dl || ! (dk->state & (1<<MD_DISK_SYNC)))
|
||||
return;
|
||||
|
||||
map->disk_ord_tbl[dk->number] = __cpu_to_le32(dl->index);
|
||||
|
||||
disk = get_imsm_disk(mpb, dl->index);
|
||||
status = CONFIGURED_DISK | USABLE_DISK;
|
||||
disk->status = __cpu_to_le32(status);
|
||||
}
|
||||
|
||||
static int store_imsm_mpb(int fd, struct intel_super *super);
|
||||
|
||||
static int write_super_imsm(struct intel_super *super, int doclose)
|
||||
|
@ -1292,113 +1274,6 @@ static int store_zero_imsm(struct supertype *st, int fd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int validate_geometry_imsm(struct supertype *st, int level, int layout,
|
||||
int raiddisks, int chunk, unsigned long long size,
|
||||
char *dev, unsigned long long *freesize,
|
||||
int verbose)
|
||||
{
|
||||
int fd, cfd;
|
||||
struct mdinfo *sra;
|
||||
|
||||
/* if given unused devices create a container
|
||||
* if given given devices in a container create a member volume
|
||||
*/
|
||||
if (level == LEVEL_CONTAINER) {
|
||||
st->ss = &super_imsm_container;
|
||||
if (dev) {
|
||||
/* validate the container, dev == NULL */
|
||||
int rv = st->ss->validate_geometry(st, level, layout,
|
||||
raiddisks, chunk,
|
||||
size,
|
||||
NULL, freesize,
|
||||
verbose);
|
||||
if (rv)
|
||||
return rv;
|
||||
}
|
||||
return st->ss->validate_geometry(st, level, layout, raiddisks,
|
||||
chunk, size, dev, freesize,
|
||||
verbose);
|
||||
}
|
||||
|
||||
if (st->sb) {
|
||||
/* creating in a given container */
|
||||
st->ss = &super_imsm_volume;
|
||||
if (dev) {
|
||||
int rv = st->ss->validate_geometry(st, level, layout,
|
||||
raiddisks, chunk,
|
||||
size,
|
||||
NULL, freesize,
|
||||
verbose);
|
||||
if (rv)
|
||||
return rv;
|
||||
}
|
||||
return st->ss->validate_geometry(st, level, layout, raiddisks,
|
||||
chunk, size, dev, freesize,
|
||||
verbose);
|
||||
}
|
||||
|
||||
/* limit creation to the following levels */
|
||||
if (!dev)
|
||||
switch (level) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 10:
|
||||
case 5:
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* This device needs to be a device in an 'imsm' container */
|
||||
fd = open(dev, O_RDONLY|O_EXCL, 0);
|
||||
if (fd >= 0) {
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
Name ": imsm: Cannot create this array on "
|
||||
"device %s\n", dev);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if (errno != EBUSY || (fd = open(dev, O_RDONLY, 0)) < 0) {
|
||||
if (verbose)
|
||||
fprintf(stderr, Name ": imsm: Cannot open %s: %s\n",
|
||||
dev, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
/* Well, it is in use by someone, maybe an 'imsm' container. */
|
||||
cfd = open_container(fd);
|
||||
if (cfd < 0) {
|
||||
close(fd);
|
||||
if (verbose)
|
||||
fprintf(stderr, Name ": imsm: Cannot use %s: %s\n",
|
||||
dev, strerror(EBUSY));
|
||||
return 0;
|
||||
}
|
||||
sra = sysfs_read(cfd, 0, GET_VERSION);
|
||||
close(fd);
|
||||
if (sra && sra->array.major_version == -1 &&
|
||||
strcmp(sra->text_version, "imsm") == 0) {
|
||||
/* This is a member of a imsm container. Load the container
|
||||
* and try to create a volume
|
||||
*/
|
||||
struct intel_super *super;
|
||||
st->ss = &super_imsm_volume;
|
||||
if (load_super_imsm_all(st, cfd, (void **) &super, NULL, 1) == 0) {
|
||||
st->sb = super;
|
||||
st->container_dev = fd2devnum(cfd);
|
||||
close(cfd);
|
||||
return st->ss->validate_geometry(st, level, layout,
|
||||
raiddisks, chunk, size,
|
||||
dev, freesize,
|
||||
verbose);
|
||||
}
|
||||
close(cfd);
|
||||
} else /* may belong to another container */
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int validate_geometry_imsm_container(struct supertype *st, int level,
|
||||
int layout, int raiddisks, int chunk,
|
||||
unsigned long long size, char *dev,
|
||||
|
@ -1473,6 +1348,7 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
|
|||
for (dl = super->disks; dl ; dl = dl->next) {
|
||||
int found = 0;
|
||||
|
||||
pos = 0;
|
||||
i = 0;
|
||||
e = get_extents(super, dl);
|
||||
if (!e) continue;
|
||||
|
@ -1530,6 +1406,94 @@ static int validate_geometry_imsm_volume(struct supertype *st, int level,
|
|||
return 1;
|
||||
}
|
||||
|
||||
static int validate_geometry_imsm(struct supertype *st, int level, int layout,
|
||||
int raiddisks, int chunk, unsigned long long size,
|
||||
char *dev, unsigned long long *freesize,
|
||||
int verbose)
|
||||
{
|
||||
int fd, cfd;
|
||||
struct mdinfo *sra;
|
||||
|
||||
/* if given unused devices create a container
|
||||
* if given given devices in a container create a member volume
|
||||
*/
|
||||
if (level == LEVEL_CONTAINER) {
|
||||
/* Must be a fresh device to add to a container */
|
||||
return validate_geometry_imsm_container(st, level, layout,
|
||||
raiddisks, chunk, size,
|
||||
dev, freesize,
|
||||
verbose);
|
||||
}
|
||||
|
||||
if (st->sb) {
|
||||
/* creating in a given container */
|
||||
return validate_geometry_imsm_volume(st, level, layout,
|
||||
raiddisks, chunk, size,
|
||||
dev, freesize, verbose);
|
||||
}
|
||||
|
||||
/* limit creation to the following levels */
|
||||
if (!dev)
|
||||
switch (level) {
|
||||
case 0:
|
||||
case 1:
|
||||
case 10:
|
||||
case 5:
|
||||
break;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* This device needs to be a device in an 'imsm' container */
|
||||
fd = open(dev, O_RDONLY|O_EXCL, 0);
|
||||
if (fd >= 0) {
|
||||
if (verbose)
|
||||
fprintf(stderr,
|
||||
Name ": Cannot create this array on device %s\n",
|
||||
dev);
|
||||
close(fd);
|
||||
return 0;
|
||||
}
|
||||
if (errno != EBUSY || (fd = open(dev, O_RDONLY, 0)) < 0) {
|
||||
if (verbose)
|
||||
fprintf(stderr, Name ": Cannot open %s: %s\n",
|
||||
dev, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
/* Well, it is in use by someone, maybe an 'imsm' container. */
|
||||
cfd = open_container(fd);
|
||||
if (cfd < 0) {
|
||||
close(fd);
|
||||
if (verbose)
|
||||
fprintf(stderr, Name ": Cannot use %s: It is busy\n",
|
||||
dev);
|
||||
return 0;
|
||||
}
|
||||
sra = sysfs_read(cfd, 0, GET_VERSION);
|
||||
close(fd);
|
||||
if (sra && sra->array.major_version == -1 &&
|
||||
strcmp(sra->text_version, "imsm") == 0) {
|
||||
/* This is a member of a imsm container. Load the container
|
||||
* and try to create a volume
|
||||
*/
|
||||
struct intel_super *super;
|
||||
|
||||
if (load_super_imsm_all(st, cfd, (void **) &super, NULL, 1) == 0) {
|
||||
st->sb = super;
|
||||
st->container_dev = fd2devnum(cfd);
|
||||
close(cfd);
|
||||
return validate_geometry_imsm_volume(st, level, layout,
|
||||
raiddisks, chunk,
|
||||
size, dev,
|
||||
freesize, verbose);
|
||||
}
|
||||
close(cfd);
|
||||
} else /* may belong to another container */
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct mdinfo *container_content_imsm(struct supertype *st)
|
||||
{
|
||||
/* Given a container loaded by load_super_imsm_all,
|
||||
|
@ -1846,6 +1810,7 @@ struct superswitch super_imsm = {
|
|||
.brief_examine_super = brief_examine_super_imsm,
|
||||
.detail_super = detail_super_imsm,
|
||||
.brief_detail_super = brief_detail_super_imsm,
|
||||
.write_init_super = write_init_super_imsm,
|
||||
#endif
|
||||
.match_home = match_home_imsm,
|
||||
.uuid_from_super= uuid_from_super_imsm,
|
||||
|
@ -1857,10 +1822,12 @@ struct superswitch super_imsm = {
|
|||
.compare_super = compare_super_imsm,
|
||||
|
||||
.load_super = load_super_imsm,
|
||||
.init_super = init_zero_imsm,
|
||||
.init_super = init_super_imsm,
|
||||
.add_to_super = add_to_super_imsm,
|
||||
.store_super = store_zero_imsm,
|
||||
.free_super = free_super_imsm,
|
||||
.match_metadata_desc = match_metadata_desc_imsm,
|
||||
.container_content = container_content_imsm,
|
||||
|
||||
.validate_geometry = validate_geometry_imsm,
|
||||
.external = 1,
|
||||
|
@ -1872,45 +1839,3 @@ struct superswitch super_imsm = {
|
|||
.set_disk = imsm_set_disk,
|
||||
.sync_metadata = imsm_sync_metadata,
|
||||
};
|
||||
|
||||
/* super_imsm_container is set by validate_geometry_imsm when given a
|
||||
* device that is not part of any array
|
||||
*/
|
||||
struct superswitch super_imsm_container = {
|
||||
|
||||
.validate_geometry = validate_geometry_imsm_container,
|
||||
.init_super = init_super_imsm,
|
||||
.add_to_super = add_to_super_imsm,
|
||||
.write_init_super = write_init_super_imsm,
|
||||
.getinfo_super = getinfo_super_imsm,
|
||||
.load_super = load_super_imsm,
|
||||
|
||||
#ifndef MDASSEMBLE
|
||||
.examine_super = examine_super_imsm,
|
||||
.brief_examine_super = brief_examine_super_imsm,
|
||||
.detail_super = detail_super_imsm,
|
||||
.brief_detail_super = brief_detail_super_imsm,
|
||||
#endif
|
||||
|
||||
.free_super = free_super_imsm,
|
||||
|
||||
.container_content = container_content_imsm,
|
||||
|
||||
.external = 1,
|
||||
};
|
||||
|
||||
static struct superswitch super_imsm_volume = {
|
||||
.update_super = update_super_imsm,
|
||||
.init_super = init_super_imsm_volume,
|
||||
.add_to_super = add_to_super_imsm_volume,
|
||||
.getinfo_super = getinfo_super_imsm_volume,
|
||||
.write_init_super = write_init_super_imsm,
|
||||
|
||||
.load_super = load_super_imsm,
|
||||
.free_super = free_super_imsm,
|
||||
.match_metadata_desc = match_metadata_desc_imsm_volume,
|
||||
|
||||
|
||||
.validate_geometry = validate_geometry_imsm_volume,
|
||||
.external = 2,
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue