aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md/md.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/md/md.c')
-rw-r--r--drivers/md/md.c35
1 files changed, 23 insertions, 12 deletions
diff --git a/drivers/md/md.c b/drivers/md/md.c
index 177d2a7d7cea..fa608a1a5c20 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -3241,12 +3241,13 @@ static void md_do_sync(mddev_t *mddev)
3241 mddev_t *mddev2; 3241 mddev_t *mddev2;
3242 unsigned int currspeed = 0, 3242 unsigned int currspeed = 0,
3243 window; 3243 window;
3244 sector_t max_sectors,j; 3244 sector_t max_sectors,j, io_sectors;
3245 unsigned long mark[SYNC_MARKS]; 3245 unsigned long mark[SYNC_MARKS];
3246 sector_t mark_cnt[SYNC_MARKS]; 3246 sector_t mark_cnt[SYNC_MARKS];
3247 int last_mark,m; 3247 int last_mark,m;
3248 struct list_head *tmp; 3248 struct list_head *tmp;
3249 sector_t last_check; 3249 sector_t last_check;
3250 int skipped = 0;
3250 3251
3251 /* just incase thread restarts... */ 3252 /* just incase thread restarts... */
3252 if (test_bit(MD_RECOVERY_DONE, &mddev->recovery)) 3253 if (test_bit(MD_RECOVERY_DONE, &mddev->recovery))
@@ -3312,7 +3313,7 @@ static void md_do_sync(mddev_t *mddev)
3312 3313
3313 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) 3314 if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
3314 /* resync follows the size requested by the personality, 3315 /* resync follows the size requested by the personality,
3315 * which default to physical size, but can be virtual size 3316 * which defaults to physical size, but can be virtual size
3316 */ 3317 */
3317 max_sectors = mddev->resync_max_sectors; 3318 max_sectors = mddev->resync_max_sectors;
3318 else 3319 else
@@ -3331,9 +3332,10 @@ static void md_do_sync(mddev_t *mddev)
3331 j = mddev->recovery_cp; 3332 j = mddev->recovery_cp;
3332 else 3333 else
3333 j = 0; 3334 j = 0;
3335 io_sectors = 0;
3334 for (m = 0; m < SYNC_MARKS; m++) { 3336 for (m = 0; m < SYNC_MARKS; m++) {
3335 mark[m] = jiffies; 3337 mark[m] = jiffies;
3336 mark_cnt[m] = j; 3338 mark_cnt[m] = io_sectors;
3337 } 3339 }
3338 last_mark = 0; 3340 last_mark = 0;
3339 mddev->resync_mark = mark[last_mark]; 3341 mddev->resync_mark = mark[last_mark];
@@ -3358,21 +3360,29 @@ static void md_do_sync(mddev_t *mddev)
3358 } 3360 }
3359 3361
3360 while (j < max_sectors) { 3362 while (j < max_sectors) {
3361 int sectors; 3363 sector_t sectors;
3362 3364
3363 sectors = mddev->pers->sync_request(mddev, j, currspeed < sysctl_speed_limit_min); 3365 skipped = 0;
3364 if (sectors < 0) { 3366 sectors = mddev->pers->sync_request(mddev, j, &skipped,
3367 currspeed < sysctl_speed_limit_min);
3368 if (sectors == 0) {
3365 set_bit(MD_RECOVERY_ERR, &mddev->recovery); 3369 set_bit(MD_RECOVERY_ERR, &mddev->recovery);
3366 goto out; 3370 goto out;
3367 } 3371 }
3368 atomic_add(sectors, &mddev->recovery_active); 3372
3373 if (!skipped) { /* actual IO requested */
3374 io_sectors += sectors;
3375 atomic_add(sectors, &mddev->recovery_active);
3376 }
3377
3369 j += sectors; 3378 j += sectors;
3370 if (j>1) mddev->curr_resync = j; 3379 if (j>1) mddev->curr_resync = j;
3371 3380
3372 if (last_check + window > j || j == max_sectors) 3381
3382 if (last_check + window > io_sectors || j == max_sectors)
3373 continue; 3383 continue;
3374 3384
3375 last_check = j; 3385 last_check = io_sectors;
3376 3386
3377 if (test_bit(MD_RECOVERY_INTR, &mddev->recovery) || 3387 if (test_bit(MD_RECOVERY_INTR, &mddev->recovery) ||
3378 test_bit(MD_RECOVERY_ERR, &mddev->recovery)) 3388 test_bit(MD_RECOVERY_ERR, &mddev->recovery))
@@ -3386,7 +3396,7 @@ static void md_do_sync(mddev_t *mddev)
3386 mddev->resync_mark = mark[next]; 3396 mddev->resync_mark = mark[next];
3387 mddev->resync_mark_cnt = mark_cnt[next]; 3397 mddev->resync_mark_cnt = mark_cnt[next];
3388 mark[next] = jiffies; 3398 mark[next] = jiffies;
3389 mark_cnt[next] = j - atomic_read(&mddev->recovery_active); 3399 mark_cnt[next] = io_sectors - atomic_read(&mddev->recovery_active);
3390 last_mark = next; 3400 last_mark = next;
3391 } 3401 }
3392 3402
@@ -3413,7 +3423,8 @@ static void md_do_sync(mddev_t *mddev)
3413 mddev->queue->unplug_fn(mddev->queue); 3423 mddev->queue->unplug_fn(mddev->queue);
3414 cond_resched(); 3424 cond_resched();
3415 3425
3416 currspeed = ((unsigned long)(j-mddev->resync_mark_cnt))/2/((jiffies-mddev->resync_mark)/HZ +1) +1; 3426 currspeed = ((unsigned long)(io_sectors-mddev->resync_mark_cnt))/2
3427 /((jiffies-mddev->resync_mark)/HZ +1) +1;
3417 3428
3418 if (currspeed > sysctl_speed_limit_min) { 3429 if (currspeed > sysctl_speed_limit_min) {
3419 if ((currspeed > sysctl_speed_limit_max) || 3430 if ((currspeed > sysctl_speed_limit_max) ||
@@ -3433,7 +3444,7 @@ static void md_do_sync(mddev_t *mddev)
3433 wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active)); 3444 wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active));
3434 3445
3435 /* tell personality that we are finished */ 3446 /* tell personality that we are finished */
3436 mddev->pers->sync_request(mddev, max_sectors, 1); 3447 mddev->pers->sync_request(mddev, max_sectors, &skipped, 1);
3437 3448
3438 if (!test_bit(MD_RECOVERY_ERR, &mddev->recovery) && 3449 if (!test_bit(MD_RECOVERY_ERR, &mddev->recovery) &&
3439 mddev->curr_resync > 2 && 3450 mddev->curr_resync > 2 &&