aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/md
diff options
context:
space:
mode:
authorNeilBrown <neilb@cse.unsw.edu.au>2005-06-21 20:17:13 -0400
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-06-21 22:07:43 -0400
commit57afd89f98a990747445f01c458ecae64263b2f8 (patch)
treecab9f5941f32299bc97936e111f6552ebcee9cf6 /drivers/md
parent06d91a5fe0b50c9060e70bdf7786f8a3c66249db (diff)
[PATCH] md: improve the interface to sync_request
1/ change the return value (which is number-of-sectors synced) from 'int' to 'sector_t'. The number of sectors is usually easily small enough to fit in an int, but if resync needs to abort, it may want to return the total number of remaining sectors, which could be large. Also errors cannot be returned as negative numbers now, so use 0 instead 2/ Add a 'skipped' return parameter to allow the array to report that it skipped the sectors. This allows md to take this into account in the speed calculations. Currently there is no important skipping, but the bitmap-based-resync that is coming will use this. Signed-off-by: Neil Brown <neilb@cse.unsw.edu.au> Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'drivers/md')
-rw-r--r--drivers/md/md.c35
-rw-r--r--drivers/md/raid1.c8
-rw-r--r--drivers/md/raid10.c19
-rw-r--r--drivers/md/raid5.c6
-rw-r--r--drivers/md/raid6main.c6
5 files changed, 45 insertions, 29 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 &&
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 3f1280bbaf39..3c5c916cb09e 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -1010,7 +1010,7 @@ static int init_resync(conf_t *conf)
1010 * that can be installed to exclude normal IO requests. 1010 * that can be installed to exclude normal IO requests.
1011 */ 1011 */
1012 1012
1013static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster) 1013static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster)
1014{ 1014{
1015 conf_t *conf = mddev_to_conf(mddev); 1015 conf_t *conf = mddev_to_conf(mddev);
1016 mirror_info_t *mirror; 1016 mirror_info_t *mirror;
@@ -1023,7 +1023,7 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)
1023 1023
1024 if (!conf->r1buf_pool) 1024 if (!conf->r1buf_pool)
1025 if (init_resync(conf)) 1025 if (init_resync(conf))
1026 return -ENOMEM; 1026 return 0;
1027 1027
1028 max_sector = mddev->size << 1; 1028 max_sector = mddev->size << 1;
1029 if (sector_nr >= max_sector) { 1029 if (sector_nr >= max_sector) {
@@ -1107,8 +1107,8 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)
1107 /* There is nowhere to write, so all non-sync 1107 /* There is nowhere to write, so all non-sync
1108 * drives must be failed - so we are finished 1108 * drives must be failed - so we are finished
1109 */ 1109 */
1110 int rv = max_sector - sector_nr; 1110 sector_t rv = max_sector - sector_nr;
1111 md_done_sync(mddev, rv, 1); 1111 *skipped = 1;
1112 put_buf(r1_bio); 1112 put_buf(r1_bio);
1113 rdev_dec_pending(conf->mirrors[disk].rdev, mddev); 1113 rdev_dec_pending(conf->mirrors[disk].rdev, mddev);
1114 return rv; 1114 return rv;
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index bfc9f52f0ecf..8476515bfdc7 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -1321,7 +1321,7 @@ static int init_resync(conf_t *conf)
1321 * 1321 *
1322 */ 1322 */
1323 1323
1324static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster) 1324static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster)
1325{ 1325{
1326 conf_t *conf = mddev_to_conf(mddev); 1326 conf_t *conf = mddev_to_conf(mddev);
1327 r10bio_t *r10_bio; 1327 r10bio_t *r10_bio;
@@ -1335,7 +1335,7 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)
1335 1335
1336 if (!conf->r10buf_pool) 1336 if (!conf->r10buf_pool)
1337 if (init_resync(conf)) 1337 if (init_resync(conf))
1338 return -ENOMEM; 1338 return 0;
1339 1339
1340 skipped: 1340 skipped:
1341 max_sector = mddev->size << 1; 1341 max_sector = mddev->size << 1;
@@ -1343,15 +1343,15 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)
1343 max_sector = mddev->resync_max_sectors; 1343 max_sector = mddev->resync_max_sectors;
1344 if (sector_nr >= max_sector) { 1344 if (sector_nr >= max_sector) {
1345 close_sync(conf); 1345 close_sync(conf);
1346 *skipped = 1;
1346 return sectors_skipped; 1347 return sectors_skipped;
1347 } 1348 }
1348 if (chunks_skipped >= conf->raid_disks) { 1349 if (chunks_skipped >= conf->raid_disks) {
1349 /* if there has been nothing to do on any drive, 1350 /* if there has been nothing to do on any drive,
1350 * then there is nothing to do at all.. 1351 * then there is nothing to do at all..
1351 */ 1352 */
1352 sector_t sec = max_sector - sector_nr; 1353 *skipped = 1;
1353 md_done_sync(mddev, sec, 1); 1354 return (max_sector - sector_nr) + sectors_skipped;
1354 return sec + sectors_skipped;
1355 } 1355 }
1356 1356
1357 /* make sure whole request will fit in a chunk - if chunks 1357 /* make sure whole request will fit in a chunk - if chunks
@@ -1565,17 +1565,22 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)
1565 } 1565 }
1566 } 1566 }
1567 1567
1568 if (sectors_skipped)
1569 /* pretend they weren't skipped, it makes
1570 * no important difference in this case
1571 */
1572 md_done_sync(mddev, sectors_skipped, 1);
1573
1568 return sectors_skipped + nr_sectors; 1574 return sectors_skipped + nr_sectors;
1569 giveup: 1575 giveup:
1570 /* There is nowhere to write, so all non-sync 1576 /* There is nowhere to write, so all non-sync
1571 * drives must be failed, so try the next chunk... 1577 * drives must be failed, so try the next chunk...
1572 */ 1578 */
1573 { 1579 {
1574 int sec = max_sector - sector_nr; 1580 sector_t sec = max_sector - sector_nr;
1575 sectors_skipped += sec; 1581 sectors_skipped += sec;
1576 chunks_skipped ++; 1582 chunks_skipped ++;
1577 sector_nr = max_sector; 1583 sector_nr = max_sector;
1578 md_done_sync(mddev, sec, 1);
1579 goto skipped; 1584 goto skipped;
1580 } 1585 }
1581} 1586}
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 677ce49078da..1ce3f5aaa984 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -1477,7 +1477,7 @@ static int make_request (request_queue_t *q, struct bio * bi)
1477} 1477}
1478 1478
1479/* FIXME go_faster isn't used */ 1479/* FIXME go_faster isn't used */
1480static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster) 1480static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster)
1481{ 1481{
1482 raid5_conf_t *conf = (raid5_conf_t *) mddev->private; 1482 raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
1483 struct stripe_head *sh; 1483 struct stripe_head *sh;
@@ -1500,8 +1500,8 @@ static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster)
1500 * nothing we can do. 1500 * nothing we can do.
1501 */ 1501 */
1502 if (mddev->degraded >= 1 && test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { 1502 if (mddev->degraded >= 1 && test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
1503 int rv = (mddev->size << 1) - sector_nr; 1503 sector_t rv = (mddev->size << 1) - sector_nr;
1504 md_done_sync(mddev, rv, 1); 1504 *skipped = 1;
1505 return rv; 1505 return rv;
1506 } 1506 }
1507 1507
diff --git a/drivers/md/raid6main.c b/drivers/md/raid6main.c
index fede16c4e8f3..d9c385496dc5 100644
--- a/drivers/md/raid6main.c
+++ b/drivers/md/raid6main.c
@@ -1636,7 +1636,7 @@ static int make_request (request_queue_t *q, struct bio * bi)
1636} 1636}
1637 1637
1638/* FIXME go_faster isn't used */ 1638/* FIXME go_faster isn't used */
1639static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster) 1639static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster)
1640{ 1640{
1641 raid6_conf_t *conf = (raid6_conf_t *) mddev->private; 1641 raid6_conf_t *conf = (raid6_conf_t *) mddev->private;
1642 struct stripe_head *sh; 1642 struct stripe_head *sh;
@@ -1659,8 +1659,8 @@ static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster)
1659 * nothing we can do. 1659 * nothing we can do.
1660 */ 1660 */
1661 if (mddev->degraded >= 2 && test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) { 1661 if (mddev->degraded >= 2 && test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
1662 int rv = (mddev->size << 1) - sector_nr; 1662 sector_t rv = (mddev->size << 1) - sector_nr;
1663 md_done_sync(mddev, rv, 1); 1663 *skipped = 1;
1664 return rv; 1664 return rv;
1665 } 1665 }
1666 1666