1 diff -pur linux-2.6.9.orig/drivers/md/raid6main.c linux-2.6.9/drivers/md/raid6main.c
2 --- linux-2.6.9.orig/drivers/md/raid6main.c 2008-01-10 13:47:18.000000000 +0800
3 +++ linux-2.6.9/drivers/md/raid6main.c 2008-01-10 13:49:06.000000000 +0800
4 @@ -1571,6 +1571,11 @@ static int make_request (request_queue_t
6 sector_t logical_sector, last_sector;
7 struct stripe_head *sh;
8 + sector_t stripe, sectors, block, r_sector, b_sector;
9 + int sectors_per_chunk;
10 + int stripes_per_chunk, sectors_per_block;
11 + int sectors_per_stripe;
14 atomic_inc(&conf->in_reqs_in_queue);
16 @@ -1596,30 +1601,69 @@ static int make_request (request_queue_t
17 bi->bi_phys_segments = 1; /* over-loaded to count active stripes */
18 if ( bio_data_dir(bi) == WRITE )
19 md_write_start(mddev);
20 - for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) {
22 - new_sector = raid6_compute_sector(logical_sector,
23 - raid_disks, data_disks, &dd_idx, &pd_idx, conf);
25 - PRINTK("raid6: make_request, sector %Lu logical %Lu\n",
26 - (unsigned long long)new_sector,
27 - (unsigned long long)logical_sector);
28 + sectors_per_chunk = conf->chunk_size >> 9;
29 + stripes_per_chunk = conf->chunk_size / STRIPE_SIZE;
30 + sectors_per_stripe = STRIPE_SECTORS * data_disks;
31 + sectors_per_block = stripes_per_chunk * sectors_per_stripe;
33 + block = logical_sector & ~((sector_t)sectors_per_block - 1);
34 + sector_div(block, sectors_per_block);
35 + sectors = bi->bi_size >> 9;
38 + stripe = block * (sectors_per_block / data_disks);
39 + b_sector = stripe * data_disks;
40 + /* iterate through all stripes in this block,
41 + * where block is a set of internal stripes
42 + * which covers chunk */
43 + for (i = 0; i < stripes_per_chunk && sectors > 0; i++) {
44 + r_sector = b_sector + (i * STRIPE_SECTORS);
46 + /* iterrate through all pages in the stripe */
47 + for (j = 0; j < data_disks && sectors > 0; j++) {
48 + if (r_sector + STRIPE_SECTORS <= bi->bi_sector ||
49 + r_sector >= last_sector) {
50 + r_sector += sectors_per_chunk;
53 + new_sector = raid6_compute_sector(r_sector, raid_disks,
54 + data_disks, &dd_idx,
57 + sh = get_active_stripe(conf, new_sector, pd_idx,
58 + (bi->bi_rw&RWA_MASK));
60 + add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK));
62 + /* cannot get stripe for read-ahead, just give-up */
63 + clear_bit(BIO_UPTODATE, &bi->bi_flags);
68 + BUG_ON (new_sector != stripe);
69 + sectors -= STRIPE_SECTORS;
70 + if (bi->bi_sector > r_sector)
71 + sectors += bi->bi_sector - r_sector;
72 + if (r_sector + STRIPE_SECTORS > last_sector)
73 + sectors += r_sector + STRIPE_SECTORS - last_sector;
74 + r_sector += sectors_per_chunk;
77 - sh = get_active_stripe(conf, new_sector, pd_idx, (bi->bi_rw&RWA_MASK));
80 - add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK));
82 raid6_plug_device(conf);
86 - /* cannot get stripe for read-ahead, just give-up */
87 - clear_bit(BIO_UPTODATE, &bi->bi_flags);
92 + stripe += STRIPE_SECTORS;
98 spin_lock_irq(&conf->device_lock);
99 if (--bi->bi_phys_segments == 0) {
100 int bytes = bi->bi_size;