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:51:32.000000000 +0800
3 +++ linux-2.6.9/drivers/md/raid6main.c 2008-01-10 13:52:20.000000000 +0800
4 @@ -956,6 +956,26 @@ static void add_stripe_bio (struct strip
9 + * The whole idea is to collect all bio's and then issue them
10 + * disk by disk to assist merging a bit -bzzz
12 +static void raid6_flush_bios(raid6_conf_t *conf, struct bio *bios[], int raid_disks)
14 + struct bio *bio, *nbio;
17 + for (i = 0; i < raid_disks; i++) {
20 + nbio = bio->bi_next;
21 + bio->bi_next = NULL;
22 + generic_make_request(bio);
30 * handle_stripe - do things to a stripe.
31 @@ -975,7 +995,7 @@ static void add_stripe_bio (struct strip
35 -static void handle_stripe(struct stripe_head *sh)
36 +static void handle_stripe(struct stripe_head *sh, struct bio *bios[])
38 raid6_conf_t *conf = sh->raid_conf;
39 int disks = conf->raid_disks;
40 @@ -1452,7 +1472,11 @@ static void handle_stripe(struct stripe_
41 bi->bi_size = STRIPE_SIZE;
43 atomic_inc(&conf->out_reqs_in_queue);
44 - generic_make_request(bi);
46 + bi->bi_next = bios[i];
49 + generic_make_request(bi);
51 PRINTK("skip op %ld on disc %d for sector %llu\n",
52 bi->bi_rw, i, (unsigned long long)sh->sector);
53 @@ -1575,6 +1599,7 @@ static int make_request (request_queue_t
54 int sectors_per_chunk;
55 int stripes_per_chunk, sectors_per_block;
56 int sectors_per_stripe;
57 + struct bio *bios[MD_SB_DISKS];
60 atomic_inc(&conf->in_reqs_in_queue);
61 @@ -1611,6 +1636,7 @@ static int make_request (request_queue_t
62 sector_div(block, sectors_per_block);
63 sectors = bi->bi_size >> 9;
65 + memset(&bios, 0, sizeof(bios));
67 stripe = block * (sectors_per_block / data_disks);
68 b_sector = stripe * data_disks;
69 @@ -1630,9 +1656,17 @@ static int make_request (request_queue_t
70 new_sector = raid6_compute_sector(r_sector, raid_disks,
74 - sh = get_active_stripe(conf, new_sector, pd_idx,
75 - (bi->bi_rw&RWA_MASK));
77 + /* first, try to get stripe w/o blocking
78 + * if we can't, then it's time to submit
79 + * all collected bio's in order to free
80 + * some space in the cache -bzzz */
81 + sh = get_active_stripe(conf, new_sector, pd_idx, 1);
82 + if (!sh && !(bi->bi_rw&RWA_MASK)) {
83 + raid6_flush_bios(conf, bios, raid_disks);
84 + sh = get_active_stripe(conf, new_sector, pd_idx, 0);
88 add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK));
90 @@ -1653,7 +1687,7 @@ static int make_request (request_queue_t
93 raid6_plug_device(conf);
95 + handle_stripe(sh, bios);
99 @@ -1664,6 +1698,9 @@ static int make_request (request_queue_t
103 + /* now flush all bio's */
104 + raid6_flush_bios(conf, bios, raid_disks);
106 spin_lock_irq(&conf->device_lock);
107 if (--bi->bi_phys_segments == 0) {
108 int bytes = bi->bi_size;
109 @@ -1719,7 +1756,7 @@ static int sync_request (mddev_t *mddev,
110 clear_bit(STRIPE_INSYNC, &sh->state);
111 spin_unlock(&sh->lock);
114 + handle_stripe(sh, NULL);
117 return STRIPE_SECTORS;
118 @@ -1769,7 +1806,7 @@ static void raid6d (mddev_t *mddev)
121 atomic_inc(&conf->handled_in_raid5d);
123 + handle_stripe(sh, NULL);
126 spin_lock_irq(&conf->device_lock);