DDF: guard against ->pdnum being negative.
It is conceivable that ->pdnum could be -1, though only if the metadata is corrupt. We should be careful not to use it if it is. Also remove an assignment for pdnum to ->container_member. This is never used and cannot possibly mean anything. Signed-off-by: NeilBrown <neilb@suse.de>
This commit is contained in:
parent
e5a03804dc
commit
a44e993e37
22
super-ddf.c
22
super-ddf.c
|
@ -2490,7 +2490,11 @@ static struct extent *get_extents(struct ddf_super *ddf, struct dl *dl)
|
||||||
struct extent *rv;
|
struct extent *rv;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
__u16 state = be16_to_cpu(ddf->phys->entries[dl->pdnum].state);
|
__u16 state;
|
||||||
|
|
||||||
|
if (dl->pdnum < 0)
|
||||||
|
return NULL;
|
||||||
|
state = be16_to_cpu(ddf->phys->entries[dl->pdnum].state);
|
||||||
|
|
||||||
if ((state & (DDF_Online|DDF_Failed|DDF_Missing)) != DDF_Online)
|
if ((state & (DDF_Online|DDF_Failed|DDF_Missing)) != DDF_Online)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -2923,7 +2927,7 @@ static int remove_from_super_ddf(struct supertype *st, mdu_disk_info_t *dk)
|
||||||
if (dl->major == dk->major &&
|
if (dl->major == dk->major &&
|
||||||
dl->minor == dk->minor)
|
dl->minor == dk->minor)
|
||||||
break;
|
break;
|
||||||
if (!dl)
|
if (!dl || dl->pdnum < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (st->update_tail) {
|
if (st->update_tail) {
|
||||||
|
@ -4105,7 +4109,7 @@ static int ddf_open_new(struct supertype *c, struct active_array *a, char *inst)
|
||||||
if (dl->major == dev->disk.major &&
|
if (dl->major == dev->disk.major &&
|
||||||
dl->minor == dev->disk.minor)
|
dl->minor == dev->disk.minor)
|
||||||
break;
|
break;
|
||||||
if (!dl) {
|
if (!dl || dl->pdnum < 0) {
|
||||||
pr_err("%s: device %d/%d of subarray %d not found in meta data\n",
|
pr_err("%s: device %d/%d of subarray %d not found in meta data\n",
|
||||||
__func__, dev->disk.major, dev->disk.minor, n);
|
__func__, dev->disk.major, dev->disk.minor, n);
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -4733,6 +4737,9 @@ static void ddf_process_update(struct supertype *st,
|
||||||
for (dl = ddf->dlist; dl; dl = dl->next) {
|
for (dl = ddf->dlist; dl; dl = dl->next) {
|
||||||
unsigned int vn = 0;
|
unsigned int vn = 0;
|
||||||
int in_degraded = 0;
|
int in_degraded = 0;
|
||||||
|
|
||||||
|
if (dl->pdnum < 0)
|
||||||
|
continue;
|
||||||
for (vcl = ddf->conflist; vcl ; vcl = vcl->next) {
|
for (vcl = ddf->conflist; vcl ; vcl = vcl->next) {
|
||||||
unsigned int dn, ibvd;
|
unsigned int dn, ibvd;
|
||||||
const struct vd_config *conf;
|
const struct vd_config *conf;
|
||||||
|
@ -4996,7 +5003,11 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a,
|
||||||
int is_dedicated = 0;
|
int is_dedicated = 0;
|
||||||
struct extent *ex;
|
struct extent *ex;
|
||||||
unsigned int j;
|
unsigned int j;
|
||||||
be16 state = ddf->phys->entries[dl->pdnum].state;
|
be16 state;
|
||||||
|
|
||||||
|
if (dl->pdnum < 0)
|
||||||
|
continue;
|
||||||
|
state = ddf->phys->entries[dl->pdnum].state;
|
||||||
if (be16_and(state,
|
if (be16_and(state,
|
||||||
cpu_to_be16(DDF_Failed|DDF_Missing)) ||
|
cpu_to_be16(DDF_Failed|DDF_Missing)) ||
|
||||||
!be16_and(state,
|
!be16_and(state,
|
||||||
|
@ -5087,7 +5098,6 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a,
|
||||||
di->recovery_start = 0;
|
di->recovery_start = 0;
|
||||||
di->data_offset = pos;
|
di->data_offset = pos;
|
||||||
di->component_size = a->info.component_size;
|
di->component_size = a->info.component_size;
|
||||||
di->container_member = dl->pdnum;
|
|
||||||
di->next = rv;
|
di->next = rv;
|
||||||
rv = di;
|
rv = di;
|
||||||
dprintf("%x:%x (%08x) to be %d at %llu\n",
|
dprintf("%x:%x (%08x) to be %d at %llu\n",
|
||||||
|
@ -5145,7 +5155,7 @@ static struct mdinfo *ddf_activate_spare(struct active_array *a,
|
||||||
if (dl->major == di->disk.major
|
if (dl->major == di->disk.major
|
||||||
&& dl->minor == di->disk.minor)
|
&& dl->minor == di->disk.minor)
|
||||||
break;
|
break;
|
||||||
if (!dl) {
|
if (!dl || dl->pdnum < 0) {
|
||||||
pr_err("%s: BUG: can't find disk %d (%d/%d)\n",
|
pr_err("%s: BUG: can't find disk %d (%d/%d)\n",
|
||||||
__func__, di->disk.raid_disk,
|
__func__, di->disk.raid_disk,
|
||||||
di->disk.major, di->disk.minor);
|
di->disk.major, di->disk.minor);
|
||||||
|
|
Loading…
Reference in New Issue