diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2013-04-26 16:06:06 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2013-04-26 16:06:06 +0000 |
commit | ee3df90a65c18095ff0ad82593bf5eaf66accc83 (patch) | |
tree | 061a03fe287e019c254b2f886ad02a2773ba6539 /sys/dev | |
parent | de9d129ba9832aa82acc482990163f10048abbda (diff) |
Convert RAID4/5 to new work unit completion routines.
Diffstat (limited to 'sys/dev')
-rw-r--r-- | sys/dev/softraid_raidp.c | 93 |
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 |