FreeBSD/sys/geom/vinum/geom_vinum_plex.c
/*
 * Prepare a normal plex request.
 */
Prepare a normal plex request.
Prepare a normal plex request .
static int 
gv_plex_normal_request(struct gv_plex *p, struct bio *bp, off_t boff,
    off_t bcount,  caddr_t addr)
{
	struct gv_sd *s;
	struct bio *cbp;
	off_t real_len, real_off;
	int i, err, sdno;
	s = NULL;
	sdno = -1;
	real_len = real_off = 0;
	err = ENXIO;
	if (p == NULL || LIST_EMPTY(&p->subdisks)) 
		goto bad;
	err = gv_plex_offset(p, boff, bcount, &real_off,
	    &real_len, &sdno, (bp->bio_pflags & GV_BIO_GROW));
	if (err == GV_ERR_ISBUSY) {
		bioq_disksort(p->rqueue, bp);
		return (-1); 
	}
	if (err) {
		err = ENXIO;
		goto bad;
	}
	err = ENXIO;
	i = 0;
	LIST_FOREACH(s, &p->subdisks, in_plex) {
		if (i == sdno)
			break;
		i++;
	}
	if (s == NULL || s->drive_sc == NULL)
		goto bad;
	switch (s->state) {
	case GV_SD_UP:
		break;
	case GV_SD_DOWN:
		if (bp->bio_pflags & GV_BIO_INTERNAL)
			G_VINUM_DEBUG(0, "subdisk must be in the stale state in"
			    " order to perform administrative requests");
		goto bad;
	case GV_SD_STALE:
		if (!(bp->bio_pflags & GV_BIO_SYNCREQ)) {
			G_VINUM_DEBUG(0, "subdisk stale, unable to perform "
			    "regular requests");
			goto bad;
		}
		G_VINUM_DEBUG(1, "sd %s is initializing", s->name);
		gv_set_sd_state(s, GV_SD_INITIALIZING, GV_SETSTATE_FORCE);
		break;
	case GV_SD_INITIALIZING:
		if (bp->bio_cmd == BIO_READ)
			goto bad;
		break;
	default:
		goto bad;
	}
	cbp = g_clone_bio(bp);
	if (cbp == NULL) {
		err = ENOMEM;
		goto bad;
	}
	cbp->bio_offset = real_off + s->drive_offset;
	cbp->bio_length = real_len;
	cbp->bio_data = addr;
	cbp->bio_done = gv_done;
	cbp->bio_caller1 = s;
	bioq_insert_tail(p->bqueue, cbp); 
	return (real_len);
bad:
	G_VINUM_LOGREQ(0, bp, "plex request failed.");
	if (bp->bio_pflags & GV_BIO_INTERNAL) {
		if (bp->bio_pflags & GV_BIO_MALLOC)
			g_free(bp->bio_data);
		g_destroy_bio(bp);
		p->flags &= ~(GV_PLEX_SYNCING | GV_PLEX_REBUILDING |
		    GV_PLEX_GROWING);
		return (-1);
	}
	g_io_deliver(bp, err);
	return (-1);
}
static int gv_plex_normal_request ( struct gv_plex * p , struct bio * bp , off_t boff , off_t bcount , caddr_t addr ) { struct gv_sd * s ; struct bio * cbp ; off_t real_len , real_off ; int i , err , sdno ; s = NULL ; sdno = -1 ; real_len = real_off = 0 ; err = ENXIO ; if ( p == NULL || LIST_EMPTY ( & p -> subdisks ) ) goto bad ; err = gv_plex_offset ( p , boff , bcount , & real_off , & real_len , & sdno , ( bp -> bio_pflags & GV_BIO_GROW ) ) ; if ( err == GV_ERR_ISBUSY ) { bioq_disksort ( p -> rqueue , bp ) ; return ( -1 ) ; } if ( err ) { err = ENXIO ; goto bad ; } err = ENXIO ; i = 0 ; LIST_FOREACH ( s , & p -> subdisks , in_plex ) { if ( i == sdno ) break ; i ++ ; } if ( s == NULL || s -> drive_sc == NULL ) goto bad ; switch ( s -> state ) { case GV_SD_UP : break ; case GV_SD_DOWN : if ( bp -> bio_pflags & GV_BIO_INTERNAL ) G_VINUM_DEBUG ( 0 , " " " " ) ; goto bad ; case GV_SD_STALE : if ( ! ( bp -> bio_pflags & GV_BIO_SYNCREQ ) ) { G_VINUM_DEBUG ( 0 , " " " " ) ; goto bad ; } G_VINUM_DEBUG ( 1 , " " , s -> name ) ; gv_set_sd_state ( s , GV_SD_INITIALIZING , GV_SETSTATE_FORCE ) ; break ; case GV_SD_INITIALIZING : if ( bp -> bio_cmd == BIO_READ ) goto bad ; break ; default : goto bad ; } cbp = g_clone_bio ( bp ) ; if ( cbp == NULL ) { err = ENOMEM ; goto bad ; } cbp -> bio_offset = real_off + s -> drive_offset ; cbp -> bio_length = real_len ; cbp -> bio_data = addr ; cbp -> bio_done = gv_done ; cbp -> bio_caller1 = s ; bioq_insert_tail ( p -> bqueue , cbp ) ; return ( real_len ) ; bad : G_VINUM_LOGREQ ( 0 , bp , " " ) ; if ( bp -> bio_pflags & GV_BIO_INTERNAL ) { if ( bp -> bio_pflags & GV_BIO_MALLOC ) g_free ( bp -> bio_data ) ; g_destroy_bio ( bp ) ; p -> flags &= ~ ( GV_PLEX_SYNCING | GV_PLEX_REBUILDING | GV_PLEX_GROWING ) ; return ( -1 ) ; } g_io_deliver ( bp , err ) ; return ( -1 ) ; }
Prepare a normal plex request.
Prepare a normal plex request .
/* If the request was blocked, put it into wait. */ /* "Fail", and delay request. */ /* Find the right subdisk. */ /* Subdisk not found. */ /* Now check if we can handle the request on this subdisk. */ /* If the subdisk is up, just continue. */ /* All other subdisk states mean it's not accessible. */ /* Clone the bio and adjust the offsets and sizes. */ /* Store the sub-requests now and let others issue them. */ /* Building the sub-request failed. If internal BIO, do not deliver. */