return 0;
 }
 
-static void raid5_build_block(struct stripe_head *sh, int i);
+static void raid5_build_block(struct stripe_head *sh, int i, int previous);
 static void stripe_set_idx(sector_t stripe, raid5_conf_t *conf, int previous,
                            struct stripe_head *sh);
 
                        BUG();
                }
                dev->flags = 0;
-               raid5_build_block(sh, i);
+               raid5_build_block(sh, i, previous);
        }
        insert_hash(conf, sh);
 }
 }
 
 
-static sector_t compute_blocknr(struct stripe_head *sh, int i);
+static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous);
        
-static void raid5_build_block(struct stripe_head *sh, int i)
+static void raid5_build_block(struct stripe_head *sh, int i, int previous)
 {
        struct r5dev *dev = &sh->dev[i];
 
        dev->req.bi_private = sh;
 
        dev->flags = 0;
-       dev->sector = compute_blocknr(sh, i);
+       dev->sector = compute_blocknr(sh, i, previous);
 }
 
 static void error(mddev_t *mddev, mdk_rdev_t *rdev)
        int pd_idx, qd_idx;
        int ddf_layout = 0;
        sector_t new_sector;
-       int sectors_per_chunk = conf->chunk_size >> 9;
+       int sectors_per_chunk = previous ? (conf->prev_chunk >> 9)
+                                        : (conf->chunk_size >> 9);
        int raid_disks = previous ? conf->previous_raid_disks
                                  : conf->raid_disks;
        int data_disks = raid_disks - conf->max_degraded;
 }
 
 
-static sector_t compute_blocknr(struct stripe_head *sh, int i)
+static sector_t compute_blocknr(struct stripe_head *sh, int i, int previous)
 {
        raid5_conf_t *conf = sh->raid_conf;
        int raid_disks = sh->disks;
        int data_disks = raid_disks - conf->max_degraded;
        sector_t new_sector = sh->sector, check;
-       int sectors_per_chunk = conf->chunk_size >> 9;
+       int sectors_per_chunk = previous ? (conf->prev_chunk >> 9)
+                                        : (conf->chunk_size >> 9);
        sector_t stripe;
        int chunk_offset;
        int chunk_number, dummy1, dd_idx = i;
        r_sector = (sector_t)chunk_number * sectors_per_chunk + chunk_offset;
 
        check = raid5_compute_sector(conf, r_sector,
-                                    (raid_disks != conf->raid_disks),
-                                    &dummy1, &sh2);
+                                    previous, &dummy1, &sh2);
        if (check != sh->sector || dummy1 != dd_idx || sh2.pd_idx != sh->pd_idx
                || sh2.qd_idx != sh->qd_idx) {
                printk(KERN_ERR "compute_blocknr: map not correct\n");
 static void stripe_set_idx(sector_t stripe, raid5_conf_t *conf, int previous,
                            struct stripe_head *sh)
 {
-       int sectors_per_chunk = conf->chunk_size >> 9;
+       int sectors_per_chunk =
+               previous ? (conf->prev_chunk >> 9)
+                        : (conf->chunk_size >> 9);
        int dd_idx;
        int chunk_offset = sector_div(stripe, sectors_per_chunk);
        int disks = previous ? conf->previous_raid_disks : conf->raid_disks;
                        int dd_idx, j;
                        struct stripe_head *sh2;
 
-                       sector_t bn = compute_blocknr(sh, i);
+                       sector_t bn = compute_blocknr(sh, i, 1);
                        sector_t s = raid5_compute_sector(conf, bn, 0,
                                                          &dd_idx, NULL);
                        sh2 = get_active_stripe(conf, s, 0, 1);
        if ((bvm->bi_rw & 1) == WRITE)
                return biovec->bv_len; /* always allow writes to be mergeable */
 
+       if (mddev->new_chunk < mddev->chunk_size)
+               chunk_sectors = mddev->new_chunk >> 9;
        max =  (chunk_sectors - ((sector & (chunk_sectors - 1)) + bio_sectors)) << 9;
        if (max < 0) max = 0;
        if (max <= biovec->bv_len && bio_sectors == 0)
        unsigned int chunk_sectors = mddev->chunk_size >> 9;
        unsigned int bio_sectors = bio->bi_size >> 9;
 
+       if (mddev->new_chunk < mddev->chunk_size)
+               chunk_sectors = mddev->new_chunk >> 9;
        return  chunk_sectors >=
                ((sector & (chunk_sectors - 1)) + bio_sectors);
 }
                BUG_ON(conf->reshape_progress == 0);
                stripe_addr = writepos;
                BUG_ON((mddev->dev_sectors &
-                       ~((sector_t)mddev->chunk_size / 512 - 1))
+                       ~((sector_t)conf->chunk_size / 512 - 1))
                       - (conf->chunk_size / 512) - stripe_addr
                       != sector_nr);
        } else {
                        if (conf->level == 6 &&
                            j == sh->qd_idx)
                                continue;
-                       s = compute_blocknr(sh, j);
+                       s = compute_blocknr(sh, j, 0);
                        if (s < raid5_size(mddev, 0, 0)) {
                                skipped = 1;
                                continue;
        }
 
        sectors &= ~((sector_t)mddev->chunk_size/512 - 1);
+       sectors &= ~((sector_t)mddev->new_chunk/512 - 1);
        return sectors * (raid_disks - conf->max_degraded);
 }
 
        conf->algorithm = mddev->new_layout;
        conf->max_nr_stripes = NR_STRIPES;
        conf->reshape_progress = mddev->reshape_position;
+       if (conf->reshape_progress != MaxSector)
+               conf->prev_chunk = mddev->chunk_size;
 
        memory = conf->max_nr_stripes * (sizeof(struct stripe_head) +
                 conf->raid_disks * ((sizeof(struct bio) + PAGE_SIZE))) / 1024;
                 * geometry.
                 */
                here_new = mddev->reshape_position;
-               if (sector_div(here_new, (mddev->chunk_size>>9)*
+               if (sector_div(here_new, (mddev->new_chunk>>9)*
                               (mddev->raid_disks - max_degraded))) {
                        printk(KERN_ERR "raid5: reshape_position not "
                               "on a stripe boundary\n");
        if ((mddev->chunk_size / STRIPE_SIZE) * 4 > conf->max_nr_stripes ||
            (mddev->new_chunk / STRIPE_SIZE) * 4 > conf->max_nr_stripes) {
                printk(KERN_WARNING "raid5: reshape: not enough stripes.  Needed %lu\n",
-                      (mddev->chunk_size / STRIPE_SIZE)*4);
+                      (max(mddev->chunk_size, mddev->new_chunk)
+                       / STRIPE_SIZE)*4);
                return -ENOSPC;
        }