Commit 356c3c30 authored by Peter Chubb's avatar Peter Chubb Committed by Linus Torvalds

[PATCH] Compile failure (gcc 2.96 bug?). 2.5.42 raid0.c

Yes it's a GCC optimiser bug.  I'm surprised I didn't see it: I tried
a whole heap of different compilers on that code, and had problems
only on the earlier similar code in raid0_run().

I didn't try redhat's compilers (I run debian) but didn't expect the
behaviour to be that different.

Anyway, please apply this patch (which also fixes the chunk overlap
problems).
parent de1c3893
......@@ -162,6 +162,29 @@ static int create_strip_zones (mddev_t *mddev)
return 1;
}
/**
* raid0_mergeable_bvec -- tell bio layer if a two requests can be merged
* @q: request queue
* @bio: the buffer head that's been built up so far
* @biovec: the request that could be merged to it.
*
* Return 1 if the merge is not permitted (because the
* result would cross a chunk boundary), 0 otherwise.
*/
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);
}
static int raid0_run (mddev_t *mddev)
{
unsigned cur=0, i=0, nb_zone;
......@@ -233,6 +256,8 @@ static int raid0_run (mddev_t *mddev)
conf->hash_table[i++].zone1 = conf->strip_zone + cur;
size -= (conf->smallest->size - zone0_size);
}
blk_queue_max_sectors(&mddev->queue, mddev->chunk_size >> 9);
blk_queue_merge_bvec(&mddev->queue, raid0_mergeable_bvec);
return 0;
out_free_zone_conf:
......@@ -262,13 +287,6 @@ static int raid0_stop (mddev_t *mddev)
return 0;
}
/*
* FIXME - We assume some things here :
* - requested buffers NEVER bigger than chunk size,
* - requested buffers NEVER cross stripes limits.
* Of course, those facts may not be valid anymore (and surely won't...)
* Hey guys, there's some work out there ;-)
*/
static int raid0_make_request (request_queue_t *q, struct bio *bio)
{
mddev_t *mddev = q->queuedata;
......@@ -286,13 +304,16 @@ static int raid0_make_request (request_queue_t *q, struct bio *bio)
{
#if __GNUC__ < 3
volatile
#endif
sector_t x = block;
sector_div(x, (unsigned long)conf->smallest->size);
hash = conf->hash_table + x;
}
/* Sanity check */
if (chunk_size < (block & (chunk_size - 1)) + (bio->bi_size >> 10))
/* Sanity check -- queue functions should prevent this happening */
if (unlikely(chunk_size < (block & (chunk_size - 1)) + (bio->bi_size >> 10)))
goto bad_map;
if (!hash)
......
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