This file is indexed.

/usr/src/kernel-patches/lustre/patches/raid5-stripe-by-stripe-handling.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
Helps to avoid unnesessary reads if request covers full stripe.

Note that reads needed to update parity hurt performance badly

Index: linux-2.6.9/drivers/md/raid5.c
===================================================================
--- linux-2.6.9.orig/drivers/md/raid5.c	2006-05-22 00:09:56.000000000 +0400
+++ linux-2.6.9/drivers/md/raid5.c	2006-05-22 00:10:01.000000000 +0400
@@ -1412,6 +1412,11 @@ static int make_request (request_queue_t
 	sector_t new_sector;
 	sector_t logical_sector, last_sector;
 	struct stripe_head *sh;
+	sector_t stripe, sectors, block, r_sector, b_sector;
+	int sectors_per_chunk = conf->chunk_size >> 9;
+	int stripes_per_chunk, sectors_per_block;
+	int sectors_per_stripe;
+	int i, j;
 
 	atomic_inc(&conf->in_reqs_in_queue);
 
@@ -1431,30 +1436,66 @@ static int make_request (request_queue_t
 	bi->bi_phys_segments = 1;	/* over-loaded to count active stripes */
 	if ( bio_data_dir(bi) == WRITE )
 		md_write_start(mddev);
-	for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) {
-		
-		new_sector = raid5_compute_sector(logical_sector,
-						  raid_disks, data_disks, &dd_idx, &pd_idx, conf);
-
-		PRINTK("raid5: make_request, sector %Lu logical %Lu\n",
-			(unsigned long long)new_sector, 
-			(unsigned long long)logical_sector);
 
-		sh = get_active_stripe(conf, new_sector, pd_idx, (bi->bi_rw&RWA_MASK));
+	stripes_per_chunk = conf->chunk_size / STRIPE_SIZE;
+	sectors_per_stripe = STRIPE_SECTORS * data_disks;
+	sectors_per_block = stripes_per_chunk * sectors_per_stripe;
+
+	block = logical_sector & ~((sector_t)sectors_per_block - 1);
+	sector_div(block, sectors_per_block);
+	sectors = bi->bi_size >> 9;
+
+repeat:
+	stripe = block * (sectors_per_block / data_disks);
+	b_sector = stripe * data_disks;
+	/* iterate through all stripes in this block,
+	 * where block is a set of internal stripes
+	 * which covers chunk */
+	for (i = 0; i < stripes_per_chunk && sectors > 0; i++) {
+		r_sector = b_sector + (i * STRIPE_SECTORS);
+		sh = NULL;
+		/* iterrate through all pages in the stripe */
+		for (j = 0; j < data_disks && sectors > 0; j++) {
+			if (r_sector + STRIPE_SECTORS <= bi->bi_sector ||
+					r_sector >= last_sector) {
+				r_sector += sectors_per_chunk;
+				continue;
+			}
+			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) {
+				add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK));
+			} else {
+				/* cannot get stripe for read-ahead, just give-up */
+				clear_bit(BIO_UPTODATE, &bi->bi_flags);
+				sectors = 0;
+				break;
+			}
+
+			BUG_ON (new_sector != stripe);
+			sectors -= STRIPE_SECTORS;
+			if (bi->bi_sector > r_sector)
+				sectors += bi->bi_sector - r_sector;
+			if (r_sector + STRIPE_SECTORS > last_sector)
+				sectors += r_sector + STRIPE_SECTORS - last_sector;
+			r_sector += sectors_per_chunk;
+		}
 		if (sh) {
-
-			add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK));
-
 			raid5_plug_device(conf);
 			handle_stripe(sh);
 			release_stripe(sh);
-		} else {
-			/* cannot get stripe for read-ahead, just give-up */
-			clear_bit(BIO_UPTODATE, &bi->bi_flags);
-			break;
+			sh = NULL;
 		}
-			
+		stripe += STRIPE_SECTORS;
 	}
+	block++; 
+	if (sectors > 0)
+		goto repeat;
+
 	spin_lock_irq(&conf->device_lock);
 	if (--bi->bi_phys_segments == 0) {
 		int bytes = bi->bi_size;