Whamcloud - gitweb
Branch b1_6
authoryangsheng <yangsheng>
Wed, 26 Dec 2007 03:27:27 +0000 (03:27 +0000)
committeryangsheng <yangsheng>
Wed, 26 Dec 2007 03:27:27 +0000 (03:27 +0000)
b=14288
i=jay
i=alex

Add a patch back the raid driver to 2.6.9-55.0.12.

lustre/kernel_patches/patches/rollback-raid5ch-to-55.patch [new file with mode: 0644]

diff --git a/lustre/kernel_patches/patches/rollback-raid5ch-to-55.patch b/lustre/kernel_patches/patches/rollback-raid5ch-to-55.patch
new file mode 100644 (file)
index 0000000..5c4eab5
--- /dev/null
@@ -0,0 +1,329 @@
+--- linux-2.6.9-67/drivers/md/raid5.c  2007-11-21 21:12:50.000000000 -0700
++++ linux-2.6.9-55.0.12/drivers/md/raid5.c     2007-11-02 01:10:35.000000000 -0700
+@@ -49,7 +49,7 @@
+  * This macro is used to determine the 'next' bio in the list, given the sector
+  * of the current stripe+device
+  */
+-#define r5_next_bio(bio, sect) ( ( (bio)->bi_sector + ((bio)->bi_size>>9) < sect + STRIPE_SECTORS) ? (bio)->bi_next : NULL)
++#define r5_next_bio(bio, sect) ( ( bio->bi_sector + (bio->bi_size>>9) < sect + STRIPE_SECTORS) ? bio->bi_next : NULL)
+ /*
+  * The following can be used to debug the driver
+  */
+@@ -232,7 +232,6 @@ static struct stripe_head *__find_stripe
+ }
+ static void unplug_slaves(mddev_t *mddev);
+-static void raid5_unplug_device(request_queue_t *q);
+ static struct stripe_head *get_active_stripe(raid5_conf_t *conf, sector_t sector,
+                                            int pd_idx, int noblock) 
+@@ -727,10 +726,6 @@ static void compute_parity(struct stripe
+                               ptr[count++] = page_address(sh->dev[i].page);
+                               chosen = sh->dev[i].towrite;
+                               sh->dev[i].towrite = NULL;
+-
+-                              if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
+-                                      wake_up(&conf->wait_for_overlap);
+-
+                               if (sh->dev[i].written) BUG();
+                               sh->dev[i].written = chosen;
+                               check_xor();
+@@ -743,10 +738,6 @@ static void compute_parity(struct stripe
+                       if (i!=pd_idx && sh->dev[i].towrite) {
+                               chosen = sh->dev[i].towrite;
+                               sh->dev[i].towrite = NULL;
+-
+-                              if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
+-                                      wake_up(&conf->wait_for_overlap);
+-
+                               if (sh->dev[i].written) BUG();
+                               sh->dev[i].written = chosen;
+                       }
+@@ -803,7 +794,7 @@ static void compute_parity(struct stripe
+  * toread/towrite point to the first in a chain. 
+  * The bi_next chain must be in order.
+  */
+-static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, int forwrite)
++static void add_stripe_bio (struct stripe_head *sh, struct bio *bi, int dd_idx, int forwrite)
+ {
+       struct bio **bip;
+       raid5_conf_t *conf = sh->raid_conf;
+@@ -820,13 +811,10 @@ static int add_stripe_bio(struct stripe_
+       else
+               bip = &sh->dev[dd_idx].toread;
+       while (*bip && (*bip)->bi_sector < bi->bi_sector) {
+-              if ((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector)
+-                      goto overlap;
++              BUG_ON((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector);
+               bip = & (*bip)->bi_next;
+       }
+-      if (*bip && (*bip)->bi_sector < bi->bi_sector + ((bi->bi_size)>>9))
+-              goto overlap;
+-
++/* FIXME do I need to worry about overlapping bion */
+       if (*bip && bi->bi_next && (*bip) != bi->bi_next)
+               BUG();
+       if (*bip)
+@@ -841,7 +829,7 @@ static int add_stripe_bio(struct stripe_
+               (unsigned long long)sh->sector, dd_idx);
+       if (forwrite) {
+-              /* check if page is covered */
++              /* check if page is coverred */
+               sector_t sector = sh->dev[dd_idx].sector;
+               for (bi=sh->dev[dd_idx].towrite;
+                    sector < sh->dev[dd_idx].sector + STRIPE_SECTORS &&
+@@ -853,13 +841,6 @@ static int add_stripe_bio(struct stripe_
+               if (sector >= sh->dev[dd_idx].sector + STRIPE_SECTORS)
+                       set_bit(R5_OVERWRITE, &sh->dev[dd_idx].flags);
+       }
+-      return 1;
+-
+- overlap:
+-      set_bit(R5_Overlap, &sh->dev[dd_idx].flags);
+-      spin_unlock_irq(&conf->device_lock);
+-      spin_unlock(&sh->lock);
+-      return 0;
+ }
+@@ -920,8 +901,6 @@ static void handle_stripe(struct stripe_
+                       spin_lock_irq(&conf->device_lock);
+                       rbi = dev->toread;
+                       dev->toread = NULL;
+-                      if (test_and_clear_bit(R5_Overlap, &dev->flags))
+-                              wake_up(&conf->wait_for_overlap);
+                       spin_unlock_irq(&conf->device_lock);
+                       while (rbi && rbi->bi_sector < dev->sector + STRIPE_SECTORS) {
+                               copy_data(0, rbi, dev->page, dev->sector);
+@@ -969,9 +948,6 @@ static void handle_stripe(struct stripe_
+                       sh->dev[i].towrite = NULL;
+                       if (bi) to_write--;
+-                      if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
+-                              wake_up(&conf->wait_for_overlap);
+-
+                       while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){
+                               struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector);
+                               clear_bit(BIO_UPTODATE, &bi->bi_flags);
+@@ -1000,8 +976,6 @@ static void handle_stripe(struct stripe_
+                       if (!test_bit(R5_Insync, &sh->dev[i].flags)) {
+                               bi = sh->dev[i].toread;
+                               sh->dev[i].toread = NULL;
+-                              if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
+-                                      wake_up(&conf->wait_for_overlap);
+                               if (bi) to_read--;
+                               while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){
+                                       struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector);
+@@ -1441,7 +1415,6 @@ static int make_request (request_queue_t
+       if ( bio_data_dir(bi) == WRITE )
+               md_write_start(mddev);
+       for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) {
+-              DEFINE_WAIT(w);
+               
+               new_sector = raid5_compute_sector(logical_sector,
+                                                 raid_disks, data_disks, &dd_idx, &pd_idx, conf);
+@@ -1450,28 +1423,17 @@ static int make_request (request_queue_t
+                       (unsigned long long)new_sector, 
+                       (unsigned long long)logical_sector);
+-      retry:
+-              prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE);
+               sh = get_active_stripe(conf, new_sector, pd_idx, (bi->bi_rw&RWA_MASK));
+               if (sh) {
+-                      if (!add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK))) {
+-                              /* Add failed due to overlap.  Flush everything
+-                               * and wait a while
+-                               */
+-                              raid5_unplug_device(mddev->queue);
+-                              release_stripe(sh);
+-                              schedule();
+-                              goto retry;
+-                      }
+-                      finish_wait(&conf->wait_for_overlap, &w);
++
++                      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);
+-                      finish_wait(&conf->wait_for_overlap, &w);
+                       break;
+               }
+                       
+@@ -1619,7 +1581,6 @@ static int run (mddev_t *mddev)
+       conf->device_lock = SPIN_LOCK_UNLOCKED;
+       init_waitqueue_head(&conf->wait_for_stripe);
+-      init_waitqueue_head(&conf->wait_for_overlap);
+       INIT_LIST_HEAD(&conf->handle_list);
+       INIT_LIST_HEAD(&conf->delayed_list);
+       INIT_LIST_HEAD(&conf->inactive_list);
+--- linux-2.6.9-67/include/linux/raid/raid5.h  2007-11-21 21:12:41.000000000 -0700
++++ linux-2.6.9-55.0.12/include/linux/raid/raid5.h     2004-10-18 15:54:55.000000000 -0600
+@@ -152,7 +152,6 @@ struct stripe_head {
+ #define       R5_Wantread     4       /* want to schedule a read */
+ #define       R5_Wantwrite    5
+ #define       R5_Syncio       6       /* this io need to be accounted as resync io */
+-#define       R5_Overlap      7       /* There is a pending overlapping request on this block */
+ /*
+  * Write method
+@@ -220,7 +219,6 @@ struct raid5_private_data {
+       atomic_t                active_stripes;
+       struct list_head        inactive_list;
+       wait_queue_head_t       wait_for_stripe;
+-      wait_queue_head_t       wait_for_overlap;
+       int                     inactive_blocked;       /* release of inactive stripes blocked,
+                                                        * waiting for 25% to be free
+                                                        */        
+--- linux-2.6.9-67/drivers/md/raid6main.c      2007-11-21 21:12:41.000000000 -0700
++++ linux-2.6.9-55.0.12/drivers/md/raid6main.c 2007-11-02 01:10:20.000000000 -0700
+@@ -54,7 +54,7 @@
+  * This macro is used to determine the 'next' bio in the list, given the sector
+  * of the current stripe+device
+  */
+-#define r5_next_bio(bio, sect) ( ( (bio)->bi_sector + ((bio)->bi_size>>9) < sect + STRIPE_SECTORS) ? (bio)->bi_next : NULL)
++#define r5_next_bio(bio, sect) ( ( bio->bi_sector + (bio->bi_size>>9) < sect + STRIPE_SECTORS) ? bio->bi_next : NULL)
+ /*
+  * The following can be used to debug the driver
+  */
+@@ -740,10 +740,6 @@ static void compute_parity(struct stripe
+                       if ( i != pd_idx && i != qd_idx && sh->dev[i].towrite ) {
+                               chosen = sh->dev[i].towrite;
+                               sh->dev[i].towrite = NULL;
+-
+-                              if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
+-                                      wake_up(&conf->wait_for_overlap);
+-
+                               if (sh->dev[i].written) BUG();
+                               sh->dev[i].written = chosen;
+                       }
+@@ -902,7 +898,7 @@ static void compute_block_2(struct strip
+  * toread/towrite point to the first in a chain.
+  * The bi_next chain must be in order.
+  */
+-static int add_stripe_bio(struct stripe_head *sh, struct bio *bi, int dd_idx, int forwrite)
++static void add_stripe_bio (struct stripe_head *sh, struct bio *bi, int dd_idx, int forwrite)
+ {
+       struct bio **bip;
+       raid6_conf_t *conf = sh->raid_conf;
+@@ -919,13 +915,10 @@ static int add_stripe_bio(struct stripe_
+       else
+               bip = &sh->dev[dd_idx].toread;
+       while (*bip && (*bip)->bi_sector < bi->bi_sector) {
+-              if ((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector)
+-                      goto overlap;
+-              bip = &(*bip)->bi_next;
++              BUG_ON((*bip)->bi_sector + ((*bip)->bi_size >> 9) > bi->bi_sector);
++              bip = & (*bip)->bi_next;
+       }
+-      if (*bip && (*bip)->bi_sector < bi->bi_sector + ((bi->bi_size)>>9))
+-              goto overlap;
+-
++/* FIXME do I need to worry about overlapping bion */
+       if (*bip && bi->bi_next && (*bip) != bi->bi_next)
+               BUG();
+       if (*bip)
+@@ -940,7 +933,7 @@ static int add_stripe_bio(struct stripe_
+               (unsigned long long)sh->sector, dd_idx);
+       if (forwrite) {
+-              /* check if page is covered */
++              /* check if page is coverred */
+               sector_t sector = sh->dev[dd_idx].sector;
+               for (bi=sh->dev[dd_idx].towrite;
+                    sector < sh->dev[dd_idx].sector + STRIPE_SECTORS &&
+@@ -952,13 +945,6 @@ static int add_stripe_bio(struct stripe_
+               if (sector >= sh->dev[dd_idx].sector + STRIPE_SECTORS)
+                       set_bit(R5_OVERWRITE, &sh->dev[dd_idx].flags);
+       }
+-      return 1;
+-
+- overlap:
+-      set_bit(R5_Overlap, &sh->dev[dd_idx].flags);
+-      spin_unlock_irq(&conf->device_lock);
+-      spin_unlock(&sh->lock);
+-      return 0;
+ }
+@@ -1022,8 +1008,6 @@ static void handle_stripe(struct stripe_
+                       spin_lock_irq(&conf->device_lock);
+                       rbi = dev->toread;
+                       dev->toread = NULL;
+-                      if (test_and_clear_bit(R5_Overlap, &dev->flags))
+-                              wake_up(&conf->wait_for_overlap);
+                       spin_unlock_irq(&conf->device_lock);
+                       while (rbi && rbi->bi_sector < dev->sector + STRIPE_SECTORS) {
+                               copy_data(0, rbi, dev->page, dev->sector);
+@@ -1073,9 +1057,6 @@ static void handle_stripe(struct stripe_
+                       sh->dev[i].towrite = NULL;
+                       if (bi) to_write--;
+-                      if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
+-                              wake_up(&conf->wait_for_overlap);
+-
+                       while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){
+                               struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector);
+                               clear_bit(BIO_UPTODATE, &bi->bi_flags);
+@@ -1104,8 +1085,6 @@ static void handle_stripe(struct stripe_
+                       if (!test_bit(R5_Insync, &sh->dev[i].flags)) {
+                               bi = sh->dev[i].toread;
+                               sh->dev[i].toread = NULL;
+-                              if (test_and_clear_bit(R5_Overlap, &sh->dev[i].flags))
+-                                      wake_up(&conf->wait_for_overlap);
+                               if (bi) to_read--;
+                               while (bi && bi->bi_sector < sh->dev[i].sector + STRIPE_SECTORS){
+                                       struct bio *nextbi = r5_next_bio(bi, sh->dev[i].sector);
+@@ -1597,7 +1576,6 @@ static int make_request (request_queue_t
+       if ( bio_data_dir(bi) == WRITE )
+               md_write_start(mddev);
+       for (;logical_sector < last_sector; logical_sector += STRIPE_SECTORS) {
+-              DEFINE_WAIT(w);
+               new_sector = raid6_compute_sector(logical_sector,
+                                                 raid_disks, data_disks, &dd_idx, &pd_idx, conf);
+@@ -1606,27 +1584,17 @@ static int make_request (request_queue_t
+                      (unsigned long long)new_sector,
+                      (unsigned long long)logical_sector);
+-      retry:
+-              prepare_to_wait(&conf->wait_for_overlap, &w, TASK_UNINTERRUPTIBLE);
+               sh = get_active_stripe(conf, new_sector, pd_idx, (bi->bi_rw&RWA_MASK));
+               if (sh) {
+-                      if (!add_stripe_bio(sh, bi, dd_idx, (bi->bi_rw&RW_MASK))) {
+-                              /* Add failed due to overlap.  Flush everything
+-                               * and wait a while
+-                               */
+-                              raid6_unplug_device(mddev->queue);
+-                              release_stripe(sh);
+-                              schedule();
+-                              goto retry;
+-                      }
+-                      finish_wait(&conf->wait_for_overlap, &w);
++
++                      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);
+-                      finish_wait(&conf->wait_for_overlap, &w);
+                       break;
+               }
+@@ -1774,7 +1742,6 @@ static int run (mddev_t *mddev)
+       conf->device_lock = SPIN_LOCK_UNLOCKED;
+       init_waitqueue_head(&conf->wait_for_stripe);
+-      init_waitqueue_head(&conf->wait_for_overlap);
+       INIT_LIST_HEAD(&conf->handle_list);
+       INIT_LIST_HEAD(&conf->delayed_list);
+       INIT_LIST_HEAD(&conf->inactive_list);