Skip to content

Commit

Permalink
[PATCH] md: improve the interface to sync_request
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
NeilBrown authored and Linus Torvalds committed Jun 22, 2005
1 parent 06d91a5 commit 57afd89
Show file tree
Hide file tree
Showing 6 changed files with 46 additions and 30 deletions.
35 changes: 23 additions & 12 deletions drivers/md/md.c
Original file line number Diff line number Diff line change
Expand Up @@ -3241,12 +3241,13 @@ static void md_do_sync(mddev_t *mddev)
mddev_t *mddev2;
unsigned int currspeed = 0,
window;
sector_t max_sectors,j;
sector_t max_sectors,j, io_sectors;
unsigned long mark[SYNC_MARKS];
sector_t mark_cnt[SYNC_MARKS];
int last_mark,m;
struct list_head *tmp;
sector_t last_check;
int skipped = 0;

/* just incase thread restarts... */
if (test_bit(MD_RECOVERY_DONE, &mddev->recovery))
Expand Down Expand Up @@ -3312,7 +3313,7 @@ static void md_do_sync(mddev_t *mddev)

if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
/* resync follows the size requested by the personality,
* which default to physical size, but can be virtual size
* which defaults to physical size, but can be virtual size
*/
max_sectors = mddev->resync_max_sectors;
else
Expand All @@ -3331,9 +3332,10 @@ static void md_do_sync(mddev_t *mddev)
j = mddev->recovery_cp;
else
j = 0;
io_sectors = 0;
for (m = 0; m < SYNC_MARKS; m++) {
mark[m] = jiffies;
mark_cnt[m] = j;
mark_cnt[m] = io_sectors;
}
last_mark = 0;
mddev->resync_mark = mark[last_mark];
Expand All @@ -3358,21 +3360,29 @@ static void md_do_sync(mddev_t *mddev)
}

while (j < max_sectors) {
int sectors;
sector_t sectors;

sectors = mddev->pers->sync_request(mddev, j, currspeed < sysctl_speed_limit_min);
if (sectors < 0) {
skipped = 0;
sectors = mddev->pers->sync_request(mddev, j, &skipped,
currspeed < sysctl_speed_limit_min);
if (sectors == 0) {
set_bit(MD_RECOVERY_ERR, &mddev->recovery);
goto out;
}
atomic_add(sectors, &mddev->recovery_active);

if (!skipped) { /* actual IO requested */
io_sectors += sectors;
atomic_add(sectors, &mddev->recovery_active);
}

j += sectors;
if (j>1) mddev->curr_resync = j;

if (last_check + window > j || j == max_sectors)

if (last_check + window > io_sectors || j == max_sectors)
continue;

last_check = j;
last_check = io_sectors;

if (test_bit(MD_RECOVERY_INTR, &mddev->recovery) ||
test_bit(MD_RECOVERY_ERR, &mddev->recovery))
Expand All @@ -3386,7 +3396,7 @@ static void md_do_sync(mddev_t *mddev)
mddev->resync_mark = mark[next];
mddev->resync_mark_cnt = mark_cnt[next];
mark[next] = jiffies;
mark_cnt[next] = j - atomic_read(&mddev->recovery_active);
mark_cnt[next] = io_sectors - atomic_read(&mddev->recovery_active);
last_mark = next;
}

Expand All @@ -3413,7 +3423,8 @@ static void md_do_sync(mddev_t *mddev)
mddev->queue->unplug_fn(mddev->queue);
cond_resched();

currspeed = ((unsigned long)(j-mddev->resync_mark_cnt))/2/((jiffies-mddev->resync_mark)/HZ +1) +1;
currspeed = ((unsigned long)(io_sectors-mddev->resync_mark_cnt))/2
/((jiffies-mddev->resync_mark)/HZ +1) +1;

if (currspeed > sysctl_speed_limit_min) {
if ((currspeed > sysctl_speed_limit_max) ||
Expand All @@ -3433,7 +3444,7 @@ static void md_do_sync(mddev_t *mddev)
wait_event(mddev->recovery_wait, !atomic_read(&mddev->recovery_active));

/* tell personality that we are finished */
mddev->pers->sync_request(mddev, max_sectors, 1);
mddev->pers->sync_request(mddev, max_sectors, &skipped, 1);

if (!test_bit(MD_RECOVERY_ERR, &mddev->recovery) &&
mddev->curr_resync > 2 &&
Expand Down
8 changes: 4 additions & 4 deletions drivers/md/raid1.c
Original file line number Diff line number Diff line change
Expand Up @@ -1010,7 +1010,7 @@ static int init_resync(conf_t *conf)
* that can be installed to exclude normal IO requests.
*/

static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)
static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster)
{
conf_t *conf = mddev_to_conf(mddev);
mirror_info_t *mirror;
Expand All @@ -1023,7 +1023,7 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)

if (!conf->r1buf_pool)
if (init_resync(conf))
return -ENOMEM;
return 0;

max_sector = mddev->size << 1;
if (sector_nr >= max_sector) {
Expand Down Expand Up @@ -1107,8 +1107,8 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)
/* There is nowhere to write, so all non-sync
* drives must be failed - so we are finished
*/
int rv = max_sector - sector_nr;
md_done_sync(mddev, rv, 1);
sector_t rv = max_sector - sector_nr;
*skipped = 1;
put_buf(r1_bio);
rdev_dec_pending(conf->mirrors[disk].rdev, mddev);
return rv;
Expand Down
19 changes: 12 additions & 7 deletions drivers/md/raid10.c
Original file line number Diff line number Diff line change
Expand Up @@ -1321,7 +1321,7 @@ static int init_resync(conf_t *conf)
*
*/

static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)
static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster)
{
conf_t *conf = mddev_to_conf(mddev);
r10bio_t *r10_bio;
Expand All @@ -1335,23 +1335,23 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)

