📄 raid5-merge-ios.patch
字号:
Merge IO requests to try and get larger requests on underlying drives.Index: linux-2.6.9/drivers/md/raid5.c===================================================================--- linux-2.6.9.orig/drivers/md/raid5.c 2006-05-22 00:10:04.000000000 +0400+++ linux-2.6.9/drivers/md/raid5.c 2006-05-22 00:10:06.000000000 +0400@@ -934,6 +934,26 @@ static void add_stripe_bio (struct strip } } +/*+ * The whole idea is to collect all bio's and then issue them+ * disk by disk to assist merging a bit -bzzz+ */+static void raid5_flush_bios(raid5_conf_t *conf, struct bio *bios[], int raid_disks)+{+ struct bio *bio, *nbio;+ int i;++ for (i = 0; i < raid_disks; i++) {+ bio = bios[i];+ while (bio) {+ nbio = bio->bi_next;+ bio->bi_next = NULL;+ generic_make_request(bio);+ bio = nbio;+ }+ bios[i] = NULL;+ }+} /* * handle_stripe - do things to a stripe.@@ -953,7 +973,7 @@ static void add_stripe_bio (struct strip * */ -static void handle_stripe(struct stripe_head *sh)+static void handle_stripe(struct stripe_head *sh, struct bio *bios[]) { raid5_conf_t *conf = sh->raid_conf; int disks = conf->raid_disks;@@ -1376,7 +1396,11 @@ static void handle_stripe(struct stripe_ bi->bi_size = STRIPE_SIZE; bi->bi_next = NULL; atomic_inc(&conf->out_reqs_in_queue);- generic_make_request(bi);+ if (bios) {+ bi->bi_next = bios[i];+ bios[i] = bi;+ } else+ generic_make_request(bi); } else { PRINTK("skip op %ld on disc %d for sector %llu\n", bi->bi_rw, i, (unsigned long long)sh->sector);@@ -1501,6 +1525,7 @@ static int make_request (request_queue_t int sectors_per_chunk = conf->chunk_size >> 9; int stripes_per_chunk, sectors_per_block; int sectors_per_stripe;+ struct bio *bios[MD_SB_DISKS]; int i, j; atomic_inc(&conf->in_reqs_in_queue);@@ -1530,6 +1555,7 @@ static int make_request (request_queue_t sector_div(block, sectors_per_block); sectors = bi->bi_size >> 9; + memset(&bios, 0, sizeof(bios)); repeat: stripe = block * sectors_per_block / data_disks; b_sector = stripe * data_disks;@@ -1549,9 +1575,17 @@ repeat: new_sector = raid5_compute_sector(r_sector, raid_disks, data_disks, &dd_idx, &pd_idx, conf);- if (sh == NULL)- sh = get_active_stripe(conf, new_sector, pd_idx,- (bi->bi_rw&RWA_MASK));+ if (sh == NULL) {+ /* first, try to get stripe w/o blocking+ * if we can't, then it's time to submit+ * all collected bio's in order to free+ * some space in the cache -bzzz */+ sh = get_active_stripe(conf, new_sector, pd_idx, 1);+ if (!sh && !(bi->bi_rw&RWA_MASK)) {+ raid5_flush_bios(conf, bios, raid_disks);+ sh = get_active_stripe(conf, new_sector, pd_idx, 0);+ }+ } if (sh) { add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK)); } else {@@ -1571,7 +1605,7 @@ repeat: } if (sh) { raid5_plug_device(conf);- handle_stripe(sh);+ handle_stripe(sh, bios); release_stripe(sh); sh = NULL; }@@ -1581,6 +1615,9 @@ repeat: if (sectors > 0) goto repeat; + /* now flush all bio's */+ raid5_flush_bios(conf, bios, raid_disks);+ spin_lock_irq(&conf->device_lock); if (--bi->bi_phys_segments == 0) { int bytes = bi->bi_size;@@ -1636,7 +1673,7 @@ static int sync_request (mddev_t *mddev, clear_bit(STRIPE_INSYNC, &sh->state); spin_unlock(&sh->lock); - handle_stripe(sh);+ handle_stripe(sh, NULL); release_stripe(sh); return STRIPE_SECTORS;@@ -1685,7 +1722,7 @@ static void raid5d (mddev_t *mddev) handled++; atomic_inc(&conf->handled_in_raid5d);- handle_stripe(sh);+ handle_stripe(sh, NULL); release_stripe(sh); spin_lock_irq(&conf->device_lock);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -