diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2015-04-11 16:23:35 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2015-04-11 16:23:35 +0000 |
commit | 901f829acc4abc1a85823a3379130207cc6a14b6 (patch) | |
tree | 7afc7a137659b6582117f54b19ee7e3174c0183d /sys/dev | |
parent | 596f88bfd3cde6a6f3e4ccf5336035eea533bb60 (diff) |
Add support for restarting rebuilds on RAID 5.
ok krw@
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/softraid_raid5.c | 24 |
1 files changed, 20 insertions, 4 deletions
diff --git a/sys/dev/softraid_raid5.c b/sys/dev/softraid_raid5.c index 60f9a064f2d..181129aa008 100644 --- a/sys/dev/softraid_raid5.c +++ b/sys/dev/softraid_raid5.c @@ -1,4 +1,4 @@ -/* $OpenBSD: softraid_raid5.c,v 1.17 2014/11/18 02:37:30 tedu Exp $ */ +/* $OpenBSD: softraid_raid5.c,v 1.18 2015/04/11 16:23:34 jsing Exp $ */ /* * Copyright (c) 2014 Joel Sing <jsing@openbsd.org> * Copyright (c) 2009 Marco Peereboom <marco@peereboom.us> @@ -766,7 +766,7 @@ sr_raid5_xor(void *a, void *b, int len) void sr_raid5_rebuild(struct sr_discipline *sd) { - int64_t strip_no, strip_size, strip_bits, i, psz, rb; + int64_t strip_no, strip_size, strip_bits, i, psz, rb, restart; int64_t chunk_count, chunk_strips, chunk_lba, chunk_size, row_size; struct sr_workunit *wu_r, *wu_w; int s, slept, percent = 0, old_percent = -1; @@ -790,14 +790,30 @@ sr_raid5_rebuild(struct sr_discipline *sd) chunk_strips = (chunk_size << DEV_BSHIFT) >> strip_bits; row_size = (chunk_count << strip_bits) >> DEV_BSHIFT; - /* XXX - handle restarts. */ DNPRINTF(SR_D_REBUILD, "%s: %s sr_raid5_rebuild volume size = %lld, " "chunk count = %lld, chunk size = %lld, chunk strips = %lld, " "row size = %lld\n", DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname, sd->sd_meta->ssdi.ssd_size, chunk_count, chunk_size, chunk_strips, row_size); - for (strip_no = 0; strip_no < chunk_strips; strip_no++) { + restart = sd->sd_meta->ssd_rebuild / row_size; + if (restart > chunk_strips) { + printf("%s: bogus rebuild restart offset, starting from 0\n", + DEVNAME(sd->sd_sc)); + restart = 0; + } + if (restart != 0) { + psz = sd->sd_meta->ssdi.ssd_size; + rb = sd->sd_meta->ssd_rebuild; + if (rb > 0) + percent = 100 - ((psz * 100 - rb * 100) / psz) - 1; + else + percent = 0; + printf("%s: resuming rebuild on %s at %d%%\n", + DEVNAME(sd->sd_sc), sd->sd_meta->ssd_devname, percent); + } + + for (strip_no = restart; strip_no < chunk_strips; strip_no++) { chunk_lba = (strip_size >> DEV_BSHIFT) * strip_no + sd->sd_meta->ssd_data_offset; |