FreeBSD/sys/geom/vinum/geom_vinum_plex.c
/*
 * Handle a finished plex sync bio.
 */
Handle a finished plex sync bio.
Handle a finished plex sync bio .
int
gv_sync_complete(struct gv_plex *to, struct bio *bp)
{
	struct gv_plex *from, *p;
	struct gv_sd *s;
	struct gv_volume *v;
	struct gv_softc *sc;
	off_t offset;
	int err;
	g_topology_assert_not();
	err = 0;
	KASSERT(to != NULL, ("NULL to"));
	KASSERT(bp != NULL, ("NULL bp"));
	from = bp->bio_caller2;
	KASSERT(from != NULL, ("NULL from"));
	v = to->vol_sc;
	KASSERT(v != NULL, ("NULL v"));
	sc = v->vinumconf;
	KASSERT(sc != NULL, ("NULL sc"));
	if (bp->bio_cmd == BIO_READ) {
		err = gv_sync_request(from, to, 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);
		to->synced += bp->bio_length;
		if (bp->bio_offset + bp->bio_length >= from->size) {
			G_VINUM_DEBUG(1, "syncing of %s from %s completed",
			    to->name, from->name);
			LIST_FOREACH(s, &to->subdisks, in_plex)
				gv_set_sd_state(s, GV_SD_UP, 0);
			gv_update_plex_state(to);
			to->flags &= ~GV_PLEX_SYNCING;
			to->synced = 0;
			gv_post_event(sc, GV_EVENT_SAVE_CONFIG, sc, NULL, 0, 0);
		} else {
			offset = bp->bio_offset + bp->bio_length;
			err = gv_sync_request(from, to, offset,
			    MIN(bp->bio_length, from->size - offset),
			    BIO_READ, NULL);
		}
	}
	g_destroy_bio(bp);
	if (err) {
		to->flags &= ~GV_PLEX_SYNCING;
		G_VINUM_DEBUG(0, "error syncing plexes: error code %d", err);
	}
	g_topology_lock();
	LIST_FOREACH(p, &v->plexes, in_volume) {
		if (p->flags & GV_PLEX_SYNCING) {
			g_topology_unlock();
			return (-1);
		}
	}
	gv_access(v->provider, -1, -1, 0);
	g_topology_unlock();
	G_VINUM_DEBUG(1, "plex sync completed");
	gv_volume_flush(v);
	return (0);
}
int gv_sync_complete ( struct gv_plex * to , struct bio * bp ) { struct gv_plex * from , * p ; struct gv_sd * s ; struct gv_volume * v ; struct gv_softc * sc ; off_t offset ; int err ; g_topology_assert_not ( ) ; err = 0 ; KASSERT ( to != NULL , ( " " ) ) ; KASSERT ( bp != NULL , ( " " ) ) ; from = bp -> bio_caller2 ; KASSERT ( from != NULL , ( " " ) ) ; v = to -> vol_sc ; KASSERT ( v != NULL , ( " " ) ) ; sc = v -> vinumconf ; KASSERT ( sc != NULL , ( " " ) ) ; if ( bp -> bio_cmd == BIO_READ ) { err = gv_sync_request ( from , to , 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 ) ; to -> synced += bp -> bio_length ; if ( bp -> bio_offset + bp -> bio_length >= from -> size ) { G_VINUM_DEBUG ( 1 , " " , to -> name , from -> name ) ; LIST_FOREACH ( s , & to -> subdisks , in_plex ) gv_set_sd_state ( s , GV_SD_UP , 0 ) ; gv_update_plex_state ( to ) ; to -> flags &= ~ GV_PLEX_SYNCING ; to -> synced = 0 ; gv_post_event ( sc , GV_EVENT_SAVE_CONFIG , sc , NULL , 0 , 0 ) ; } else { offset = bp -> bio_offset + bp -> bio_length ; err = gv_sync_request ( from , to , offset , MIN ( bp -> bio_length , from -> size - offset ) , BIO_READ , NULL ) ; } } g_destroy_bio ( bp ) ; if ( err ) { to -> flags &= ~ GV_PLEX_SYNCING ; G_VINUM_DEBUG ( 0 , " " , err ) ; } g_topology_lock ( ) ; LIST_FOREACH ( p , & v -> plexes , in_volume ) { if ( p -> flags & GV_PLEX_SYNCING ) { g_topology_unlock ( ) ; return ( -1 ) ; } } gv_access ( v -> provider , -1 , -1 , 0 ) ; g_topology_unlock ( ) ; G_VINUM_DEBUG ( 1 , " " ) ; gv_volume_flush ( v ) ; return ( 0 ) ; }
Handle a finished plex sync bio.
Handle a finished plex sync bio .
/* If it was a read, write it. */ /* If it was a write, read the next one. */ /* If we're finished, clean up. */ /* Update our state. */ /* Clean up if there was an error. */ /* Check if all plexes are synced, and lower refcounts. */ /* If we came here, all plexes are synced, and we're free. */