/usr/src/kernel-patches/lustre/patches/raid6-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 | diff -pur linux-2.6.9.orig/drivers/md/raid6main.c linux-2.6.9/drivers/md/raid6main.c
--- linux-2.6.9.orig/drivers/md/raid6main.c 2008-01-10 13:47:18.000000000 +0800
+++ linux-2.6.9/drivers/md/raid6main.c 2008-01-10 13:49:06.000000000 +0800
@@ -1571,6 +1571,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;
+ int stripes_per_chunk, sectors_per_block;
+ int sectors_per_stripe;
+ int i, j;
atomic_inc(&conf->in_reqs_in_queue);
@@ -1596,30 +1601,69 @@ 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 = raid6_compute_sector(logical_sector,
- raid_disks, data_disks, &dd_idx, &pd_idx, conf);
-
- PRINTK("raid6: make_request, sector %Lu logical %Lu\n",
- (unsigned long long)new_sector,
- (unsigned long long)logical_sector);
+ sectors_per_chunk = conf->chunk_size >> 9;
+ 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 = raid6_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;
+ }
- 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));
-
raid6_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;
|