sys/dev/disk/dm/targets/striped/dm_target_striped.c
static int
dm_target_stripe_strategy(dm_table_entry_t *table_en, struct buf *bp)
{
	dm_target_stripe_config_t *tsc;
	struct bio *bio = &bp->b_bio1;
	struct buf *nestbuf;
	uint64_t blkno, blkoff;
	uint64_t stripe, blknr;
	uint32_t stripe_off, stripe_rest, num_blks, issue_blks;
	int devnr;

	tsc = table_en->target_config;
	if (tsc == NULL)
		return 0;

	/* calculate extent of request */
	KKASSERT(bp->b_resid % DEV_BSIZE == 0);

	switch(bp->b_cmd) {
	case BUF_CMD_READ:
	case BUF_CMD_WRITE:
	case BUF_CMD_FREEBLKS:
		/*
		 * Loop through to individual operations
		 */
		blkno = bp->b_bio1.bio_offset / DEV_BSIZE;
		blkoff = 0;
		num_blks = bp->b_resid / DEV_BSIZE;
		nestiobuf_init(bio);

		while (num_blks > 0) {
			/* blockno to strip piece nr */
			stripe = blkno / tsc->stripe_chunksize;
			stripe_off = blkno % tsc->stripe_chunksize;

			/* where we are inside the strip */
			devnr = stripe % tsc->stripe_num;
			blknr = stripe / tsc->stripe_num;

			/* how much is left before we hit a boundary */
			stripe_rest = tsc->stripe_chunksize - stripe_off;

			/* issue this piece on stripe `stripe' */
			issue_blks = MIN(stripe_rest, num_blks);
			nestbuf = getpbuf(NULL);
			nestbuf->b_flags |= bio->bio_buf->b_flags & B_HASBOGUS;

			nestiobuf_add(bio, nestbuf, blkoff,
					issue_blks * DEV_BSIZE, NULL);

			/* I need number of bytes. */
			nestbuf->b_bio1.bio_offset =
				blknr * tsc->stripe_chunksize + stripe_off;
			nestbuf->b_bio1.bio_offset +=
				tsc->stripe_devs[devnr].offset;
			nestbuf->b_bio1.bio_offset *= DEV_BSIZE;

			vn_strategy(tsc->stripe_devs[devnr].pdev->pdev_vnode,
				    &nestbuf->b_bio1);

			blkno += issue_blks;
			blkoff += issue_blks * DEV_BSIZE;
			num_blks -= issue_blks;
		}
		nestiobuf_start(bio);
		break;
	case BUF_CMD_FLUSH:
		nestiobuf_init(bio);
		for (devnr = 0; devnr < tsc->stripe_num; ++devnr) {
			nestbuf = getpbuf(NULL);
			nestbuf->b_flags |= bio->bio_buf->b_flags & B_HASBOGUS;

			nestiobuf_add(bio, nestbuf, 0, 0, NULL);
			nestbuf->b_bio1.bio_offset = 0;
			vn_strategy(tsc->stripe_devs[devnr].pdev->pdev_vnode,
				    &nestbuf->b_bio1);
		}
		nestiobuf_start(bio);
		break;
	default:
		bp->b_flags |= B_ERROR;
		bp->b_error = EIO;
		biodone(bio);
		break;
	}
	return 0;
}
/*
 * Strategy routine called from dm_strategy.
 */
Strategy routine called from dm_strategy.
Strategy routine called from dm_strategy .
static int
dm_target_stripe_strategy(dm_table_entry_t *table_en, struct buf *bp)
{
	dm_target_stripe_config_t *tsc;
	struct bio *bio = &bp->b_bio1;
	struct buf *nestbuf;
	uint64_t blkno, blkoff;
	uint64_t stripe, blknr;
	uint32_t stripe_off, stripe_rest, num_blks, issue_blks;
	int devnr;
	tsc = table_en->target_config;
	if (tsc == NULL)
		return 0;
	KKASSERT(bp->b_resid % DEV_BSIZE == 0);
	switch(bp->b_cmd) {
	case BUF_CMD_READ:
	case BUF_CMD_WRITE:
	case BUF_CMD_FREEBLKS:
		blkno = bp->b_bio1.bio_offset / DEV_BSIZE;
		blkoff = 0;
		num_blks = bp->b_resid / DEV_BSIZE;
		nestiobuf_init(bio);
		while (num_blks > 0) {
			stripe = blkno / tsc->stripe_chunksize;
			stripe_off = blkno % tsc->stripe_chunksize;
			devnr = stripe % tsc->stripe_num;
			blknr = stripe / tsc->stripe_num;
			stripe_rest = tsc->stripe_chunksize - stripe_off;
			issue_blks = MIN(stripe_rest, num_blks);
			nestbuf = getpbuf(NULL);
			nestbuf->b_flags |= bio->bio_buf->b_flags & B_HASBOGUS;
			nestiobuf_add(bio, nestbuf, blkoff,
					issue_blks * DEV_BSIZE, NULL);
			nestbuf->b_bio1.bio_offset =
				blknr * tsc->stripe_chunksize + stripe_off;
			nestbuf->b_bio1.bio_offset +=
				tsc->stripe_devs[devnr].offset;
			nestbuf->b_bio1.bio_offset *= DEV_BSIZE;
			vn_strategy(tsc->stripe_devs[devnr].pdev->pdev_vnode,
				    &nestbuf->b_bio1);
			blkno += issue_blks;
			blkoff += issue_blks * DEV_BSIZE;
			num_blks -= issue_blks;
		}
		nestiobuf_start(bio);
		break;
	case BUF_CMD_FLUSH:
		nestiobuf_init(bio);
		for (devnr = 0; devnr < tsc->stripe_num; ++devnr) {
			nestbuf = getpbuf(NULL);
			nestbuf->b_flags |= bio->bio_buf->b_flags & B_HASBOGUS;
			nestiobuf_add(bio, nestbuf, 0, 0, NULL);
			nestbuf->b_bio1.bio_offset = 0;
			vn_strategy(tsc->stripe_devs[devnr].pdev->pdev_vnode,
				    &nestbuf->b_bio1);
		}
		nestiobuf_start(bio);
		break;
	default:
		bp->b_flags |= B_ERROR;
		bp->b_error = EIO;
		biodone(bio);
		break;
	}
	return 0;
}
static int dm_target_stripe_strategy ( dm_table_entry_t * table_en , struct buf * bp ) { dm_target_stripe_config_t * tsc ; struct bio * bio = & bp -> b_bio1 ; struct buf * nestbuf ; uint64_t blkno , blkoff ; uint64_t stripe , blknr ; uint32_t stripe_off , stripe_rest , num_blks , issue_blks ; int devnr ; tsc = table_en -> target_config ; if ( tsc == NULL ) return 0 ; KKASSERT ( bp -> b_resid % DEV_BSIZE == 0 ) ; switch ( bp -> b_cmd ) { case BUF_CMD_READ : case BUF_CMD_WRITE : case BUF_CMD_FREEBLKS : blkno = bp -> b_bio1 . bio_offset / DEV_BSIZE ; blkoff = 0 ; num_blks = bp -> b_resid / DEV_BSIZE ; nestiobuf_init ( bio ) ; while ( num_blks > 0 ) { stripe = blkno / tsc -> stripe_chunksize ; stripe_off = blkno % tsc -> stripe_chunksize ; devnr = stripe % tsc -> stripe_num ; blknr = stripe / tsc -> stripe_num ; stripe_rest = tsc -> stripe_chunksize - stripe_off ; issue_blks = MIN ( stripe_rest , num_blks ) ; nestbuf = getpbuf ( NULL ) ; nestbuf -> b_flags |= bio -> bio_buf -> b_flags & B_HASBOGUS ; nestiobuf_add ( bio , nestbuf , blkoff , issue_blks * DEV_BSIZE , NULL ) ; nestbuf -> b_bio1 . bio_offset = blknr * tsc -> stripe_chunksize + stripe_off ; nestbuf -> b_bio1 . bio_offset += tsc -> stripe_devs [ devnr ] . offset ; nestbuf -> b_bio1 . bio_offset *= DEV_BSIZE ; vn_strategy ( tsc -> stripe_devs [ devnr ] . pdev -> pdev_vnode , & nestbuf -> b_bio1 ) ; blkno += issue_blks ; blkoff += issue_blks * DEV_BSIZE ; num_blks -= issue_blks ; } nestiobuf_start ( bio ) ; break ; case BUF_CMD_FLUSH : nestiobuf_init ( bio ) ; for ( devnr = 0 ; devnr < tsc -> stripe_num ; ++ devnr ) { nestbuf = getpbuf ( NULL ) ; nestbuf -> b_flags |= bio -> bio_buf -> b_flags & B_HASBOGUS ; nestiobuf_add ( bio , nestbuf , 0 , 0 , NULL ) ; nestbuf -> b_bio1 . bio_offset = 0 ; vn_strategy ( tsc -> stripe_devs [ devnr ] . pdev -> pdev_vnode , & nestbuf -> b_bio1 ) ; } nestiobuf_start ( bio ) ; break ; default : bp -> b_flags |= B_ERROR ; bp -> b_error = EIO ; biodone ( bio ) ; break ; } return 0 ; }
Strategy routine called from dm_strategy.
Strategy routine called from dm_strategy .
/* calculate extent of request */ /*
		 * Loop through to individual operations
		 */ /* blockno to strip piece nr */ /* where we are inside the strip */ /* how much is left before we hit a boundary */ /* issue this piece on stripe `stripe' */ /* I need number of bytes. */