Start cleaning up the aynchronous probing code for SLICE handlers.

This commit is contained in:
Julian Elischer 1998-07-20 04:12:40 +00:00
parent 9713f575e4
commit d73cede61f
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=37768
3 changed files with 106 additions and 72 deletions

View File

@ -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");

View File

@ -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);

View File

@ -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>
@ -81,66 +81,11 @@ sl_findtype(char *type)
return (NULL);
}
/*
* 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);
}