1 diff -pur linux-2.6.9-67.orig/drivers/md/raid5.c linux-2.6.9-67/drivers/md/raid5.c
2 --- linux-2.6.9-67.orig/drivers/md/raid5.c 2009-02-20 16:06:12.000000000 +0800
3 +++ linux-2.6.9-67/drivers/md/raid5.c 2009-02-20 16:06:37.000000000 +0800
4 @@ -852,6 +852,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 raid5_flush_bios(raid5_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 @@ -871,7 +891,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 raid5_conf_t *conf = sh->raid_conf;
39 int disks = conf->raid_disks;
40 @@ -1291,7 +1311,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 @@ -1416,6 +1440,7 @@ static int make_request (request_queue_t
54 int sectors_per_chunk = conf->chunk_size >> 9;
55 int stripes_per_chunk, sectors_per_block;
56 int sectors_per_stripe;
57 + struct bio *bios[MD_SB_DISKS];
60 if (unlikely(bio_barrier(bi))) {
61 @@ -1450,6 +1475,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 @@ -1469,9 +1495,17 @@ repeat:
70 new_sector = raid5_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 + raid5_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 @@ -1491,7 +1525,7 @@ repeat:
93 raid5_plug_device(conf);
95 + handle_stripe(sh, bios);
99 @@ -1501,6 +1535,9 @@ repeat:
103 + /* now flush all bio's */
104 + raid5_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 @@ -1556,7 +1593,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 @@ -1605,9 +1642,11 @@ static void raid5d (mddev_t *mddev)
121 atomic_inc(&conf->handled_in_raid5d);
123 + handle_stripe(sh, NULL);
128 spin_lock_irq(&conf->device_lock);
130 PRINTK("%d stripes handled\n", handled);