if (!conf->r10buf_pool)
if (init_resync(conf))
return -ENOMEM;
return 0;

skipped:
max_sector = mddev->size << 1;
if (test_bit(MD_RECOVERY_SYNC, &mddev->recovery))
max_sector = mddev->resync_max_sectors;
if (sector_nr >= max_sector) {
close_sync(conf);
*skipped = 1;
return sectors_skipped;
}
if (chunks_skipped >= conf->raid_disks) {
/* if there has been nothing to do on any drive,
* then there is nothing to do at all..
*/
sector_t sec = max_sector - sector_nr;
md_done_sync(mddev, sec, 1);
return sec + sectors_skipped;
*skipped = 1;
return (max_sector - sector_nr) + sectors_skipped;
}

/* make sure whole request will fit in a chunk - if chunks
Expand Down Expand Up @@ -1565,17 +1565,22 @@ static int sync_request(mddev_t *mddev, sector_t sector_nr, int go_faster)
}
}

if (sectors_skipped)
/* pretend they weren't skipped, it makes
* no important difference in this case
*/
md_done_sync(mddev, sectors_skipped, 1);

return sectors_skipped + nr_sectors;
giveup:
/* There is nowhere to write, so all non-sync
* drives must be failed, so try the next chunk...
*/
{
int sec = max_sector - sector_nr;
sector_t sec = max_sector - sector_nr;
sectors_skipped += sec;
chunks_skipped ++;
sector_nr = max_sector;
md_done_sync(mddev, sec, 1);
goto skipped;
}
}
Expand Down
6 changes: 3 additions & 3 deletions drivers/md/raid5.c
Original file line number Diff line number Diff line change
Expand Up @@ -1477,7 +1477,7 @@ static int make_request (request_queue_t *q, struct bio * bi)
}

/* FIXME go_faster isn't used */
static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster)
static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster)
{
raid5_conf_t *conf = (raid5_conf_t *) mddev->private;
struct stripe_head *sh;
Expand All @@ -1500,8 +1500,8 @@ static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster)
* nothing we can do.
*/
if (mddev->degraded >= 1 && test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
int rv = (mddev->size << 1) - sector_nr;
md_done_sync(mddev, rv, 1);
sector_t rv = (mddev->size << 1) - sector_nr;
*skipped = 1;
return rv;
}

Expand Down
6 changes: 3 additions & 3 deletions drivers/md/raid6main.c
Original file line number Diff line number Diff line change
Expand Up @@ -1636,7 +1636,7 @@ static int make_request (request_queue_t *q, struct bio * bi)
}

/* FIXME go_faster isn't used */
static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster)
static sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster)
{
raid6_conf_t *conf = (raid6_conf_t *) mddev->private;
struct stripe_head *sh;
Expand All @@ -1659,8 +1659,8 @@ static int sync_request (mddev_t *mddev, sector_t sector_nr, int go_faster)
* nothing we can do.
*/
if (mddev->degraded >= 2 && test_bit(MD_RECOVERY_SYNC, &mddev->recovery)) {
int rv = (mddev->size << 1) - sector_nr;
md_done_sync(mddev, rv, 1);
sector_t rv = (mddev->size << 1) - sector_nr;
*skipped = 1;
return rv;
}

Expand Down
2 changes: 1 addition & 1 deletion include/linux/raid/md_k.h
Original file line number Diff line number Diff line change
Expand Up @@ -298,7 +298,7 @@ struct mdk_personality_s
int (*hot_add_disk) (mddev_t *mddev, mdk_rdev_t *rdev);
int (*hot_remove_disk) (mddev_t *mddev, int number);
int (*spare_active) (mddev_t *mddev);
int (*sync_request)(mddev_t *mddev, sector_t sector_nr, int go_faster);
sector_t (*sync_request)(mddev_t *mddev, sector_t sector_nr, int *skipped, int go_faster);
int (*resize) (mddev_t *mddev, sector_t sectors);
int (*reshape) (mddev_t *mddev, int raid_disks);
int (*reconfig) (mddev_t *mddev, int layout, int chunk_size);
Expand Down

0 comments on commit 57afd89

Please sign in to comment.