* Virtual device vector for disks.
*/
typedef struct dio_request {
- struct completion dr_comp; /* Completion for sync IO */
zio_t *dr_zio; /* Parent ZIO */
atomic_t dr_ref; /* References */
- int dr_wait; /* Wait for IO */
int dr_error; /* Bio error */
int dr_bio_count; /* Count of bio's */
struct bio *dr_bio[0]; /* Attached bio's */
dr = kmem_zalloc(sizeof (dio_request_t) +
sizeof (struct bio *) * bio_count, KM_SLEEP);
if (dr) {
- init_completion(&dr->dr_comp);
atomic_set(&dr->dr_ref, 0);
dr->dr_bio_count = bio_count;
dr->dr_error = 0;
{
dio_request_t *dr = bio->bi_private;
int rc;
- int wait;
if (dr->dr_error == 0) {
#ifdef HAVE_1ARG_BIO_END_IO_T
#endif
}
- wait = dr->dr_wait;
/* Drop reference aquired by __vdev_disk_physio */
rc = vdev_disk_dio_put(dr);
-
- /* Wake up synchronous waiter this is the last outstanding bio */
- if (wait && rc == 1)
- complete(&dr->dr_comp);
}
static inline unsigned long
static int
__vdev_disk_physio(struct block_device *bdev, zio_t *zio, caddr_t kbuf_ptr,
- size_t kbuf_size, uint64_t kbuf_offset, int flags, int wait)
+ size_t kbuf_size, uint64_t kbuf_offset, int flags)
{
dio_request_t *dr;
caddr_t bio_ptr;
rw = flags;
dr->dr_zio = zio;
- dr->dr_wait = wait;
/*
* When the IO size exceeds the maximum bio size for the request
if (dr->dr_bio[i])
vdev_submit_bio(rw, dr->dr_bio[i]);
- /*
- * On synchronous blocking requests we wait for all bio the completion
- * callbacks to run. We will be woken when the last callback runs
- * for this dio. We are responsible for putting the last dio_request
- * reference will in turn put back the last bio references. The
- * only synchronous consumer is vdev_disk_read_rootlabel() all other
- * IO originating from vdev_disk_io_start() is asynchronous.
- */
- if (wait) {
- wait_for_completion(&dr->dr_comp);
- error = dr->dr_error;
- ASSERT3S(atomic_read(&dr->dr_ref), ==, 1);
- }
-
(void) vdev_disk_dio_put(dr);
return (error);
}
+#ifndef __linux__
int
vdev_disk_physio(struct block_device *bdev, caddr_t kbuf,
size_t size, uint64_t offset, int flags)
{
bio_set_flags_failfast(bdev, &flags);
- return (__vdev_disk_physio(bdev, NULL, kbuf, size, offset, flags, 1));
+ return (__vdev_disk_physio(bdev, NULL, kbuf, size, offset, flags));
}
+#endif
BIO_END_IO_PROTO(vdev_disk_io_flush_completion, bio, rc)
{
{
vdev_t *v = zio->io_vd;
vdev_disk_t *vd = v->vdev_tsd;
- zio_priority_t pri = zio->io_priority;
int flags, error;
switch (zio->io_type) {
zio_execute(zio);
return;
case ZIO_TYPE_WRITE:
- if ((pri == ZIO_PRIORITY_SYNC_WRITE) && (v->vdev_nonrot))
- flags = WRITE_SYNC;
- else
- flags = WRITE;
+#if defined(HAVE_BLK_QUEUE_HAVE_BIO_RW_UNPLUG)
+ flags = WRITE | (1 << BIO_RW_UNPLUG);
+#elif defined(REQ_UNPLUG)
+ flags = WRITE | REQ_UNPLUG;
+#else
+ flags = WRITE;
+#endif
break;
case ZIO_TYPE_READ:
- if ((pri == ZIO_PRIORITY_SYNC_READ) && (v->vdev_nonrot))
- flags = READ_SYNC;
- else
- flags = READ;
+#if defined(HAVE_BLK_QUEUE_HAVE_BIO_RW_UNPLUG)
+ flags = READ | (1 << BIO_RW_UNPLUG);
+#elif defined(REQ_UNPLUG)
+ flags = READ | REQ_UNPLUG;
+#else
+ flags = READ;
+#endif
break;
default:
zio->io_target_timestamp = zio_handle_io_delay(zio);
error = __vdev_disk_physio(vd->vd_bdev, zio, zio->io_data,
- zio->io_size, zio->io_offset, flags, 0);
+ zio->io_size, zio->io_offset, flags);
if (error) {
zio->io_error = error;
zio_interrupt(zio);
B_TRUE /* leaf vdev */
};
+#ifndef __linux__
/*
* Given the root disk device devid or pathname, read the label from
* the device, and construct a configuration nvlist.
return (0);
}
+#endif /* __linux__ */
module_param(zfs_vdev_scheduler, charp, 0644);
MODULE_PARM_DESC(zfs_vdev_scheduler, "I/O scheduler");