Whamcloud - gitweb
decf7a45cdb9a19f6c6d88efe0866728c1c80692
[fs/lustre-release.git] / lustre / kernel_patches / patches / raid5-merge-ios-rhel5.patch
1 Index: linux-2.6.18-92.1.17/drivers/md/raid5.c
2 ===================================================================
3 --- linux-2.6.18-92.1.17.orig/drivers/md/raid5.c
4 +++ linux-2.6.18-92.1.17/drivers/md/raid5.c
5 @@ -1277,7 +1277,26 @@ static void compute_block_2(struct strip
6         }
7  }
8  
9 +/*
10 + * The whole idea is to collect all bio's and then issue them
11 + * disk by disk to assist merging a bit -bzzz
12 + */
13 +static void raid5_flush_bios(raid5_conf_t *conf, struct bio *bios[], int raid_disks)
14 +{
15 +       struct bio *bio, *nbio;
16 +       int i;
17  
18 +       for (i = 0; i < raid_disks; i++) {
19 +               bio = bios[i];
20 +               while (bio) {
21 +                       nbio = bio->bi_next;
22 +                       bio->bi_next = NULL;
23 +                       generic_make_request(bio);
24 +                       bio = nbio;
25 +               }
26 +               bios[i] = NULL;
27 +       }
28 +}
29  
30  /*
31   * Each stripe/dev can have one or more bion attached.
32 @@ -1392,7 +1411,7 @@ static int stripe_to_pdidx(sector_t stri
33   *
34   */
35   
36 -static void handle_stripe5(struct stripe_head *sh)
37 +static void handle_stripe5(struct stripe_head *sh, struct bio *bios[])
38  {
39         raid5_conf_t *conf = sh->raid_conf;
40         int disks = sh->disks;
41 @@ -1939,7 +1958,11 @@ static void handle_stripe5(struct stripe
42                             test_bit(R5_ReWrite, &sh->dev[i].flags))
43                                 atomic_add(STRIPE_SECTORS, &rdev->corrected_errors);
44                         atomic_inc(&conf->out_reqs_in_queue);
45 -                       generic_make_request(bi);
46 +                       if (bios) {
47 +                               bi->bi_next = bios[i];
48 +                               bios[i] = bi;
49 +                       } else
50 +                               generic_make_request(bi);
51                 } else {
52                         if (rw == 1)
53                                 set_bit(STRIPE_DEGRADED, &sh->state);
54 @@ -1951,7 +1974,7 @@ static void handle_stripe5(struct stripe
55         }
56  }
57  
58 -static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page)
59 +static void handle_stripe6(struct stripe_head *sh, struct page *tmp_page, struct bio *bios[])
60  {
61         raid6_conf_t *conf = sh->raid_conf;
62         int disks = conf->raid_disks;
63 @@ -2499,7 +2522,11 @@ static void handle_stripe6(struct stripe
64                         if (rw == WRITE &&
65                             test_bit(R5_ReWrite, &sh->dev[i].flags))
66                                 atomic_add(STRIPE_SECTORS, &rdev->corrected_errors);
67 -                       generic_make_request(bi);
68 +                       if (bios) {
69 +                               bi->bi_next = bios[i];
70 +                               bios[i] = bi;
71 +                       } else
72 +                               generic_make_request(bi);
73                         atomic_inc(&conf->out_reqs_in_queue);
74                 } else {
75                         if (rw == 1)
76 @@ -2512,12 +2539,12 @@ static void handle_stripe6(struct stripe
77         }
78  }
79  
80 -static void handle_stripe(struct stripe_head *sh, struct page *tmp_page)
81 +static void handle_stripe(struct stripe_head *sh, struct page *tmp_page, struct bio *bios[])
82  {
83         if (sh->raid_conf->level == 6)
84 -               handle_stripe6(sh, tmp_page);
85 +               handle_stripe6(sh, tmp_page, bios);
86         else
87 -               handle_stripe5(sh);
88 +               handle_stripe5(sh, bios);
89  }
90  
91  
92 @@ -2670,6 +2697,7 @@ static int make_request(request_queue_t 
93         int stripes_per_chunk, sectors_per_block;
94         int sectors_per_stripe;
95         int i, j;
96 +       struct bio *bios[MD_SB_DISKS];
97  
98         DEFINE_WAIT(w);
99         int disks, data_disks;
100 @@ -2698,6 +2726,7 @@ static int make_request(request_queue_t 
101         sectors = bi->bi_size >> 9;
102         stripes_per_chunk = conf->chunk_size / STRIPE_SIZE;
103  
104 +       memset(&bios, 0, sizeof(bios));
105  redo_bio:
106         /* stripe by stripe handle needs a stable raid layout, so if this
107          * reuqest covers the expanding region, wait it over. 
108 @@ -2756,8 +2785,10 @@ retry:
109                                          * the raid layout has been changed, we have to redo the 
110                                          * whole bio because we don't which sectors in it has been
111                                          * done, and which is not done. -jay */
112 -                                       if (raid5_redo_bio(conf, bi, disks, logical_sector))
113 +                                       if (raid5_redo_bio(conf, bi, disks, logical_sector)) {
114 +                                               raid5_flush_bios(conf, bios, disks);
115                                                 goto redo_bio;
116 +                                       }
117  
118                                         if (test_bit(STRIPE_EXPANDING, &sh->state)) {
119                                                 /* Stripe is busy expanding or
120 @@ -2766,6 +2797,7 @@ retry:
121                                                  */
122                                                 release_stripe(sh);
123                                                 sh = NULL;
124 +                                               raid5_flush_bios(conf, bios, disks);
125                                                 raid5_unplug_device(mddev->queue);
126                                                 schedule();
127                                                 goto retry;
128 @@ -2784,17 +2816,19 @@ retry:
129                          */
130                         if (r_sector >= mddev->suspend_lo &&
131                             r_sector < mddev->suspend_hi) {
132 -                               handle_stripe(sh, NULL);
133 +                               handle_stripe(sh, NULL, NULL);
134                                 release_stripe(sh);
135                                 sh = NULL;
136 +                               raid5_flush_bios(conf, bios, disks);
137                                 schedule();
138                                 goto retry;
139                         }
140  
141                         if (!add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK))) {
142 -                               handle_stripe(sh, NULL);
143 +                               handle_stripe(sh, NULL, NULL);
144                                 release_stripe(sh);
145                                 sh = NULL;
146 +                               raid5_flush_bios(conf, bios, disks);
147                                 raid5_unplug_device(mddev->queue);
148                                 schedule();
149                                 goto retry;
150 @@ -2810,7 +2844,7 @@ retry:
151                         r_sector += sectors_per_chunk;
152                 }
153                 if (sh) {
154 -                       handle_stripe(sh, NULL);
155 +                       handle_stripe(sh, NULL, bios);
156                         release_stripe(sh);
157                         sh = NULL;
158                 }
159 @@ -2820,6 +2854,9 @@ retry:
160         if (sectors > 0)
161                 goto repeat;
162  
163 +       /* flush all of the bios */
164 +       raid5_flush_bios(conf, bios, disks);
165 +
166         spin_lock_irq(&conf->device_lock);
167         remaining = --bi->bi_phys_segments;
168         spin_unlock_irq(&conf->device_lock);
169 @@ -3035,7 +3072,7 @@ static inline sector_t sync_request(mdde
170         clear_bit(STRIPE_INSYNC, &sh->state);
171         spin_unlock(&sh->lock);
172  
173 -       handle_stripe(sh, NULL);
174 +       handle_stripe(sh, NULL, NULL);
175         release_stripe(sh);
176  
177         return STRIPE_SECTORS;
178 @@ -3091,7 +3128,7 @@ static void raid5d (mddev_t *mddev)
179                 
180                 handled++;
181                 atomic_inc(&conf->handled_in_raid5d);
182 -               handle_stripe(sh, conf->spare_page);
183 +               handle_stripe(sh, conf->spare_page, NULL);
184                 release_stripe(sh);
185  
186                 spin_lock_irq(&conf->device_lock);