This file is indexed.

/usr/src/kernel-patches/lustre/patches/raid5-merge-ios.patch is in linux-patch-lustre 1.8.5+dfsg-3ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
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);