Whamcloud - gitweb
b=15428
authorjxiong <jxiong>
Sun, 15 Feb 2009 02:38:40 +0000 (02:38 +0000)
committerjxiong <jxiong>
Sun, 15 Feb 2009 02:38:40 +0000 (02:38 +0000)
r=adilger

Fixed a crash issue for raid5-zerocopy

lustre/kernel_patches/patches/raid5-zerocopy.patch

index 0986343..f3c1e04 100644 (file)
@@ -1,15 +1,17 @@
-diff -pru linux-2.6.9.orig/drivers/md/raid5.c linux-2.6.9/drivers/md/raid5.c
---- linux-2.6.9.orig/drivers/md/raid5.c        2007-07-09 02:43:33.000000000 -0600
-+++ linux-2.6.9/drivers/md/raid5.c     2007-07-13 00:39:15.000000000 -0600
-@@ -412,6 +412,7 @@ static int raid5_end_read_request (struc
+diff -pur linux-2.6.9-67.orig/drivers/md/raid5.c linux-2.6.9-67/drivers/md/raid5.c
+--- linux-2.6.9-67.orig/drivers/md/raid5.c     2009-02-15 10:11:54.000000000 +0800
++++ linux-2.6.9-67/drivers/md/raid5.c  2009-02-15 10:22:51.000000000 +0800
+@@ -412,6 +412,9 @@ static int raid5_end_read_request (struc
                clear_buffer_uptodate(bh);
        }
  #endif
-+      BUG_ON(test_bit(R5_Direct, &sh->dev[i].flags));
++      /* Read on a Directing write is allowable */
++      /* BUG_ON(test_bit(R5_Direct, &sh->dev[i].flags)) */
++      BUG_ON(sh->dev[i].req.bi_io_vec[0].bv_page != sh->dev[i].page);
        clear_bit(R5_LOCKED, &sh->dev[i].flags);
        set_bit(STRIPE_HANDLE, &sh->state);
        release_stripe(sh);
-@@ -450,6 +451,10 @@ static int raid5_end_write_request (stru
+@@ -450,6 +453,10 @@ static int raid5_end_write_request (stru
  
        rdev_dec_pending(conf->disks[i].rdev, conf->mddev);
        
@@ -20,33 +22,35 @@ diff -pru linux-2.6.9.orig/drivers/md/raid5.c linux-2.6.9/drivers/md/raid5.c
        clear_bit(R5_LOCKED, &sh->dev[i].flags);
        set_bit(STRIPE_HANDLE, &sh->state);
        __release_stripe(conf, sh);
-@@ -621,6 +626,25 @@ static sector_t compute_blocknr(struct s
+@@ -620,7 +627,27 @@ static sector_t compute_blocknr(struct s
+       return r_sector;
  }
  
 +static struct page *zero_copy_data(struct bio *bio, sector_t sector)
 +{
 +      sector_t bi_sector = bio->bi_sector;
-+      struct page *page;
++      struct page *page = NULL;
 +      struct bio_vec *bvl;
 +      int i;
-+
 +      bio_for_each_segment(bvl, bio, i) {
-+              if (sector > bi_sector) {
-+                      bi_sector += bio_iovec_idx(bio, i)->bv_len >> 9;
-+                      continue;
++              if (sector == bi_sector)
++                      page = bio_iovec_idx(bio, i)->bv_page;
++              bi_sector += bio_iovec_idx(bio, i)->bv_len >> 9;
++              if (bi_sector >= sector + STRIPE_SECTORS) {
++                      /* check if the stripe is covered by one page */
++                      if (page == bio_iovec_idx(bio, i)->bv_page &&
++                          PageConstant(page))
++                              return page;
++                      return NULL;
 +              }
-+              BUG_ON(sector != bi_sector);
-+              page = bio_iovec_idx(bio, i)->bv_page;
-+              return PageConstant(page) ? page : NULL;
 +      }
-+      BUG();
 +      return NULL;
 +}
  
  /*
   * Copy data between a page in the stripe cache, and one or more bion
-@@ -716,8 +740,9 @@ static void compute_parity(struct stripe
+@@ -716,8 +743,9 @@ static void compute_parity(struct stripe
  {
        raid5_conf_t *conf = sh->raid_conf;
        int i, pd_idx = sh->pd_idx, disks = conf->raid_disks, count;
@@ -57,7 +61,7 @@ diff -pru linux-2.6.9.orig/drivers/md/raid5.c linux-2.6.9/drivers/md/raid5.c
  
        PRINTK("compute_parity, stripe %llu, method %d\n",
                (unsigned long long)sh->sector, method);
-@@ -744,13 +769,14 @@ static void compute_parity(struct stripe
+@@ -744,13 +772,14 @@ static void compute_parity(struct stripe
                break;
        case RECONSTRUCT_WRITE:
                memset(ptr[0], 0, STRIPE_SIZE);
@@ -73,7 +77,7 @@ diff -pru linux-2.6.9.orig/drivers/md/raid5.c linux-2.6.9/drivers/md/raid5.c
                break;
        case CHECK_PARITY:
                break;
-@@ -760,34 +786,88 @@ static void compute_parity(struct stripe
+@@ -760,34 +789,90 @@ static void compute_parity(struct stripe
                count = 1;
        }
        
@@ -103,6 +107,8 @@ diff -pru linux-2.6.9.orig/drivers/md/raid5.c linux-2.6.9/drivers/md/raid5.c
 +                      page = zero_copy_data(wbi, sector);
 +                      if (page) {
 +                              atomic_inc(&conf->writes_zcopy);
++                              /* The pointer must be restored whenever the LOCKED
++                               * gets cleared. */
 +                              sh->dev[i].req.bi_io_vec[0].bv_page = page;
 +                              set_bit(R5_Direct, &sh->dev[i].flags);
 +                              clear_bit(R5_UPTODATE, &sh->dev[i].flags);
@@ -114,7 +120,7 @@ diff -pru linux-2.6.9.orig/drivers/md/raid5.c linux-2.6.9/drivers/md/raid5.c
 -                      set_bit(R5_LOCKED, &sh->dev[i].flags);
 -                      set_bit(R5_UPTODATE, &sh->dev[i].flags);
 +              atomic_inc(&conf->writes_copied);
-+              test_and_clear_bit(R5_OVERWRITE, &sh->dev[i].flags);
++              clear_bit(R5_OVERWRITE, &sh->dev[i].flags);
 +              set_bit(R5_UPTODATE, &sh->dev[i].flags);
 +              while (wbi && wbi->bi_sector < sector + STRIPE_SECTORS) {
 +                      copy_data(1, wbi, sh->dev[i].page, sector);
@@ -179,7 +185,7 @@ diff -pru linux-2.6.9.orig/drivers/md/raid5.c linux-2.6.9/drivers/md/raid5.c
        }
        if (count != 1)
                xor_block(count, STRIPE_SIZE, ptr);
-@@ -1059,13 +1139,15 @@ static void handle_stripe(struct stripe_
+@@ -1061,13 +1146,15 @@ static void handle_stripe(struct stripe_
                if (sh->dev[i].written) {
                    dev = &sh->dev[i];
                    if (!test_bit(R5_LOCKED, &dev->flags) &&
@@ -192,11 +198,27 @@ diff -pru linux-2.6.9.orig/drivers/md/raid5.c linux-2.6.9/drivers/md/raid5.c
                            spin_lock_irq(&conf->device_lock);
                            wbi = dev->written;
                            dev->written = NULL;
-+                          test_and_clear_bit(R5_Direct, &dev->flags);
++                          clear_bit(R5_Direct, &dev->flags);
                            while (wbi && wbi->bi_sector < dev->sector + STRIPE_SECTORS) {
                                    wbi2 = r5_next_bio(wbi, dev->sector);
                                    if (--wbi->bi_phys_segments == 0) {
-@@ -1831,6 +1913,7 @@ memory = conf->max_nr_stripes * (sizeof(
+@@ -1337,6 +1424,15 @@ static void handle_stripe(struct stripe_
+               } else {
+                       PRINTK("skip op %ld on disc %d for sector %llu\n",
+                               bi->bi_rw, i, (unsigned long long)sh->sector);
++
++                      if (test_bit(R5_Direct, &sh->dev[i].flags)) {
++                              /* restore the page pointer of req, otherwise,
++                               * no any read is permitted on this stripe, this is
++                               * not what we want. -jay */
++                              BUG_ON(sh->dev[i].req.bi_io_vec[0].bv_page == sh->dev[i].page);
++                              sh->dev[i].req.bi_io_vec[0].bv_page = sh->dev[i].page;
++                      }
++
+                       clear_bit(R5_LOCKED, &sh->dev[i].flags);
+                       set_bit(STRIPE_HANDLE, &sh->state);
+               }
+@@ -1835,6 +1931,7 @@ memory = conf->max_nr_stripes * (sizeof(
                if (mddev->queue->backing_dev_info.ra_pages < 2 * stripe)
                        mddev->queue->backing_dev_info.ra_pages = 2 * stripe;
        }
@@ -204,7 +226,7 @@ diff -pru linux-2.6.9.orig/drivers/md/raid5.c linux-2.6.9/drivers/md/raid5.c
  
        /* Ok, everything is just fine now */
        mddev->array_size =  mddev->size * (mddev->raid_disks - 1);
-@@ -1918,9 +2001,11 @@ static void status (struct seq_file *seq
+@@ -1922,9 +2019,11 @@ static void status (struct seq_file *seq
                        atomic_read(&conf->handled_in_raid5d),
                        atomic_read(&conf->out_of_stripes),
                        atomic_read(&conf->handle_called));
@@ -218,9 +240,9 @@ diff -pru linux-2.6.9.orig/drivers/md/raid5.c linux-2.6.9/drivers/md/raid5.c
        seq_printf (seq, "\n\t\t%u delayed, %u active, queues: %u in, %u out\n",
                        atomic_read(&conf->delayed),
                        atomic_read(&conf->active_stripes),
-diff -pru linux-2.6.9.orig/include/linux/backing-dev.h linux-2.6.9/include/linux/backing-dev.h
---- linux-2.6.9.orig/include/linux/backing-dev.h       2004-10-18 15:53:46.000000000 -0600
-+++ linux-2.6.9/include/linux/backing-dev.h    2007-07-13 00:12:46.000000000 -0600
+diff -pur linux-2.6.9-67.orig/include/linux/backing-dev.h linux-2.6.9-67/include/linux/backing-dev.h
+--- linux-2.6.9-67.orig/include/linux/backing-dev.h    2009-02-15 10:11:54.000000000 +0800
++++ linux-2.6.9-67/include/linux/backing-dev.h 2009-02-15 10:22:40.000000000 +0800
 @@ -30,8 +30,11 @@ struct backing_dev_info {
        void *congested_data;   /* Pointer to aux data for congested func */
        void (*unplug_io_fn)(struct backing_dev_info *, struct page *);
@@ -241,9 +263,9 @@ diff -pru linux-2.6.9.orig/include/linux/backing-dev.h linux-2.6.9/include/linux
 +      ((mapping)->backing_dev_info->capabilities & BDI_CAP_PAGE_CONST_WRITE)
 +
  #endif                /* _LINUX_BACKING_DEV_H */
-diff -pru linux-2.6.9.orig/include/linux/page-flags.h linux-2.6.9/include/linux/page-flags.h
---- linux-2.6.9.orig/include/linux/page-flags.h        2004-10-18 15:54:39.000000000 -0600
-+++ linux-2.6.9/include/linux/page-flags.h     2007-07-13 00:12:46.000000000 -0600
+diff -pur linux-2.6.9-67.orig/include/linux/page-flags.h linux-2.6.9-67/include/linux/page-flags.h
+--- linux-2.6.9-67.orig/include/linux/page-flags.h     2009-02-15 10:11:54.000000000 +0800
++++ linux-2.6.9-67/include/linux/page-flags.h  2009-02-15 10:22:40.000000000 +0800
 @@ -74,6 +74,7 @@
  #define PG_swapcache          16      /* Swap page: swp_entry_t in private */
  #define PG_mappedtodisk               17      /* Has blocks allocated on-disk */
@@ -264,9 +286,9 @@ diff -pru linux-2.6.9.orig/include/linux/page-flags.h linux-2.6.9/include/linux/
  struct page;  /* forward declaration */
  
  int test_clear_page_dirty(struct page *page);
-diff -pru linux-2.6.9.orig/include/linux/pagemap.h linux-2.6.9/include/linux/pagemap.h
---- linux-2.6.9.orig/include/linux/pagemap.h   2004-10-18 15:53:06.000000000 -0600
-+++ linux-2.6.9/include/linux/pagemap.h        2007-07-13 00:12:46.000000000 -0600
+diff -pur linux-2.6.9-67.orig/include/linux/pagemap.h linux-2.6.9-67/include/linux/pagemap.h
+--- linux-2.6.9-67.orig/include/linux/pagemap.h        2009-02-15 10:11:54.000000000 +0800
++++ linux-2.6.9-67/include/linux/pagemap.h     2009-02-15 10:22:40.000000000 +0800
 @@ -191,6 +191,19 @@ static inline void wait_on_page_writebac
  
  extern void end_page_writeback(struct page *page);
@@ -287,9 +309,9 @@ diff -pru linux-2.6.9.orig/include/linux/pagemap.h linux-2.6.9/include/linux/pag
  /*
   * Fault a userspace page into pagetables.  Return non-zero on a fault.
   *
-diff -pru linux-2.6.9.orig/include/linux/raid/raid5.h linux-2.6.9/include/linux/raid/raid5.h
---- linux-2.6.9.orig/include/linux/raid/raid5.h        2007-07-09 02:43:33.000000000 -0600
-+++ linux-2.6.9/include/linux/raid/raid5.h     2007-07-13 00:39:15.000000000 -0600
+diff -pur linux-2.6.9-67.orig/include/linux/raid/raid5.h linux-2.6.9-67/include/linux/raid/raid5.h
+--- linux-2.6.9-67.orig/include/linux/raid/raid5.h     2009-02-15 10:11:54.000000000 +0800
++++ linux-2.6.9-67/include/linux/raid/raid5.h  2009-02-15 10:22:40.000000000 +0800
 @@ -153,6 +153,7 @@ struct stripe_head {
  #define       R5_Wantread     4       /* want to schedule a read */
  #define       R5_Wantwrite    5
@@ -307,9 +329,9 @@ diff -pru linux-2.6.9.orig/include/linux/raid/raid5.h linux-2.6.9/include/linux/
        atomic_t                handle_called;
        atomic_t                delayed;
        atomic_t                in_reqs_in_queue;
-diff -pru linux-2.6.9.orig/mm/filemap.c linux-2.6.9/mm/filemap.c
---- linux-2.6.9.orig/mm/filemap.c      2007-07-09 02:43:33.000000000 -0600
-+++ linux-2.6.9/mm/filemap.c   2007-07-13 00:12:46.000000000 -0600
+diff -pur linux-2.6.9-67.orig/mm/filemap.c linux-2.6.9-67/mm/filemap.c
+--- linux-2.6.9-67.orig/mm/filemap.c   2009-02-15 10:11:55.000000000 +0800
++++ linux-2.6.9-67/mm/filemap.c        2009-02-15 10:22:40.000000000 +0800
 @@ -27,6 +27,8 @@
  #include <linux/pagevec.h>
  #include <linux/blkdev.h>
@@ -319,7 +341,7 @@ diff -pru linux-2.6.9.orig/mm/filemap.c linux-2.6.9/mm/filemap.c
  /*
   * This is needed for the following functions:
   *  - try_to_release_page
-@@ -486,11 +488,52 @@ void end_page_writeback(struct page *pag
+@@ -485,11 +487,52 @@ void end_page_writeback(struct page *pag
                        BUG();
                smp_mb__after_clear_bit();
        }