FreeBSD/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev_geom.c
/*
 * Issue one or more bios to the vdev in parallel
 * cmds, datas, offsets, errors, and sizes are arrays of length ncmds.  Each IO
 * operation is described by parallel entries from each array.  There may be
 * more bios actually issued than entries in the array
 */
Issue one or more bios to the vdev in parallel
cmds, datas, offsets, errors, and sizes are arrays of length ncmds.  Each IO
operation is described by parallel entries from each array.  There may be
more bios actually issued than entries in the array
Issue one or more bios to the vdev in parallel cmds datas offsets errors and sizes are arrays of length ncmds . Each IO operation is described by parallel entries from each array . There may be more bios actually issued than entries in the array
static void
vdev_geom_io(struct g_consumer *cp, int *cmds, void **datas, off_t *offsets,
    off_t *sizes, int *errors, int ncmds)
{
	struct bio **bios;
	u_char *p;
	off_t off, maxio, s, end;
	int i, n_bios, j;
	size_t bios_size;
	maxio = MAXPHYS - (MAXPHYS % cp->provider->sectorsize);
	n_bios = 0;
	for (i = 0; i < ncmds; i++)
		n_bios += (sizes[i] + maxio - 1) / maxio;
	bios_size = n_bios * sizeof(struct bio*);
	bios = kmem_zalloc(bios_size, KM_SLEEP);
	for (i = j = 0; i < ncmds; i++) {
		off = offsets[i];
		p = datas[i];
		s = sizes[i];
		end = off + s;
		ASSERT((off % cp->provider->sectorsize) == 0);
		ASSERT((s % cp->provider->sectorsize) == 0);
		for (; off < end; off += maxio, p += maxio, s -= maxio, j++) {
			bios[j] = g_alloc_bio();
			bios[j]->bio_cmd = cmds[i];
			bios[j]->bio_done = NULL;
			bios[j]->bio_offset = off;
			bios[j]->bio_length = MIN(s, maxio);
			bios[j]->bio_data = p;
			g_io_request(bios[j], cp);
		}
	}
	ASSERT(j == n_bios);
	for (i = j = 0; i < ncmds; i++) {
		off = offsets[i];
		s = sizes[i];
		end = off + s;
		for (; off < end; off += maxio, s -= maxio, j++) {
			errors[i] = biowait(bios[j], "vdev_geom_io") || errors[i];
			g_destroy_bio(bios[j]);
		}
	}
	kmem_free(bios, bios_size);
}
static void vdev_geom_io ( struct g_consumer * cp , int * cmds , void * * datas , off_t * offsets , off_t * sizes , int * errors , int ncmds ) { struct bio * * bios ; u_char * p ; off_t off , maxio , s , end ; int i , n_bios , j ; size_t bios_size ; maxio = MAXPHYS - ( MAXPHYS % cp -> provider -> sectorsize ) ; n_bios = 0 ; for ( i = 0 ; i < ncmds ; i ++ ) n_bios += ( sizes [ i ] + maxio - 1 ) / maxio ; bios_size = n_bios * sizeof ( struct bio * ) ; bios = kmem_zalloc ( bios_size , KM_SLEEP ) ; for ( i = j = 0 ; i < ncmds ; i ++ ) { off = offsets [ i ] ; p = datas [ i ] ; s = sizes [ i ] ; end = off + s ; ASSERT ( ( off % cp -> provider -> sectorsize ) == 0 ) ; ASSERT ( ( s % cp -> provider -> sectorsize ) == 0 ) ; for ( ; off < end ; off += maxio , p += maxio , s -= maxio , j ++ ) { bios [ j ] = g_alloc_bio ( ) ; bios [ j ] -> bio_cmd = cmds [ i ] ; bios [ j ] -> bio_done = NULL ; bios [ j ] -> bio_offset = off ; bios [ j ] -> bio_length = MIN ( s , maxio ) ; bios [ j ] -> bio_data = p ; g_io_request ( bios [ j ] , cp ) ; } } ASSERT ( j == n_bios ) ; for ( i = j = 0 ; i < ncmds ; i ++ ) { off = offsets [ i ] ; s = sizes [ i ] ; end = off + s ; for ( ; off < end ; off += maxio , s -= maxio , j ++ ) { errors [ i ] = biowait ( bios [ j ] , " " ) || errors [ i ] ; g_destroy_bio ( bios [ j ] ) ; } } kmem_free ( bios , bios_size ) ; }
Issue one or more bios to the vdev in parallel
 cmds, datas, offsets, errors, and sizes are arrays of length ncmds.
Issue one or more bios to the vdev in parallel cmds datas offsets errors and sizes are arrays of length ncmds .
/* How many bios are required for all commands ? */ /* Allocate memory for the bios */ /* Prepare and issue all of the bios */ /* Wait for all of the bios to complete, and clean them up */