Check all member devices in enough_fd
The loop over all member devices in enough_fd could easily stop before it had found all devices. This would cause --re-add to fail incorrectly. So change the loop to be based on the reported number of devices in the device - with a safe-guard limit of 1024. Change some other loops to be more careful too. Reported-by: "Schmidt, Annemarie" <Annemarie.Schmidt@stratus.com> Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
f4db7a6f3c
commit
9e6d929127
8
Manage.c
8
Manage.c
|
@ -438,19 +438,21 @@ int Manage_subdevs(char *devname, int fd,
|
|||
|
||||
if (strcmp(dv->devname, "failed")==0 ||
|
||||
strcmp(dv->devname, "faulty")==0) {
|
||||
int remaining_disks = array.nr_disks;
|
||||
if (dv->disposition != 'r') {
|
||||
fprintf(stderr, Name ": %s only meaningful "
|
||||
"with -r, not -%c\n",
|
||||
dv->devname, dv->disposition);
|
||||
return 1;
|
||||
}
|
||||
for (; j < array.raid_disks + array.nr_disks ; j++) {
|
||||
for (; j < 1024 && remaining_disks > 0; j++) {
|
||||
unsigned dev;
|
||||
disc.number = j;
|
||||
if (ioctl(fd, GET_DISK_INFO, &disc))
|
||||
continue;
|
||||
if (disc.major == 0 && disc.minor == 0)
|
||||
continue;
|
||||
remaining_disks --;
|
||||
if ((disc.state & 1) == 0) /* faulty */
|
||||
continue;
|
||||
dev = makedev(disc.major, disc.minor);
|
||||
|
@ -469,13 +471,14 @@ int Manage_subdevs(char *devname, int fd,
|
|||
if (next != dv)
|
||||
continue;
|
||||
} else if (strcmp(dv->devname, "detached") == 0) {
|
||||
int remaining_disks = array.nr_disks;
|
||||
if (dv->disposition != 'r' && dv->disposition != 'f') {
|
||||
fprintf(stderr, Name ": %s only meaningful "
|
||||
"with -r of -f, not -%c\n",
|
||||
dv->devname, dv->disposition);
|
||||
return 1;
|
||||
}
|
||||
for (; j < array.raid_disks + array.nr_disks; j++) {
|
||||
for (; j < 1024 && remaining_disks > 0; j++) {
|
||||
int sfd;
|
||||
unsigned dev;
|
||||
disc.number = j;
|
||||
|
@ -483,6 +486,7 @@ int Manage_subdevs(char *devname, int fd,
|
|||
continue;
|
||||
if (disc.major == 0 && disc.minor == 0)
|
||||
continue;
|
||||
remaining_disks --;
|
||||
sprintf(dvname,"%d:%d", disc.major, disc.minor);
|
||||
sfd = dev_open(dvname, O_RDONLY);
|
||||
if (sfd >= 0) {
|
||||
|
|
10
Monitor.c
10
Monitor.c
|
@ -449,6 +449,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
|||
char *dev = st->devname;
|
||||
int fd;
|
||||
int i;
|
||||
int remaining_disks;
|
||||
int last_disk;
|
||||
|
||||
if (test)
|
||||
alert("TestMessage", dev, NULL, ainfo);
|
||||
|
@ -565,7 +567,8 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
|||
}
|
||||
st->percent = mse->percent;
|
||||
|
||||
for (i=0; i<MaxDisks && i <= array.raid_disks + array.nr_disks;
|
||||
remaining_disks = array.nr_disks;
|
||||
for (i=0; i<MaxDisks && remaining_disks > 0;
|
||||
i++) {
|
||||
mdu_disk_info_t disc;
|
||||
disc.number = i;
|
||||
|
@ -573,9 +576,12 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
|||
info[i].state = disc.state;
|
||||
info[i].major = disc.major;
|
||||
info[i].minor = disc.minor;
|
||||
if (disc.major || disc.minor)
|
||||
remaining_disks --;
|
||||
} else
|
||||
info[i].major = info[i].minor = 0;
|
||||
}
|
||||
last_disk = i;
|
||||
|
||||
if (mse->metadata_version &&
|
||||
strncmp(mse->metadata_version, "external:", 9) == 0 &&
|
||||
|
@ -596,7 +602,7 @@ static int check_array(struct state *st, struct mdstat_ent *mdstat,
|
|||
int change;
|
||||
char *dv = NULL;
|
||||
disc.number = i;
|
||||
if (i > array.raid_disks + array.nr_disks) {
|
||||
if (i >= last_disk) {
|
||||
newstate = 0;
|
||||
disc.major = disc.minor = 0;
|
||||
} else if (info[i].major || info[i].minor) {
|
||||
|
|
13
util.c
13
util.c
|
@ -370,10 +370,14 @@ int enough_fd(int fd)
|
|||
array.raid_disks <= 0)
|
||||
return 0;
|
||||
avail = calloc(array.raid_disks, 1);
|
||||
for (i=0; i<array.raid_disks + array.nr_disks; i++) {
|
||||
for (i=0; i < 1024 && array.nr_disks > 0; i++) {
|
||||
disk.number = i;
|
||||
if (ioctl(fd, GET_DISK_INFO, &disk) != 0)
|
||||
continue;
|
||||
if (disk.major == 0 && disk.minor == 0)
|
||||
continue;
|
||||
array.nr_disks--;
|
||||
|
||||
if (! (disk.state & (1<<MD_DISK_SYNC)))
|
||||
continue;
|
||||
if (disk.raid_disk < 0 || disk.raid_disk >= array.raid_disks)
|
||||
|
@ -1256,10 +1260,13 @@ int check_partitions(int fd, char *dname, unsigned long long freesize,
|
|||
void get_one_disk(int mdfd, mdu_array_info_t *ainf, mdu_disk_info_t *disk)
|
||||
{
|
||||
int d;
|
||||
|
||||
ioctl(mdfd, GET_ARRAY_INFO, ainf);
|
||||
for (d = 0 ; d < ainf->raid_disks + ainf->nr_disks ; d++)
|
||||
if (ioctl(mdfd, GET_DISK_INFO, disk) == 0)
|
||||
for (d = 0 ; d < 1024 ; d++) {
|
||||
if (ioctl(mdfd, GET_DISK_INFO, disk) == 0 &&
|
||||
(disk->major || disk->minor))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
int open_container(int fd)
|
||||
|
|
Loading…
Reference in New Issue