Skip to contentSkip to conversation

2.5.48-bk, md raid0 fix

PATCH In review Thorbjørn Lind 3 participants 4 messages Nov 20, 2002 – Nov 21, 2002 MD RAID

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 2.5.48-bk, md raid0 fix

Fixes the 'BUG at drivers/block/ll_rw_blk.c:19xx' when using raid0 md devices since 2.5.45...

/tul

drivers/md/raid0.c +8 -9
@@ -173,15 +173,14 @@
 static int raid0_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio_vec *biovec)
 {
 	mddev_t *mddev = q->queuedata;
-	sector_t block;
-	unsigned int chunk_size;
-	unsigned int bio_sz;
-
-	chunk_size = mddev->chunk_size >> 10;
-	block = bio->bi_sector >> 1;
-	bio_sz = (bio->bi_size + biovec->bv_len) >> 10;
-
-	return (chunk_size - ((block & (chunk_size - 1)) + bio_sz)) << 10;
+	unsigned int max_size;
+
+	max_size = mddev->chunk_size - ((bio->bi_sector % (mddev->chunk_size >> 9)) << 9);
+
+	if(biovec->bv_len <= (max_size - bio->bi_size))
+	    return biovec->bv_len;
+
+	return max_size - bio->bi_size;
 }
 
 static int raid0_run (mddev_t *mddev)
#1 lore raw
Quoted 5 lines · Thorbjørn Lind

Fixes the 'BUG at drivers/block/ll_rw_blk.c:19xx' when using raid0 md devices since 2.5.45...

...
+ max_size = mddev->chunk_size - ((bio->bi_sector % (mddev->chunk_size >> 9)) << 9);

The mod operator on a 64-bit quantity won't work with CONFIG_LBD=y, will it?

#2 lore raw
Quoted 2 lines

The mod operator on a 64-bit quantity won't work with CONFIG_LBD=y, will it?

Ohh.. there is such a thing.. let's use & :)

#3 lore raw
Quoted 5 lines · On Wednesday November 20, [email protected] wrote:
Quoted 2 lines

The mod operator on a 64-bit quantity won't work with CONFIG_LBD=y, will it?

Ohh.. there is such a thing.. let's use & :)

Here is my version which does the 'right' thing w.r.t. large sector addresses etc.

I just sent it to Linus for the third time. Hopefully it wont be dropped again :-(

NeilBrown
--------------------------------------------------------
Fix *_mergeable_bvec routines for linear/raid0.

They take the length of the passed bvec into account, which is wrong.

----------- Diffstat output ------------

 ./drivers/md/linear.c |    7 ++-----
 ./drivers/md/raid0.c  |   16 ++++++++--------
 2 files changed, 10 insertions(+), 13 deletions(-)
drivers/md/linear.c renamed from drivers/md/linear.c~current~ +2 -5
diff ./drivers/md/linear.c~current~ ./drivers/md/linear.c
@@ -58,15 +58,12 @@ static int linear_mergeable_bvec(request
 {
 	mddev_t *mddev = q->queuedata;
 	dev_info_t *dev0;
-	int maxsectors, bio_sectors = (bio->bi_size + biovec->bv_len) >> 9;
+	unsigned long maxsectors, bio_sectors = bio->bi_size >> 9;
 
 	dev0 = which_dev(mddev, bio->bi_sector);
 	maxsectors = (dev0->size << 1) - (bio->bi_sector - (dev0->offset<<1));
 
-	if (bio_sectors <= maxsectors)
-		return biovec->bv_len;
-
-	return (maxsectors << 9) - bio->bi_size;
+	return (maxsectors - bio_sectors) << 9;
 }
 
 static int linear_run (mddev_t *mddev)
drivers/md/raid0.c renamed from drivers/md/raid0.c~current~ +8 -8
diff ./drivers/md/raid0.c~current~ ./drivers/md/raid0.c
@@ -173,15 +173,15 @@ static int create_strip_zones (mddev_t *
 static int raid0_mergeable_bvec(request_queue_t *q, struct bio *bio, struct bio_vec *biovec)
 {
 	mddev_t *mddev = q->queuedata;
-	sector_t block;
-	unsigned int chunk_size;
-	unsigned int bio_sz;
+	sector_t sector;
+	unsigned int chunk_sectors;
+	unsigned int bio_sectors;
+
+	chunk_sectors = mddev->chunk_size >> 9;
+	sector = bio->bi_sector;
+	bio_sectors = bio->bi_size >> 9;
 
-	chunk_size = mddev->chunk_size >> 10;
-	block = bio->bi_sector >> 1;
-	bio_sz = (bio->bi_size + biovec->bv_len) >> 10;
-
-	return (chunk_size - ((block & (chunk_size - 1)) + bio_sz)) << 10;
+	return (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9;
 }
 
 static int raid0_run (mddev_t *mddev)