Commit 59165b4f authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] md: Limit max_sectors on md when merge_bvec_fn defined on underlying device.

From: NeilBrown <neilb@cse.unsw.edu.au>

As no md personalities honour the merge_bvec_fn of underlying devices,
we must make sure never to submit a bio larger than 1 page when a 
merge_bvec_fn is defined.

raid5 already does this (it never submits bios larger than one page).
With this patch, all other raid personalities limit their
max_sectors when a merge_bvec_fn is present.
parent 0b0a866d
...@@ -113,8 +113,17 @@ static int linear_run (mddev_t *mddev) ...@@ -113,8 +113,17 @@ static int linear_run (mddev_t *mddev)
} }
disk->rdev = rdev; disk->rdev = rdev;
blk_queue_stack_limits(mddev->queue, blk_queue_stack_limits(mddev->queue,
rdev->bdev->bd_disk->queue); rdev->bdev->bd_disk->queue);
/* as we don't honour merge_bvec_fn, we must never risk
* violating it, so limit ->max_sector to one PAGE, as
* a one page request is never in violation.
*/
if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
mddev->queue->max_sectors > (PAGE_SIZE>>9))
mddev->queue->max_sectors = (PAGE_SIZE>>9);
disk->size = rdev->size; disk->size = rdev->size;
mddev->array_size += rdev->size; mddev->array_size += rdev->size;
......
...@@ -273,6 +273,17 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) ...@@ -273,6 +273,17 @@ static int multipath_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
p->rdev = rdev; p->rdev = rdev;
blk_queue_stack_limits(mddev->queue, blk_queue_stack_limits(mddev->queue,
rdev->bdev->bd_disk->queue); rdev->bdev->bd_disk->queue);
/* as we don't honour merge_bvec_fn, we must never risk
* violating it, so limit ->max_sector to one PAGE, as
* a one page request is never in violation.
* (Note: it is very unlikely that a device with
* merge_bvec_fn will be involved in multipath.)
*/
if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
mddev->queue->max_sectors > (PAGE_SIZE>>9))
mddev->queue->max_sectors = (PAGE_SIZE>>9);
conf->working_disks++; conf->working_disks++;
rdev->raid_disk = path; rdev->raid_disk = path;
rdev->in_sync = 1; rdev->in_sync = 1;
...@@ -410,8 +421,16 @@ static int multipath_run (mddev_t *mddev) ...@@ -410,8 +421,16 @@ static int multipath_run (mddev_t *mddev)
disk = conf->multipaths + disk_idx; disk = conf->multipaths + disk_idx;
disk->rdev = rdev; disk->rdev = rdev;
blk_queue_stack_limits(mddev->queue, blk_queue_stack_limits(mddev->queue,
rdev->bdev->bd_disk->queue); rdev->bdev->bd_disk->queue);
/* as we don't honour merge_bvec_fn, we must never risk
* violating it, not that we ever expect a device with
* a merge_bvec_fn to be involved in multipath */
if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
mddev->queue->max_sectors > (PAGE_SIZE>>9))
mddev->queue->max_sectors = (PAGE_SIZE>>9);
if (!rdev->faulty) if (!rdev->faulty)
conf->working_disks++; conf->working_disks++;
} }
......
...@@ -112,8 +112,18 @@ static int create_strip_zones (mddev_t *mddev) ...@@ -112,8 +112,18 @@ static int create_strip_zones (mddev_t *mddev)
goto abort; goto abort;
} }
zone->dev[j] = rdev1; zone->dev[j] = rdev1;
blk_queue_stack_limits(mddev->queue, blk_queue_stack_limits(mddev->queue,
rdev1->bdev->bd_disk->queue); rdev1->bdev->bd_disk->queue);
/* as we don't honour merge_bvec_fn, we must never risk
* violating it, so limit ->max_sector to one PAGE, as
* a one page request is never in violation.
*/
if (rdev1->bdev->bd_disk->queue->merge_bvec_fn &&
mddev->queue->max_sectors > (PAGE_SIZE>>9))
mddev->queue->max_sectors = (PAGE_SIZE>>9);
if (!smallest || (rdev1->size <smallest->size)) if (!smallest || (rdev1->size <smallest->size))
smallest = rdev1; smallest = rdev1;
cnt++; cnt++;
......
...@@ -677,8 +677,17 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev) ...@@ -677,8 +677,17 @@ static int raid1_add_disk(mddev_t *mddev, mdk_rdev_t *rdev)
for (mirror=0; mirror < mddev->raid_disks; mirror++) for (mirror=0; mirror < mddev->raid_disks; mirror++)
if ( !(p=conf->mirrors+mirror)->rdev) { if ( !(p=conf->mirrors+mirror)->rdev) {
p->rdev = rdev; p->rdev = rdev;
blk_queue_stack_limits(mddev->queue, blk_queue_stack_limits(mddev->queue,
rdev->bdev->bd_disk->queue); rdev->bdev->bd_disk->queue);
/* as we don't honour merge_bvec_fn, we must never risk
* violating it, so limit ->max_sector to one PAGE, as
* a one page request is never in violation.
*/
if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
mddev->queue->max_sectors > (PAGE_SIZE>>9))
mddev->queue->max_sectors = (PAGE_SIZE>>9);
p->head_position = 0; p->head_position = 0;
rdev->raid_disk = mirror; rdev->raid_disk = mirror;
found = 1; found = 1;
...@@ -1077,8 +1086,17 @@ static int run(mddev_t *mddev) ...@@ -1077,8 +1086,17 @@ static int run(mddev_t *mddev)
disk = conf->mirrors + disk_idx; disk = conf->mirrors + disk_idx;
disk->rdev = rdev; disk->rdev = rdev;
blk_queue_stack_limits(mddev->queue, blk_queue_stack_limits(mddev->queue,
rdev->bdev->bd_disk->queue); rdev->bdev->bd_disk->queue);
/* as we don't honour merge_bvec_fn, we must never risk
* violating it, so limit ->max_sector to one PAGE, as
* a one page request is never in violation.
*/
if (rdev->bdev->bd_disk->queue->merge_bvec_fn &&
mddev->queue->max_sectors > (PAGE_SIZE>>9))
mddev->queue->max_sectors = (PAGE_SIZE>>9);
disk->head_position = 0; disk->head_position = 0;
if (!rdev->faulty && rdev->in_sync) if (!rdev->faulty && rdev->in_sync)
conf->working_disks++; conf->working_disks++;
......
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