Commit e2a7b9f4 authored by Jens Axboe's avatar Jens Axboe

Merge branch 'md-next' of...

Merge branch 'md-next' of git://git.kernel.org/pub/scm/linux/kernel/git/song/md into for-5.5/drivers

Pull MD changes from Song.

* 'md-next' of git://git.kernel.org/pub/scm/linux/kernel/git/song/md:
  md/raid10: prevent access of uninitialized resync_pages offset
  md: avoid invalid memory access for array sb->dev_roles
  md/raid1: avoid soft lockup under high load
parents da644b2c 45422b70
...@@ -1105,6 +1105,7 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor ...@@ -1105,6 +1105,7 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor
char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
mdp_super_t *sb; mdp_super_t *sb;
int ret; int ret;
bool spare_disk = true;
/* /*
* Calculate the position of the superblock (512byte sectors), * Calculate the position of the superblock (512byte sectors),
...@@ -1155,13 +1156,15 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor ...@@ -1155,13 +1156,15 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor
else else
rdev->desc_nr = sb->this_disk.number; rdev->desc_nr = sb->this_disk.number;
/* not spare disk, or LEVEL_MULTIPATH */
if (sb->level == LEVEL_MULTIPATH ||
(rdev->desc_nr >= 0 &&
sb->disks[rdev->desc_nr].state &
((1<<MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE))))
spare_disk = false;
if (!refdev) { if (!refdev) {
/* if (!spare_disk)
* Insist on good event counter while assembling, except
* for spares (which don't need an event count)
*/
if (sb->disks[rdev->desc_nr].state & (
(1<<MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE)))
ret = 1; ret = 1;
else else
ret = 0; ret = 0;
...@@ -1181,13 +1184,7 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor ...@@ -1181,13 +1184,7 @@ static int super_90_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor
ev1 = md_event(sb); ev1 = md_event(sb);
ev2 = md_event(refsb); ev2 = md_event(refsb);
/* if (!spare_disk && ev1 > ev2)
* Insist on good event counter while assembling, except
* for spares (which don't need an event count)
*/
if (sb->disks[rdev->desc_nr].state & (
(1<<MD_DISK_SYNC) | (1 << MD_DISK_ACTIVE)) &&
(ev1 > ev2))
ret = 1; ret = 1;
else else
ret = 0; ret = 0;
...@@ -1547,7 +1544,7 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_ ...@@ -1547,7 +1544,7 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
sector_t sectors; sector_t sectors;
char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE]; char b[BDEVNAME_SIZE], b2[BDEVNAME_SIZE];
int bmask; int bmask;
__u64 role; bool spare_disk = true;
/* /*
* Calculate the position of the superblock in 512byte sectors. * Calculate the position of the superblock in 512byte sectors.
...@@ -1681,17 +1678,16 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_ ...@@ -1681,17 +1678,16 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
sb->level != 0) sb->level != 0)
return -EINVAL; return -EINVAL;
role = le16_to_cpu(sb->dev_roles[rdev->desc_nr]); /* not spare disk, or LEVEL_MULTIPATH */
if (sb->level == cpu_to_le32(LEVEL_MULTIPATH) ||
(rdev->desc_nr >= 0 &&
rdev->desc_nr < le32_to_cpu(sb->max_dev) &&
(le16_to_cpu(sb->dev_roles[rdev->desc_nr]) < MD_DISK_ROLE_MAX ||
le16_to_cpu(sb->dev_roles[rdev->desc_nr]) == MD_DISK_ROLE_JOURNAL)))
spare_disk = false;
if (!refdev) { if (!refdev) {
/* if (!spare_disk)
* Insist of good event counter while assembling, except for
* spares (which don't need an event count)
*/
if (rdev->desc_nr >= 0 &&
rdev->desc_nr < le32_to_cpu(sb->max_dev) &&
(role < MD_DISK_ROLE_MAX ||
role == MD_DISK_ROLE_JOURNAL))
ret = 1; ret = 1;
else else
ret = 0; ret = 0;
...@@ -1711,14 +1707,7 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_ ...@@ -1711,14 +1707,7 @@ static int super_1_load(struct md_rdev *rdev, struct md_rdev *refdev, int minor_
ev1 = le64_to_cpu(sb->events); ev1 = le64_to_cpu(sb->events);
ev2 = le64_to_cpu(refsb->events); ev2 = le64_to_cpu(refsb->events);
/* if (!spare_disk && ev1 > ev2)
* Insist of good event counter while assembling, except for
* spares (which don't need an event count)
*/
if (rdev->desc_nr >= 0 &&
rdev->desc_nr < le32_to_cpu(sb->max_dev) &&
(role < MD_DISK_ROLE_MAX ||
role == MD_DISK_ROLE_JOURNAL) && ev1 > ev2)
ret = 1; ret = 1;
else else
ret = 0; ret = 0;
......
...@@ -819,6 +819,7 @@ static void flush_bio_list(struct r1conf *conf, struct bio *bio) ...@@ -819,6 +819,7 @@ static void flush_bio_list(struct r1conf *conf, struct bio *bio)
else else
generic_make_request(bio); generic_make_request(bio);
bio = next; bio = next;
cond_resched();
} }
} }
......
...@@ -191,7 +191,7 @@ static void * r10buf_pool_alloc(gfp_t gfp_flags, void *data) ...@@ -191,7 +191,7 @@ static void * r10buf_pool_alloc(gfp_t gfp_flags, void *data)
out_free_pages: out_free_pages:
while (--j >= 0) while (--j >= 0)
resync_free_pages(&rps[j * 2]); resync_free_pages(&rps[j]);
j = 0; j = 0;
out_free_bio: out_free_bio:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment