diff options
author | 2008-01-24 19:58:08 +0000 | |
---|---|---|
committer | 2008-01-24 19:58:08 +0000 | |
commit | f09486a69fd4f29af1cf5ab659c0addea26b22bf (patch) | |
tree | 8923acb09370ccacc2236e7737a03cc5a436e51e /sys/dev/softraid_raid0.c | |
parent | Add RAID 0 and clean up some of the text. (diff) | |
download | wireguard-openbsd-f09486a69fd4f29af1cf5ab659c0addea26b22bf.tar.xz wireguard-openbsd-f09486a69fd4f29af1cf5ab659c0addea26b22bf.zip |
Create chunk and state transition functions for RAID 0.
Move RAID 1 chunk and state transition functions into proper file.
Let Crypto use RAID 1 chunk and state transition functions for now but this
needs fixing.
Diffstat (limited to 'sys/dev/softraid_raid0.c')
-rw-r--r-- | sys/dev/softraid_raid0.c | 108 |
1 files changed, 107 insertions, 1 deletions
diff --git a/sys/dev/softraid_raid0.c b/sys/dev/softraid_raid0.c index 2e2f7dbe6f6..66cd5f4b975 100644 --- a/sys/dev/softraid_raid0.c +++ b/sys/dev/softraid_raid0.c @@ -1,4 +1,4 @@ -/* $OpenBSD: softraid_raid0.c,v 1.4 2008/01/24 17:50:17 marco Exp $ */ +/* $OpenBSD: softraid_raid0.c,v 1.5 2008/01/24 19:58:08 marco Exp $ */ /* * Copyright (c) 2008 Marco Peereboom <marco@peereboom.us> * @@ -92,6 +92,112 @@ sr_raid0_free_resources(struct sr_discipline *sd) return (rv); } +void +sr_raid0_set_chunk_state(struct sr_discipline *sd, int c, int new_state) +{ + int old_state, s; + + DNPRINTF(SR_D_STATE, "%s: %s: %s: sr_raid_set_chunk_state %d -> %d\n", + DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname, + sd->sd_vol.sv_chunks[c]->src_meta.scm_devname, c, new_state); + + /* ok to go to splbio since this only happens in error path */ + s = splbio(); + old_state = sd->sd_vol.sv_chunks[c]->src_meta.scm_status; + + /* multiple IOs to the same chunk that fail will come through here */ + if (old_state == new_state) + goto done; + + switch (old_state) { + case BIOC_SDONLINE: + if (new_state == BIOC_SDOFFLINE) + break; + else + goto die; + break; + + case BIOC_SDOFFLINE: + goto die; + + default: +die: + splx(s); /* XXX */ + panic("%s: %s: %s: invalid chunk state transition " + "%d -> %d\n", DEVNAME(sd->sd_sc), + sd->sd_vol.sv_meta.svm_devname, + sd->sd_vol.sv_chunks[c]->src_meta.scm_devname, + old_state, new_state); + /* NOTREACHED */ + } + + sd->sd_vol.sv_chunks[c]->src_meta.scm_status = new_state; + sd->sd_set_vol_state(sd); + + sd->sd_must_flush = 1; + workq_add_task(NULL, 0, sr_save_metadata_callback, sd, NULL); +done: + splx(s); +} + +void +sr_raid0_set_vol_state(struct sr_discipline *sd) +{ + int states[SR_MAX_STATES]; + int new_state, i, s, nd; + int old_state = sd->sd_vol.sv_meta.svm_status; + + DNPRINTF(SR_D_STATE, "%s: %s: sr_raid_set_vol_state\n", + DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname); + + nd = sd->sd_vol.sv_meta.svm_no_chunk; + + for (i = 0; i < SR_MAX_STATES; i++) + states[i] = 0; + + for (i = 0; i < nd; i++) { + s = sd->sd_vol.sv_chunks[i]->src_meta.scm_status; + if (s > SR_MAX_STATES) + panic("%s: %s: %s: invalid chunk state", + DEVNAME(sd->sd_sc), + sd->sd_vol.sv_meta.svm_devname, + sd->sd_vol.sv_chunks[i]->src_meta.scm_devname); + states[s]++; + } + + if (states[BIOC_SDONLINE] == nd) + new_state = BIOC_SVONLINE; + else + new_state = BIOC_SVOFFLINE; + + DNPRINTF(SR_D_STATE, "%s: %s: sr_raid_set_vol_state %d -> %d\n", + DEVNAME(sd->sd_sc), sd->sd_vol.sv_meta.svm_devname, + old_state, new_state); + + switch (old_state) { + case BIOC_SVONLINE: + if (new_state == BIOC_SVOFFLINE) + break; + else + goto die; + break; + + case BIOC_SVOFFLINE: + /* XXX this might be a little too much */ + goto die; + + default: +die: + panic("%s: %s: invalid volume state transition " + "%d -> %d\n", DEVNAME(sd->sd_sc), + sd->sd_vol.sv_meta.svm_devname, + old_state, new_state); + /* NOTREACHED */ + } + + sd->sd_vol.sv_meta.svm_status = new_state; +} + int sr_raid0_rw(struct sr_workunit *wu) { |