diff options
author | NeilBrown <neilb@suse.de> | 2012-05-31 01:39:11 -0400 |
---|---|---|
committer | NeilBrown <neilb@suse.de> | 2012-05-31 01:56:30 -0400 |
commit | aba336bd1d46d6b0404b06f6915ed76150739057 (patch) | |
tree | 6517e35ba3f6df77276d9c4e81d8ec726228aacd /drivers | |
parent | 2aa4ee2a8805ec0260dde971e9e6699917c868a7 (diff) |
md: raid1/raid10: fix problem with merge_bvec_fn
The new merge_bvec_fn which calls the corresponding function
in subsidiary devices requires that mddev->merge_check_needed
be set if any child has a merge_bvec_fn.
However were were only setting that when a device was hot-added,
not when a device was present from the start.
This bug was introduced in 3.4 so patch is suitable for 3.4.y
kernels. However that are conflicts in raid10.c so a separate
patch will be needed for 3.4.y.
Cc: stable@vger.kernel.org
Reported-by: Sebastian Riemer <sebastian.riemer@profitbricks.com>
Signed-off-by: NeilBrown <neilb@suse.de>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/md/raid1.c | 4 | ||||
-rw-r--r-- | drivers/md/raid10.c | 4 |
2 files changed, 8 insertions, 0 deletions
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c index 835de7168cd3..a9c7981ddd24 100644 --- a/drivers/md/raid1.c +++ b/drivers/md/raid1.c | |||
@@ -2550,6 +2550,7 @@ static struct r1conf *setup_conf(struct mddev *mddev) | |||
2550 | err = -EINVAL; | 2550 | err = -EINVAL; |
2551 | spin_lock_init(&conf->device_lock); | 2551 | spin_lock_init(&conf->device_lock); |
2552 | rdev_for_each(rdev, mddev) { | 2552 | rdev_for_each(rdev, mddev) { |
2553 | struct request_queue *q; | ||
2553 | int disk_idx = rdev->raid_disk; | 2554 | int disk_idx = rdev->raid_disk; |
2554 | if (disk_idx >= mddev->raid_disks | 2555 | if (disk_idx >= mddev->raid_disks |
2555 | || disk_idx < 0) | 2556 | || disk_idx < 0) |
@@ -2562,6 +2563,9 @@ static struct r1conf *setup_conf(struct mddev *mddev) | |||
2562 | if (disk->rdev) | 2563 | if (disk->rdev) |
2563 | goto abort; | 2564 | goto abort; |
2564 | disk->rdev = rdev; | 2565 | disk->rdev = rdev; |
2566 | q = bdev_get_queue(rdev->bdev); | ||
2567 | if (q->merge_bvec_fn) | ||
2568 | mddev->merge_check_needed = 1; | ||
2565 | 2569 | ||
2566 | disk->head_position = 0; | 2570 | disk->head_position = 0; |
2567 | } | 2571 | } |
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c index 987db37cb875..99ae6068e456 100644 --- a/drivers/md/raid10.c +++ b/drivers/md/raid10.c | |||
@@ -3475,6 +3475,7 @@ static int run(struct mddev *mddev) | |||
3475 | 3475 | ||
3476 | rdev_for_each(rdev, mddev) { | 3476 | rdev_for_each(rdev, mddev) { |
3477 | long long diff; | 3477 | long long diff; |
3478 | struct request_queue *q; | ||
3478 | 3479 | ||
3479 | disk_idx = rdev->raid_disk; | 3480 | disk_idx = rdev->raid_disk; |
3480 | if (disk_idx < 0) | 3481 | if (disk_idx < 0) |
@@ -3493,6 +3494,9 @@ static int run(struct mddev *mddev) | |||
3493 | goto out_free_conf; | 3494 | goto out_free_conf; |
3494 | disk->rdev = rdev; | 3495 | disk->rdev = rdev; |
3495 | } | 3496 | } |
3497 | q = bdev_get_queue(rdev->bdev); | ||
3498 | if (q->merge_bvec_fn) | ||
3499 | mddev->merge_check_needed = 1; | ||
3496 | diff = (rdev->new_data_offset - rdev->data_offset); | 3500 | diff = (rdev->new_data_offset - rdev->data_offset); |
3497 | if (!mddev->reshape_backwards) | 3501 | if (!mddev->reshape_backwards) |
3498 | diff = -diff; | 3502 | diff = -diff; |