sync_speed_show(mddev_t *mddev, char *page)
 {
        unsigned long resync, dt, db;
-       resync = (mddev->curr_resync - atomic_read(&mddev->recovery_active));
+       resync = (mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active));
        dt = ((jiffies - mddev->resync_mark) / HZ);
        if (!dt) dt++;
        db = resync - (mddev->resync_mark_cnt);
         */
        dt = ((jiffies - mddev->resync_mark) / HZ);
        if (!dt) dt++;
-       db = resync - (mddev->resync_mark_cnt/2);
-       rt = (dt * ((unsigned long)(max_blocks-resync) / (db/100+1)))/100;
+       db = (mddev->curr_mark_cnt - atomic_read(&mddev->recovery_active))
+               - mddev->resync_mark_cnt;
+       rt = (dt * ((unsigned long)(max_blocks-resync) / (db/2/100+1)))/100;
 
        seq_printf(seq, " finish=%lu.%lumin", rt / 60, (rt % 60)/6);
 
-       seq_printf(seq, " speed=%ldK/sec", db/dt);
+       seq_printf(seq, " speed=%ldK/sec", db/2/dt);
 }
 
 static void *md_seq_start(struct seq_file *seq, loff_t *pos)
 
                j += sectors;
                if (j>1) mddev->curr_resync = j;
+               mddev->curr_mark_cnt = io_sectors;
                if (last_check == 0)
                        /* this is the earliers that rebuilt will be
                         * visible in /proc/mdstat
 
                        } else {
                                if (!test_bit(STRIPE_HANDLE, &sh->state))
                                        atomic_inc(&conf->active_stripes);
-                               if (list_empty(&sh->lru))
+                               if (list_empty(&sh->lru) &&
+                                   !test_bit(STRIPE_EXPANDING, &sh->state))
                                        BUG();
                                list_del_init(&sh->lru);
                        }
 
 
        struct mdk_thread_s             *thread;        /* management thread */
        struct mdk_thread_s             *sync_thread;   /* doing resync or reconstruct */
-       sector_t                        curr_resync;    /* blocks scheduled */
+       sector_t                        curr_resync;    /* last block scheduled */
        unsigned long                   resync_mark;    /* a recent timestamp */
        sector_t                        resync_mark_cnt;/* blocks written at resync_mark */
+       sector_t                        curr_mark_cnt; /* blocks scheduled now */
 
        sector_t                        resync_max_sectors; /* may be set by personality */