Whamcloud - gitweb
Branch b1_8
[fs/lustre-release.git] / lustre / kernel_patches / patches / raid6-stripe-by-stripe-handling.patch
1 diff -pur linux-2.6.9.orig/drivers/md/raid6main.c linux-2.6.9/drivers/md/raid6main.c
2 --- linux-2.6.9.orig/drivers/md/raid6main.c     2008-01-10 13:47:18.000000000 +0800
3 +++ linux-2.6.9/drivers/md/raid6main.c  2008-01-10 13:49:06.000000000 +0800
4 @@ -1571,6 +1571,11 @@ static int make_request (request_queue_t
5         sector_t new_sector;
6         sector_t logical_sector, last_sector;
7         struct stripe_head *sh;
8 +       sector_t stripe, sectors, block, r_sector, b_sector;
9 +       int sectors_per_chunk;
10 +       int stripes_per_chunk, sectors_per_block;
11 +       int sectors_per_stripe;
12 +       int i, j;
13  
14         atomic_inc(&conf->in_reqs_in_queue);
15  
16 @@ -1596,30 +1601,69 @@ static int make_request (request_queue_t
17         bi->bi_phys_segments = 1;       /* over-loaded to count active stripes */
18         if ( bio_data_dir(bi) == WRITE )
19                 md_write_start(mddev);
20 -       for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) {
21  
22 -               new_sector = raid6_compute_sector(logical_sector,
23 -                                                 raid_disks, data_disks, &dd_idx, &pd_idx, conf);
24 -
25 -               PRINTK("raid6: make_request, sector %Lu logical %Lu\n",
26 -                      (unsigned long long)new_sector,
27 -                      (unsigned long long)logical_sector);
28 +       sectors_per_chunk = conf->chunk_size >> 9;
29 +       stripes_per_chunk = conf->chunk_size / STRIPE_SIZE;
30 +       sectors_per_stripe = STRIPE_SECTORS * data_disks;
31 +       sectors_per_block = stripes_per_chunk * sectors_per_stripe;
32
33 +       block = logical_sector & ~((sector_t)sectors_per_block - 1);
34 +       sector_div(block, sectors_per_block);
35 +       sectors = bi->bi_size >> 9;
36
37 + repeat:
38 +       stripe = block * (sectors_per_block / data_disks);
39 +       b_sector = stripe * data_disks;
40 +       /* iterate through all stripes in this block,
41 +        * where block is a set of internal stripes
42 +        * which covers chunk */
43 +       for (i = 0; i < stripes_per_chunk && sectors > 0; i++) {
44 +               r_sector = b_sector + (i * STRIPE_SECTORS);
45 +               sh = NULL;
46 +               /* iterrate through all pages in the stripe */
47 +               for (j = 0; j < data_disks && sectors > 0; j++) {
48 +                       if (r_sector + STRIPE_SECTORS <= bi->bi_sector ||
49 +                           r_sector >= last_sector) {
50 +                               r_sector += sectors_per_chunk;
51 +                               continue;
52 +                       }
53 +                       new_sector = raid6_compute_sector(r_sector, raid_disks,
54 +                                                       data_disks, &dd_idx, 
55 +                                                       &pd_idx, conf);
56 +                       if (sh == NULL)
57 +                               sh = get_active_stripe(conf, new_sector, pd_idx,
58 +                                                       (bi->bi_rw&RWA_MASK));
59 +                       if (sh) {
60 +                               add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK));
61 +                       } else {
62 +                               /* cannot get stripe for read-ahead, just give-up */
63 +                               clear_bit(BIO_UPTODATE, &bi->bi_flags);
64 +                               sectors = 0;
65 +                               break;
66 +                       }
67
68 +                       BUG_ON (new_sector != stripe);
69 +                       sectors -= STRIPE_SECTORS;
70 +                       if (bi->bi_sector > r_sector)
71 +                               sectors += bi->bi_sector - r_sector;
72 +                       if (r_sector + STRIPE_SECTORS > last_sector)
73 +                               sectors += r_sector + STRIPE_SECTORS - last_sector;
74 +                       r_sector += sectors_per_chunk;
75 +               }
76  
77 -               sh = get_active_stripe(conf, new_sector, pd_idx, (bi->bi_rw&RWA_MASK));
78                 if (sh) {
79 -
80 -                       add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK));
81 -
82                         raid6_plug_device(conf);
83                         handle_stripe(sh);
84                         release_stripe(sh);
85 -               } else {
86 -                       /* cannot get stripe for read-ahead, just give-up */
87 -                       clear_bit(BIO_UPTODATE, &bi->bi_flags);
88 -                       break;
89 +                       sh = NULL;
90                 }
91  
92 +               stripe += STRIPE_SECTORS;
93         }
94 +       block++;
95 +       if(sectors > 0)
96 +               goto repeat;
97 +
98         spin_lock_irq(&conf->device_lock);
99         if (--bi->bi_phys_segments == 0) {
100                 int bytes = bi->bi_size;