diff options
author | julian <julian@FreeBSD.org> | 1998-07-20 04:12:40 +0000 |
---|---|---|
committer | julian <julian@FreeBSD.org> | 1998-07-20 04:12:40 +0000 |
commit | b2313fb5d398faac45d3afa1537ea9534045953c (patch) | |
tree | 2abf6efc06e95fb6c066ed8a1375e8061e13e153 /sys/dev/slice | |
parent | f9b168cc92876cc4eef49f8b99b11f44a46a9a46 (diff) | |
download | FreeBSD-src-b2313fb5d398faac45d3afa1537ea9534045953c.zip FreeBSD-src-b2313fb5d398faac45d3afa1537ea9534045953c.tar.gz |
Start cleaning up the aynchronous probing code for SLICE handlers.
Diffstat (limited to 'sys/dev/slice')
-rw-r--r-- | sys/dev/slice/disklabel.c | 5 | ||||
-rw-r--r-- | sys/dev/slice/mbr.c | 5 | ||||
-rw-r--r-- | sys/dev/slice/slice_base.c | 168 |
3 files changed, 106 insertions, 72 deletions
diff --git a/sys/dev/slice/disklabel.c b/sys/dev/slice/disklabel.c index 197510d..aa0fb96 100644 --- a/sys/dev/slice/disklabel.c +++ b/sys/dev/slice/disklabel.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: disklabel.c,v 1.6 1998/06/07 19:40:31 dfr Exp $ + * $Id: disklabel.c,v 1.7 1998/07/13 08:22:54 julian Exp $ */ #define BAD144 #undef BAD144 @@ -138,9 +138,7 @@ dkl_claim(sl_p slice) return (error); } } - slice->flags |= SLF_PROBING; if ((error = slice_request_block(slice, LABELSECTOR))) { - slice->flags &= ~SLF_PROBING; dkl_revoke(slice->private_up); } return (error); @@ -396,7 +394,6 @@ printf(" part %c, start=%d, size=%d\n", part + 'a', dp->p_offset, dp->p_size); } slice_start_probe(pd->subdevs[part].slice); } - slice->flags &= ~SLF_PROBING; return (0); nope: printf(" .. nope\n"); diff --git a/sys/dev/slice/mbr.c b/sys/dev/slice/mbr.c index f3eff94..a7889eb 100644 --- a/sys/dev/slice/mbr.c +++ b/sys/dev/slice/mbr.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: mbr.c,v 1.6 1998/06/07 19:40:31 dfr Exp $ + * $Id: mbr.c,v 1.7 1998/07/13 08:22:55 julian Exp $ */ #include <sys/param.h> @@ -144,9 +144,7 @@ mbr_claim(sl_p slice) return (error); } } - slice->flags |= SLF_PROBING; if ((error = slice_request_block(slice, 0))) { - slice->flags &= ~SLF_PROBING; mbr_revoke(slice->private_up); } return (error); @@ -414,7 +412,6 @@ printf(" part %d, start=%d, size=%d\n", part + 1, dp->dp_start, dp->dp_size); } slice_start_probe(pd->subdevs[part].slice); } - slice->flags &= ~SLF_PROBING; return (0); nope: mbr_revoke(pd); diff --git a/sys/dev/slice/slice_base.c b/sys/dev/slice/slice_base.c index 2752124..4aa3792 100644 --- a/sys/dev/slice/slice_base.c +++ b/sys/dev/slice/slice_base.c @@ -23,7 +23,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: slice_base.c,v 1.4 1998/06/14 19:00:12 julian Exp $ + * $Id: slice_base.c,v 1.5 1998/07/13 08:22:56 julian Exp $ */ #include <sys/param.h> @@ -82,65 +82,10 @@ sl_findtype(char *type) } /* - * Ask all known handler types if a given slice is handled by them. - * If the slice specifies a type, then just find that. - */ -void -slice_start_probe(sl_p slice) -{ - sh_p tp = types; - - if (slice->probeinfo.type == NULL) { - if(slice->handler_up == NULL) { - slice->probeinfo.trial_handler = tp; - printf("%s: probing for %s.. ",slice->name, tp->name); - (*tp->claim) (slice); - } - return; - } - - /* - * Null string ("") means "don't even try". Caller probably - * should pre-trap such cases but we'll check here too. - */ - if (slice->probeinfo.type[0]) { - tp = sl_findtype(slice->probeinfo.type); - if (tp) { - printf("%s: attaching %s..\n", slice->name, tp->name); - (*tp->claim) (slice); - } - } -} - -/* - * Move the slice probe type, on to the next type - * and call that. Called from failed probes. - */ -void -slice_probe_next(sl_p slice) -{ - sh_p tp = slice->probeinfo.trial_handler; - - if ((slice->flags & SLF_PROBING) == 0) - panic("slice_probe_next: bad call"); - if (tp != NULL) { - tp = tp->next; - slice->probeinfo.trial_handler = tp; - if (tp) { - printf("%s: probing for %s.. ",slice->name, tp->name); - (*tp->claim) (slice); - return; - } - } - slice->flags &= ~SLF_PROBING; -} - - -/* * Make a handler instantiation of the requested type. * don't take no for an answer. * force it to mark it's new territory. - * Must be called from a with a user context. + * Must be called from a within a user context. * */ static int @@ -308,9 +253,82 @@ sl_unref(sl_p slice) } +/*********************************************************************** + * Handler probing state machine support. + ***********************************************************************/ + +/* + * Ask all known handler types if a given slice is handled by them. + * If the slice specifies a type, then just find that. + * This will be done asynchronously. The claim operation may simply + * queue the work to be done. When this item has been rejected, + * control will pass to slice_probe_next(). + * This starts up the generic probeing state machine, which + * will start up the probing state machine for each handler in turn, + * until one has claimed the device, or there are no more handlers. + * + */ +void +slice_start_probe(sl_p slice) +{ + sh_p tp = types; + + if (slice->probeinfo.type == NULL) { + if(slice->handler_up == NULL) { + slice->probeinfo.trial_handler = tp; + slice->flags |= SLF_PROBING; + printf("%s: probing for %s.. ",slice->name, tp->name); + (*tp->claim) (slice); + } + return; + } + + /* + * Null string ("") means "don't even try". Caller probably + * should pre-trap such cases but we'll check here too. + * Notice that the PROBING bit is not set. + * This means that we should not do a full probe, + * but just this one handler. + */ + if (slice->probeinfo.type[0]) { + tp = sl_findtype(slice->probeinfo.type); + if (tp) { + printf("%s: attaching %s..\n", slice->name, tp->name); + (*tp->claim) (slice); + } + } +} + +/* + * Move the slice probe type, on to the next type + * and call that. Called from failed probes. + * Don't do anything if the PROBING flag has been cleared. + */ +void +slice_probe_next(sl_p slice) +{ + sh_p tp = slice->probeinfo.trial_handler; + + if ((slice->flags & SLF_PROBING) == 0) + return; + if (tp != NULL) { + if (slice->probeinfo.trial_handler = tp = tp->next) { + printf("%s: probing for %s.. ",slice->name, tp->name); + (*tp->claim) (slice); + return; + } + } + slice->flags &= ~SLF_PROBING; +} + + /* * Given a slice, launch an IOrequest for information * This is not a bulk IO routine but meant for probes etc. + * This routine may be called at interrupt time. It schedules an + * IO that will be completed asynchronously. On completion the + * Block IO system will call sl_async_done, which will trigger + * a completion event for the handler's probe state machine. */ int slice_request_block(sl_p slice, int blknum) @@ -385,7 +403,9 @@ slice_writeblock(struct slice * slice, int blkno, } /* - * called with an argument of a bp when it is completed + * called with an argument of a bp when it is completed. + * Th eslice is extracted from the operation and the completion event + * is used to trigger that slice's state machine to make the next move. */ static void sl_async_done(struct buf *bp) @@ -410,9 +430,13 @@ RR; panic("sl_async_done: unexpected write completion"); } #endif /* PARANOID */ + /* * if the IO failed, then abandon the probes and * return. Possibly ask the lower layer to try again later? + * It's assumed that a a revoke will abort the state machine. + * XXX Maybe we should call the done() routine anyhow + * and let each handler detect the failure.. */ if (bp->b_flags & B_ERROR) { (* slice->handler_up->revoke)(slice->private_up); @@ -421,24 +445,40 @@ RR; bp->b_flags |= B_INVAL | B_AGE; brelse(bp); + slice->flags &= ~SLF_PROBING; return; } - error = (* slice->handler_up->done)(slice, bp); + /* + * Call the handler's done() routine. This will + * examine the result of the probe and do whatever is needed. + * Check for abnormal error conditions. (return value non 0) + * Not claiming the slice is not an error condition. + */ + if ( (* slice->handler_up->done)(slice, bp)) { + slice->flags &= ~SLF_PROBING; + return; + } + /* * If the handler has left itself there, or cleared * the PROBING bit, then consider * probing to have come to a close. So just return. - * an IO error would be a great hint to abandon probing as well. - * we could catch that on the way up but we might want to give + * XXX An IO error would be a great hint to abandon probing as well. + * we catch that on the way up but we might want to give * the handler a chance to clean up state? */ - if (slice->handler_up) - return; - if (error) { + if (slice->handler_up || ((slice->flags & SLF_PROBING) == 0)) { slice->flags &= ~SLF_PROBING; return; } + + + /* + * The handler didn't claim it. Nor did it abort the + * probing sequence. + * Ok, so we should try the next handler to probe. + */ slice_probe_next(slice); } |