Commit 00d1b0e9 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] md: merge_bvec_fn needs to know about partitions.

From: Neil Brown <neilb@cse.unsw.edu.au>

Addresses http://bugme.osdl.org/show_bug.cgi?id=2355

It seems that a merge_bvec_fn needs to be aware of partitioning...  who
would have thought it :-(

The following patch should fix the merge_bvec_fn for both linear and raid0.
We teach linear and raid0 about partitions in the merge_bvec_fn.

->merge_bvec_fn needs to make decisions based on the physical geometry of the
device.  For raid0, it needs to decide if adding the bvec to the bio will
make the bio span two drives.

To do this, it needs to know where the request is (what the sector number is)
in the whole device.

However when called from bio_add_page, bi_sector is the sector number
relative to the current partition, as generic_make_request hasn't been called
yet.

So raid_mergeable_bvec needs to map bio->bi_sector (which is partition
relative) to a bi_sector which is device relative, so it can perform proper
calculations about when chunk boundaries are.
parent 9abdc660
...@@ -61,9 +61,10 @@ static int linear_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio ...@@ -61,9 +61,10 @@ static int linear_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio
mddev_t *mddev = q->queuedata; mddev_t *mddev = q->queuedata;
dev_info_t *dev0; dev_info_t *dev0;
unsigned long maxsectors, bio_sectors = bio->bi_size >> 9; unsigned long maxsectors, bio_sectors = bio->bi_size >> 9;
sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev);
dev0 = which_dev(mddev, bio->bi_sector); dev0 = which_dev(mddev, sector);
maxsectors = (dev0->size << 1) - (bio->bi_sector - (dev0->offset<<1)); maxsectors = (dev0->size << 1) - (sector - (dev0->offset<<1));
if (maxsectors < bio_sectors) if (maxsectors < bio_sectors)
maxsectors = 0; maxsectors = 0;
......
...@@ -219,7 +219,7 @@ static int create_strip_zones (mddev_t *mddev) ...@@ -219,7 +219,7 @@ static int create_strip_zones (mddev_t *mddev)
static int raid0_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio_vec *biovec) static int raid0_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio_vec *biovec)
{ {
mddev_t *mddev = q->queuedata; mddev_t *mddev = q->queuedata;
sector_t sector = bio->bi_sector; sector_t sector = bio->bi_sector + get_start_sect(bio->bi_bdev);
int max; int max;
unsigned int chunk_sectors = mddev->chunk_size >> 9; unsigned int chunk_sectors = mddev->chunk_size >> 9;
unsigned int bio_sectors = bio->bi_size >> 9; unsigned int bio_sectors = bio->bi_size >> 9;
......
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