summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/dev/softraid.c212
-rw-r--r--sys/dev/softraid_raid0.c108
-rw-r--r--sys/dev/softraid_raid1.c198
-rw-r--r--sys/dev/softraidvar.h20
4 files changed, 325 insertions, 213 deletions
diff --git a/sys/dev/softraid.c b/sys/dev/softraid.c
index 6bdbecf4e25..b03137755e2 100644
--- a/sys/dev/softraid.c
+++ b/sys/dev/softraid.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid.c,v 1.95 2008/01/24 17:50:17 marco Exp $ */
+/* $OpenBSD: softraid.c,v 1.96 2008/01/24 19:58:08 marco Exp $ */
/*
* Copyright (c) 2007 Marco Peereboom <marco@peereboom.us>
*
@@ -107,7 +107,6 @@ void sr_print_uuid(struct sr_uuid *, int);
u_int32_t sr_checksum(char *, u_int32_t *, u_int32_t);
int sr_clear_metadata(struct sr_discipline *);
int sr_save_metadata(struct sr_discipline *, u_int32_t);
-void sr_save_metadata_callback(void *, void *);
int sr_boot_assembly(struct sr_softc *);
int sr_already_assembled(struct sr_discipline *);
int sr_validate_metadata(struct sr_softc *, dev_t,
@@ -886,8 +885,8 @@ sr_ioctl_createraid(struct sr_softc *sc, struct bioc_createraid *bc, int user)
sd->sd_scsi_start_stop = sr_raid_start_stop;
sd->sd_scsi_sync = sr_raid_sync;
sd->sd_scsi_rw = sr_raid0_rw;
- sd->sd_set_chunk_state = sr_raid_set_chunk_state;
- sd->sd_set_vol_state = sr_raid_set_vol_state;
+ sd->sd_set_chunk_state = sr_raid0_set_chunk_state;
+ sd->sd_set_vol_state = sr_raid0_set_vol_state;
break;
case 1:
/* fill out discipline members */
@@ -905,8 +904,8 @@ sr_ioctl_createraid(struct sr_softc *sc, struct bioc_createraid *bc, int user)
sd->sd_scsi_start_stop = sr_raid_start_stop;
sd->sd_scsi_sync = sr_raid_sync;
sd->sd_scsi_rw = sr_raid1_rw;
- sd->sd_set_chunk_state = sr_raid_set_chunk_state;
- sd->sd_set_vol_state = sr_raid_set_vol_state;
+ sd->sd_set_chunk_state = sr_raid1_set_chunk_state;
+ sd->sd_set_vol_state = sr_raid1_set_vol_state;
break;
#ifdef CRYPTO
case 'C':
@@ -925,8 +924,9 @@ sr_ioctl_createraid(struct sr_softc *sc, struct bioc_createraid *bc, int user)
sd->sd_scsi_start_stop = sr_raid_start_stop;
sd->sd_scsi_sync = sr_raid_sync;
sd->sd_scsi_rw = sr_crypto_rw;
- sd->sd_set_chunk_state = sr_raid_set_chunk_state;
- sd->sd_set_vol_state = sr_raid_set_vol_state;
+ /* XXX reuse raid 1 functions for now FIXME */
+ sd->sd_set_chunk_state = sr_raid1_set_chunk_state;
+ sd->sd_set_vol_state = sr_raid1_set_vol_state;
break;
#endif
default:
@@ -1555,202 +1555,6 @@ sr_raid_startwu(struct sr_workunit *wu)
}
}
-void
-sr_raid_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:
- switch (new_state) {
- case BIOC_SDOFFLINE:
- break;
- case BIOC_SDSCRUB:
- break;
- default:
- goto die;
- }
- break;
-
- case BIOC_SDOFFLINE:
- if (new_state == BIOC_SDREBUILD) {
- ;
- } else
- goto die;
- break;
-
- case BIOC_SDSCRUB:
- if (new_state == BIOC_SDONLINE) {
- ;
- } else
- goto die;
- break;
-
- case BIOC_SDREBUILD:
- if (new_state == BIOC_SDONLINE) {
- ;
- } else
- goto die;
- break;
-
- case BIOC_SDHOTSPARE:
- if (new_state == BIOC_SDREBUILD) {
- ;
- } else
- goto die;
- break;
-
- 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_raid_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 if (states[BIOC_SDONLINE] == 0)
- new_state = BIOC_SVOFFLINE;
- else if (states[BIOC_SDSCRUB] != 0)
- new_state = BIOC_SVSCRUB;
- else if (states[BIOC_SDREBUILD] != 0)
- new_state = BIOC_SVREBUILD;
- else if (states[BIOC_SDOFFLINE] != 0)
- new_state = BIOC_SVDEGRADED;
- else {
- printf("old_state = %d, ", old_state);
- for (i = 0; i < nd; i++)
- printf("%d = %d, ", i,
- sd->sd_vol.sv_chunks[i]->src_meta.scm_status);
- panic("invalid new_state");
- }
-
- 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:
- switch (new_state) {
- case BIOC_SVOFFLINE:
- case BIOC_SVDEGRADED:
- break;
- default:
- goto die;
- }
- break;
-
- case BIOC_SVOFFLINE:
- /* XXX this might be a little too much */
- goto die;
-
- case BIOC_SVSCRUB:
- switch (new_state) {
- case BIOC_SVONLINE:
- case BIOC_SVOFFLINE:
- case BIOC_SVDEGRADED:
- case BIOC_SVSCRUB: /* can go to same state */
- break;
- default:
- goto die;
- }
- break;
-
- case BIOC_SVBUILDING:
- switch (new_state) {
- case BIOC_SVONLINE:
- case BIOC_SVOFFLINE:
- case BIOC_SVBUILDING: /* can go to the same state */
- break;
- default:
- goto die;
- }
- break;
-
- case BIOC_SVREBUILD:
- switch (new_state) {
- case BIOC_SVONLINE:
- case BIOC_SVOFFLINE:
- case BIOC_SVREBUILD: /* can go to the same state */
- break;
- default:
- goto die;
- }
- break;
-
- case BIOC_SVDEGRADED:
- switch (new_state) {
- case BIOC_SVOFFLINE:
- case BIOC_SVREBUILD:
- case BIOC_SVDEGRADED: /* can go to the same state */
- break;
- default:
- goto die;
- }
- break;
-
- 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;
-}
-
u_int32_t
sr_checksum(char *s, u_int32_t *p, u_int32_t size)
{
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)
{
diff --git a/sys/dev/softraid_raid1.c b/sys/dev/softraid_raid1.c
index 6e20c959802..933c5d57a54 100644
--- a/sys/dev/softraid_raid1.c
+++ b/sys/dev/softraid_raid1.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid_raid1.c,v 1.2 2008/01/24 17:50:17 marco Exp $ */
+/* $OpenBSD: softraid_raid1.c,v 1.3 2008/01/24 19:58:08 marco Exp $ */
/*
* Copyright (c) 2007 Marco Peereboom <marco@peereboom.us>
*
@@ -86,6 +86,202 @@ sr_raid1_free_resources(struct sr_discipline *sd)
return (rv);
}
+void
+sr_raid1_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:
+ switch (new_state) {
+ case BIOC_SDOFFLINE:
+ break;
+ case BIOC_SDSCRUB:
+ break;
+ default:
+ goto die;
+ }
+ break;
+
+ case BIOC_SDOFFLINE:
+ if (new_state == BIOC_SDREBUILD) {
+ ;
+ } else
+ goto die;
+ break;
+
+ case BIOC_SDSCRUB:
+ if (new_state == BIOC_SDONLINE) {
+ ;
+ } else
+ goto die;
+ break;
+
+ case BIOC_SDREBUILD:
+ if (new_state == BIOC_SDONLINE) {
+ ;
+ } else
+ goto die;
+ break;
+
+ case BIOC_SDHOTSPARE:
+ if (new_state == BIOC_SDREBUILD) {
+ ;
+ } else
+ goto die;
+ break;
+
+ 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_raid1_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 if (states[BIOC_SDONLINE] == 0)
+ new_state = BIOC_SVOFFLINE;
+ else if (states[BIOC_SDSCRUB] != 0)
+ new_state = BIOC_SVSCRUB;
+ else if (states[BIOC_SDREBUILD] != 0)
+ new_state = BIOC_SVREBUILD;
+ else if (states[BIOC_SDOFFLINE] != 0)
+ new_state = BIOC_SVDEGRADED;
+ else {
+ printf("old_state = %d, ", old_state);
+ for (i = 0; i < nd; i++)
+ printf("%d = %d, ", i,
+ sd->sd_vol.sv_chunks[i]->src_meta.scm_status);
+ panic("invalid new_state");
+ }
+
+ 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:
+ switch (new_state) {
+ case BIOC_SVOFFLINE:
+ case BIOC_SVDEGRADED:
+ break;
+ default:
+ goto die;
+ }
+ break;
+
+ case BIOC_SVOFFLINE:
+ /* XXX this might be a little too much */
+ goto die;
+
+ case BIOC_SVSCRUB:
+ switch (new_state) {
+ case BIOC_SVONLINE:
+ case BIOC_SVOFFLINE:
+ case BIOC_SVDEGRADED:
+ case BIOC_SVSCRUB: /* can go to same state */
+ break;
+ default:
+ goto die;
+ }
+ break;
+
+ case BIOC_SVBUILDING:
+ switch (new_state) {
+ case BIOC_SVONLINE:
+ case BIOC_SVOFFLINE:
+ case BIOC_SVBUILDING: /* can go to the same state */
+ break;
+ default:
+ goto die;
+ }
+ break;
+
+ case BIOC_SVREBUILD:
+ switch (new_state) {
+ case BIOC_SVONLINE:
+ case BIOC_SVOFFLINE:
+ case BIOC_SVREBUILD: /* can go to the same state */
+ break;
+ default:
+ goto die;
+ }
+ break;
+
+ case BIOC_SVDEGRADED:
+ switch (new_state) {
+ case BIOC_SVOFFLINE:
+ case BIOC_SVREBUILD:
+ case BIOC_SVDEGRADED: /* can go to the same state */
+ break;
+ default:
+ goto die;
+ }
+ break;
+
+ 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_raid1_rw(struct sr_workunit *wu)
{
diff --git a/sys/dev/softraidvar.h b/sys/dev/softraidvar.h
index 3bd4d3e6c81..a9bd161007f 100644
--- a/sys/dev/softraidvar.h
+++ b/sys/dev/softraidvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraidvar.h,v 1.37 2008/01/24 13:58:14 marco Exp $ */
+/* $OpenBSD: softraidvar.h,v 1.38 2008/01/24 19:58:08 marco Exp $ */
/*
* Copyright (c) 2006 Marco Peereboom <marco@peereboom.us>
*
@@ -359,6 +359,10 @@ void sr_free_wu(struct sr_discipline *);
struct sr_workunit *sr_get_wu(struct sr_discipline *);
void sr_put_wu(struct sr_workunit *);
+/* misc functions */
+int32_t sr_validate_stripsize(u_int32_t);
+void sr_save_metadata_callback(void *, void *);
+
/* discipline functions */
int sr_raid_inquiry(struct sr_workunit *);
int sr_raid_read_cap(struct sr_workunit *);
@@ -366,17 +370,16 @@ int sr_raid_tur(struct sr_workunit *);
int sr_raid_request_sense( struct sr_workunit *);
int sr_raid_start_stop(struct sr_workunit *);
int sr_raid_sync(struct sr_workunit *);
-void sr_raid_set_chunk_state(struct sr_discipline *,
- int, int);
-void sr_raid_set_vol_state(struct sr_discipline *);
void sr_raid_startwu(struct sr_workunit *);
-int32_t sr_validate_stripsize(u_int32_t);
/* raid 0 */
int sr_raid0_alloc_resources(struct sr_discipline *);
int sr_raid0_free_resources(struct sr_discipline *);
int sr_raid0_rw(struct sr_workunit *);
void sr_raid0_intr(struct buf *);
+void sr_raid0_set_chunk_state(struct sr_discipline *,
+ int, int);
+void sr_raid0_set_vol_state(struct sr_discipline *);
/* raid 1 */
int sr_raid1_alloc_resources(struct sr_discipline *);
@@ -384,10 +387,13 @@ int sr_raid1_free_resources(struct sr_discipline *);
int sr_raid1_rw(struct sr_workunit *);
void sr_raid1_intr(struct buf *);
void sr_raid1_recreate_wu(struct sr_workunit *);
+void sr_raid1_set_chunk_state(struct sr_discipline *,
+ int, int);
+void sr_raid1_set_vol_state(struct sr_discipline *);
/* crypto discipline */
-struct cryptop * sr_crypto_getcryptop(struct sr_workunit *, int);
-void * sr_crypto_putcryptop(struct cryptop *);
+struct cryptop *sr_crypto_getcryptop(struct sr_workunit *, int);
+void *sr_crypto_putcryptop(struct cryptop *);
int sr_crypto_alloc_resources(struct sr_discipline *);
int sr_crypto_free_resources(struct sr_discipline *);
int sr_crypto_rw(struct sr_workunit *);