diff options
author | Joel Sing <jsing@cvs.openbsd.org> | 2013-04-21 13:00:22 +0000 |
---|---|---|
committer | Joel Sing <jsing@cvs.openbsd.org> | 2013-04-21 13:00:22 +0000 |
commit | 1506227fb7bf0e35a5d09a78acdd4aba82ec2d9a (patch) | |
tree | cb3f0ca03efc81178a0a9aa59dcbcc5d23399060 /sys/dev/softraid.c | |
parent | 2a9984d3a338db73d4aaad8fc601709de644742e (diff) |
Convert RAID1 to the new work unit completion functions and generic
interrupt handler. Disciplines such as RAID1/4/5/6 need a way to intercept
I/O when the work unit is complete, but before the SCSI xfer is complete.
This is provided via a sd_scsi_wu_done hook, which enables work units to be
restarted or otherwise modified before the SCSI xfer completion occurs.
ok krw@
Diffstat (limited to 'sys/dev/softraid.c')
-rw-r--r-- | sys/dev/softraid.c | 32 |
1 files changed, 23 insertions, 9 deletions
diff --git a/sys/dev/softraid.c b/sys/dev/softraid.c index 3a71a25c643..e75ca773d73 100644 --- a/sys/dev/softraid.c +++ b/sys/dev/softraid.c @@ -1,4 +1,4 @@ -/* $OpenBSD: softraid.c,v 1.299 2013/03/31 15:46:11 jsing Exp $ */ +/* $OpenBSD: softraid.c,v 1.300 2013/04/21 13:00:21 jsing Exp $ */ /* * Copyright (c) 2007, 2008, 2009 Marco Peereboom <marco@peereboom.us> * Copyright (c) 2008 Chris Kuethe <ckuethe@openbsd.org> @@ -2255,36 +2255,49 @@ sr_wu_done_callback(void *arg1, void *arg2) s = splbio(); + if (wu->swu_ios_failed) + xs->error = XS_DRIVER_STUFFUP; + else + xs->error = XS_NOERROR; + + if (sd->sd_scsi_wu_done) { + if (sd->sd_scsi_wu_done(wu) == SR_WU_RESTART) + goto done; + } + + /* Remove work unit from pending queue. */ TAILQ_FOREACH(wup, &sd->sd_wu_pendq, swu_link) if (wup == wu) 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? */ 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 (wu->swu_ios_failed) - xs->error = XS_DRIVER_STUFFUP; - else - xs->error = XS_NOERROR; - /* * If a discipline provides its own sd_scsi_done function, then it * is responsible for calling sr_scsi_done() once I/O is complete. */ + if (wu->swu_flags & SR_WUF_REBUILD) + wu->swu_flags |= SR_WUF_REBUILDIOCOMP; + if (wu->swu_flags & SR_WUF_WAKEUP) + wakeup(wu); if (sd->sd_scsi_done) sd->sd_scsi_done(wu); - else + else if (!(wu->swu_flags & SR_WUF_REBUILD)) sr_scsi_done(sd, xs); +done: splx(s); } @@ -3892,6 +3905,7 @@ sr_discipline_init(struct sr_discipline *sd, int level) sd->sd_scsi_sync = sr_raid_sync; sd->sd_scsi_rw = NULL; sd->sd_scsi_intr = sr_raid_intr; + sd->sd_scsi_wu_done = NULL; sd->sd_scsi_done = NULL; sd->sd_set_chunk_state = sr_set_chunk_state; sd->sd_set_vol_state = sr_set_vol_state; |