Ejemplo n.º 1
0
static int
vdev_disk_physio(struct device *dev, caddr_t data, size_t size,
    uint64_t offset, int write)
{
	struct bio *bio;
	int ret;

	bio = alloc_bio();
	if (write)
		bio->bio_cmd = BIO_WRITE;
	else
		bio->bio_cmd = BIO_READ;

	bio->bio_dev = dev;
	bio->bio_data = data;
	bio->bio_offset = offset;
	bio->bio_bcount = size;

	bio->bio_dev->driver->devops->strategy(bio);

	ret = bio_wait(bio);
	destroy_bio(bio);

	return ret;
}
Ejemplo n.º 2
0
static int
vdev_disk_start_flush(zio_t *zio)
{
	vdev_t *vd = zio->io_vd;
	struct vdev_disk *dvd = vd->vdev_tsd;
	struct bio *bio;

	bio = alloc_bio();
	bio->bio_cmd = BIO_FLUSH;
	bio->bio_dev = dvd->device;

	bio->bio_caller1 = zio;
	bio->bio_done = vdev_disk_bio_done;

	bio->bio_dev->driver->devops->strategy(bio);
	return ZIO_PIPELINE_STOP;
}
Ejemplo n.º 3
0
void multiplex_strategy(struct bio *bio)
{
	struct device *dev = bio->bio_dev;
	devop_strategy_t strategy = *((devop_strategy_t *)dev->private_data);

	uint64_t len = bio->bio_bcount;

	bio->bio_offset += bio->bio_dev->offset;
	uint64_t offset = bio->bio_offset;
	void *buf = bio->bio_data;

	assert(strategy != NULL);

	if (len <= dev->max_io_size) {
		strategy(bio);
		return;
	}

	// It is better to initialize the refcounter beforehand, specially because we can
	// trivially determine what is the number going to be. Otherwise, we can have a
	// situation in which we bump the refcount to 1, get scheduled out, the bio is
	// finished, and when it drops its refcount to 0, we consider the main bio finished.
	refcount_init(&bio->bio_refcnt, (len / dev->max_io_size) + !!(len % dev->max_io_size));

	while (len > 0) {
		uint64_t req_size = MIN(len, dev->max_io_size);
		struct bio *b = alloc_bio();

		b->bio_bcount = req_size;
		b->bio_data = buf;
		b->bio_offset = offset;

		b->bio_cmd = bio->bio_cmd;
		b->bio_dev = bio->bio_dev;
		b->bio_caller1 = bio;
		b->bio_done = multiplex_bio_done;

		strategy(b);
		buf += req_size;
		offset += req_size;
		len -= req_size;
	}
}
Ejemplo n.º 4
0
static int
vdev_disk_start_bio(zio_t *zio)
{
	vdev_t *vd = zio->io_vd;
	struct vdev_disk *dvd = vd->vdev_tsd;
	struct bio *bio;

	bio = alloc_bio();
	if (zio->io_type == ZIO_TYPE_READ)
		bio->bio_cmd = BIO_READ;
	else
		bio->bio_cmd = BIO_WRITE;

	bio->bio_dev = dvd->device;
	bio->bio_data = zio->io_data;
	bio->bio_offset = zio->io_offset;
	bio->bio_bcount = zio->io_size;

	bio->bio_caller1 = zio;
	bio->bio_done = vdev_disk_bio_done;

	bio->bio_dev->driver->devops->strategy(bio);
	return ZIO_PIPELINE_STOP;
}