summaryrefslogtreecommitdiff
path: root/sys/dev
diff options
context:
space:
mode:
authorJoel Sing <jsing@cvs.openbsd.org>2013-04-26 16:06:06 +0000
committerJoel Sing <jsing@cvs.openbsd.org>2013-04-26 16:06:06 +0000
commitee3df90a65c18095ff0ad82593bf5eaf66accc83 (patch)
tree061a03fe287e019c254b2f886ad02a2773ba6539 /sys/dev
parentde9d129ba9832aa82acc482990163f10048abbda (diff)
Convert RAID4/5 to new work unit completion routines.
Diffstat (limited to 'sys/dev')
-rw-r--r--sys/dev/softraid_raidp.c93
1 files changed, 35 insertions, 58 deletions
diff --git a/sys/dev/softraid_raidp.c b/sys/dev/softraid_raidp.c
index 323095f7d21..02c7d3a7e08 100644
--- a/sys/dev/softraid_raidp.c
+++ b/sys/dev/softraid_raidp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softraid_raidp.c,v 1.45 2013/04/26 15:45:35 jsing Exp $ */
+/* $OpenBSD: softraid_raidp.c,v 1.46 2013/04/26 16:06:05 jsing Exp $ */
/*
* Copyright (c) 2009 Marco Peereboom <marco@peereboom.us>
* Copyright (c) 2009 Jordan Hargrave <jordan@openbsd.org>
@@ -53,6 +53,7 @@ int sr_raidp_init(struct sr_discipline *);
int sr_raidp_rw(struct sr_workunit *);
int sr_raidp_openings(struct sr_discipline *);
void sr_raidp_intr(struct buf *);
+int sr_raidp_wu_done(struct sr_workunit *);
void sr_raidp_set_chunk_state(struct sr_discipline *, int, int);
void sr_raidp_set_vol_state(struct sr_discipline *);
@@ -86,6 +87,7 @@ sr_raidp_discipline_init(struct sr_discipline *sd, u_int8_t type)
sd->sd_openings = sr_raidp_openings;
sd->sd_scsi_rw = sr_raidp_rw;
sd->sd_scsi_intr = sr_raidp_intr;
+ sd->sd_scsi_wu_done = sr_raidp_wu_done;
sd->sd_set_chunk_state = sr_raidp_set_chunk_state;
sd->sd_set_vol_state = sr_raidp_set_vol_state;
}
@@ -517,19 +519,18 @@ void
sr_raidp_intr(struct buf *bp)
{
struct sr_ccb *ccb = (struct sr_ccb *)bp;
- struct sr_workunit *wu = ccb->ccb_wu, *wup;
+ struct sr_workunit *wu = ccb->ccb_wu;
struct sr_discipline *sd = wu->swu_dis;
- struct scsi_xfer *xs = wu->swu_xs;
- struct sr_softc *sc = sd->sd_sc;
int s;
DNPRINTF(SR_D_INTR, "%s: sr_raidp_intr bp %p xs %p\n",
- DEVNAME(sc), bp, xs);
+ DEVNAME(sd->sd_sc), bp, wu->swu_xs);
s = splbio();
-
sr_ccb_done(ccb);
+ /* XXX - Should this be done via the workq? */
+
/* XOR data to result. */
if (ccb->ccb_state == SR_CCB_OK && ccb->ccb_opaque)
sr_raidp_xor(ccb->ccb_opaque, ccb->ccb_buf.b_data,
@@ -541,66 +542,42 @@ sr_raidp_intr(struct buf *bp)
ccb->ccb_buf.b_data = NULL;
}
- DNPRINTF(SR_D_INTR, "%s: sr_intr: comp: %d count: %d failed: %d\n",
- DEVNAME(sc), wu->swu_ios_complete, wu->swu_io_count,
- wu->swu_ios_failed);
+ sr_wu_done(wu);
+ splx(s);
+}
- if (wu->swu_ios_complete < wu->swu_io_count)
- goto done;
+int
+sr_raidp_wu_done(struct sr_workunit *wu)
+{
+ struct sr_discipline *sd = wu->swu_dis;
+ struct scsi_xfer *xs = wu->swu_xs;
- if (xs != NULL)
- xs->error = XS_NOERROR;
+ /* XXX - we have no way of propagating errors... */
+ if (wu->swu_flags & SR_WUF_DISCIPLINE)
+ return SR_WU_OK;
- /* if all ios failed, retry reads and give up on writes */
- if (wu->swu_ios_failed == wu->swu_ios_complete) {
- /* XXX xs could be NULL here. */
- if (xs->flags & SCSI_DATA_IN) {
- printf("%s: retrying read on block %lld\n",
- DEVNAME(sc), ccb->ccb_buf.b_blkno);
- sr_wu_release_ccbs(wu);
- wu->swu_state = SR_WU_RESTART;
- if (sd->sd_scsi_rw(wu) == 0)
- goto done;
- xs->error = XS_DRIVER_STUFFUP;
- } else {
- printf("%s: permanently fail write on block %lld\n",
- DEVNAME(sc), ccb->ccb_buf.b_blkno);
- xs->error = XS_DRIVER_STUFFUP;
- }
+ /* XXX - This is insufficient for RAID 4/5. */
+ if (wu->swu_ios_succeeded > 0) {
+ xs->error = XS_NOERROR;
+ return SR_WU_OK;
}
- TAILQ_FOREACH(wup, &sd->sd_wu_pendq, swu_link)
- if (wu == wup)
- break;
-
- if (wup == NULL)
- panic("%s: wu %p not on pending queue",
- DEVNAME(sd->sd_sc), wu);
-
- TAILQ_REMOVE(&sd->sd_wu_pendq, wu, swu_link);
-
- if (wu->swu_collider) {
- if (wu->swu_ios_failed)
- sr_raid_recreate_wu(wu->swu_collider);
-
- /* XXX Should the collider be failed if this xs failed? */
- /* restart deferred wu */
- wu->swu_collider->swu_state = SR_WU_INPROGRESS;
- TAILQ_REMOVE(&sd->sd_wu_defq, wu->swu_collider, swu_link);
- sr_raid_startwu(wu->swu_collider);
+ if (xs->flags & SCSI_DATA_IN) {
+ printf("%s: retrying read on block %lld\n",
+ sd->sd_meta->ssd_devname, wu->swu_blk_start);
+ sr_wu_release_ccbs(wu);
+ wu->swu_state = SR_WU_RESTART;
+ if (sd->sd_scsi_rw(wu) == 0)
+ return SR_WU_RESTART;
+ } else {
+ printf("%s: permanently fail write on block %lld\n",
+ sd->sd_meta->ssd_devname, wu->swu_blk_start);
}
- if (wu->swu_flags & SR_WUF_REBUILD)
- wu->swu_flags |= SR_WUF_REBUILDIOCOMP;
- if (wu->swu_flags & SR_WUF_WAKEUP)
- wakeup(wu);
- if (wu->swu_flags & SR_WUF_DISCIPLINE)
- sr_scsi_wu_put(sd, wu);
- else if (!(wu->swu_flags & SR_WUF_REBUILD))
- sr_scsi_done(sd, xs);
+ wu->swu_state = SR_WU_FAILED;
+ xs->error = XS_DRIVER_STUFFUP;
-done:
- splx(s);
+ return SR_WU_FAILED;
}
int