FreeBSD/sys/geom/vinum/geom_vinum_plex.c
/*
 * Finish handling of a bio to a growing plex.
 */
Finish handling of a bio to a growing plex.
Finish handling of a bio to a growing plex .
void
gv_grow_complete(struct gv_plex *p, struct bio *bp)
{
	struct gv_softc *sc;
	struct gv_sd *s;
	struct gv_volume *v;
	off_t origsize, offset;
	int sdcount, err;
	v = p->vol_sc;
	KASSERT(v != NULL, ("gv_grow_complete: NULL v"));
	sc = v->vinumconf;
	KASSERT(sc != NULL, ("gv_grow_complete: NULL sc"));
	err = 0;
	if (bp->bio_cmd == BIO_READ) {
		p->synced += bp->bio_length;
		err = gv_grow_request(p, bp->bio_offset, bp->bio_length,
		    BIO_WRITE, bp->bio_data);
	} else if (bp->bio_cmd == BIO_WRITE) {
		if (bp->bio_pflags & GV_BIO_MALLOC)
			g_free(bp->bio_data);
		sdcount = gv_sdcount(p, 1);
		s = LIST_FIRST(&p->subdisks);
		KASSERT(s != NULL, ("NULL s"));
		origsize = (s->size * (sdcount - 1));
		if (bp->bio_offset + bp->bio_length >= origsize) {
			G_VINUM_DEBUG(1, "growing of %s completed", p->name);
			p->flags &= ~GV_PLEX_GROWING;
			LIST_FOREACH(s, &p->subdisks, in_plex) {
				s->flags &= ~GV_SD_GROW;
				gv_set_sd_state(s, GV_SD_UP, 0);
			}
			p->size = gv_plex_size(p);
			gv_update_vol_size(v, gv_vol_size(v));
			gv_set_plex_state(p, GV_PLEX_UP, 0);
			g_topology_lock();
			gv_access(v->provider, -1, -1, 0);
			g_topology_unlock();
			p->synced = 0;
			gv_post_event(sc, GV_EVENT_SAVE_CONFIG, sc, NULL, 0, 0);
			gv_plex_flush(p);
		} else {
			offset = bp->bio_offset + bp->bio_length;
			err = gv_grow_request(p, offset,
			   MIN(bp->bio_length, origsize - offset),
			   BIO_READ, NULL);
		}
	}
	g_destroy_bio(bp);
	if (err) {
		p->flags &= ~GV_PLEX_GROWING;
		G_VINUM_DEBUG(0, "error growing plex: error code %d", err);
	}
}
void gv_grow_complete ( struct gv_plex * p , struct bio * bp ) { struct gv_softc * sc ; struct gv_sd * s ; struct gv_volume * v ; off_t origsize , offset ; int sdcount , err ; v = p -> vol_sc ; KASSERT ( v != NULL , ( " " ) ) ; sc = v -> vinumconf ; KASSERT ( sc != NULL , ( " " ) ) ; err = 0 ; if ( bp -> bio_cmd == BIO_READ ) { p -> synced += bp -> bio_length ; err = gv_grow_request ( p , bp -> bio_offset , bp -> bio_length , BIO_WRITE , bp -> bio_data ) ; } else if ( bp -> bio_cmd == BIO_WRITE ) { if ( bp -> bio_pflags & GV_BIO_MALLOC ) g_free ( bp -> bio_data ) ; sdcount = gv_sdcount ( p , 1 ) ; s = LIST_FIRST ( & p -> subdisks ) ; KASSERT ( s != NULL , ( " " ) ) ; origsize = ( s -> size * ( sdcount - 1 ) ) ; if ( bp -> bio_offset + bp -> bio_length >= origsize ) { G_VINUM_DEBUG ( 1 , " " , p -> name ) ; p -> flags &= ~ GV_PLEX_GROWING ; LIST_FOREACH ( s , & p -> subdisks , in_plex ) { s -> flags &= ~ GV_SD_GROW ; gv_set_sd_state ( s , GV_SD_UP , 0 ) ; } p -> size = gv_plex_size ( p ) ; gv_update_vol_size ( v , gv_vol_size ( v ) ) ; gv_set_plex_state ( p , GV_PLEX_UP , 0 ) ; g_topology_lock ( ) ; gv_access ( v -> provider , -1 , -1 , 0 ) ; g_topology_unlock ( ) ; p -> synced = 0 ; gv_post_event ( sc , GV_EVENT_SAVE_CONFIG , sc , NULL , 0 , 0 ) ; gv_plex_flush ( p ) ; } else { offset = bp -> bio_offset + bp -> bio_length ; err = gv_grow_request ( p , offset , MIN ( bp -> bio_length , origsize - offset ) , BIO_READ , NULL ) ; } } g_destroy_bio ( bp ) ; if ( err ) { p -> flags &= ~ GV_PLEX_GROWING ; G_VINUM_DEBUG ( 0 , " " , err ) ; } }
Finish handling of a bio to a growing plex.
Finish handling of a bio to a growing plex .
/* If it was a read, write it. */ /* If it was a write, read next. */ /* Find the real size of the plex. */ /* Issue delayed requests. */