return get_capacity(bdev->bd_disk);
}
+static void
+vdev_disk_error(zio_t *zio)
+{
+#ifdef ZFS_DEBUG
+ printk("ZFS: zio error=%d type=%d offset=%llu size=%llu "
+ "flags=%x delay=%llu\n", zio->io_error, zio->io_type,
+ (u_longlong_t)zio->io_offset, (u_longlong_t)zio->io_size,
+ zio->io_flags, (u_longlong_t)zio->io_delay);
+#endif
+}
+
static int
vdev_disk_open(vdev_t *v, uint64_t *psize, uint64_t *ashift)
{
vdev_disk_dio_free(dr);
if (zio) {
+ zio->io_delay = jiffies_to_msecs(
+ jiffies_64 - zio->io_delay);
zio->io_error = error;
+ ASSERT3S(zio->io_error, >=, 0);
+ if (zio->io_error)
+ vdev_disk_error(zio);
zio_interrupt(zio);
}
}
#endif /* HAVE_2ARGS_BIO_END_IO_T */
if (error == 0 && !test_bit(BIO_UPTODATE, &bio->bi_flags))
- error = EIO;
+ error = -EIO;
if (dr->dr_error == 0)
- dr->dr_error = error;
+ dr->dr_error = -error;
/* Drop reference aquired by __vdev_disk_physio */
rc = vdev_disk_dio_put(dr);
if (dr == NULL)
return ENOMEM;
+ if (zio && !(zio->io_flags & (ZIO_FLAG_IO_RETRY | ZIO_FLAG_TRYHARD)))
+ bio_set_flags_failfast(bdev, &flags);
+
dr->dr_zio = zio;
dr->dr_rw = flags;
block_size = vdev_bdev_block_size(bdev);
-#ifdef BIO_RW_FAILFAST
- if (flags & (1 << BIO_RW_FAILFAST))
- dr->dr_rw |= 1 << BIO_RW_FAILFAST;
-#endif /* BIO_RW_FAILFAST */
-
/*
* When the IO size exceeds the maximum bio size for the request
* queue we are forced to break the IO in multiple bio's and wait
/* Extra reference to protect dio_request during submit_bio */
vdev_disk_dio_get(dr);
+ if (zio)
+ zio->io_delay = jiffies_64;
/* Submit all bio's associated with this dio */
for (i = 0; i < dr->dr_bio_count; i++)
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);
}
{
zio_t *zio = bio->bi_private;
+ zio->io_delay = jiffies_to_msecs(jiffies_64 - zio->io_delay);
zio->io_error = -rc;
if (rc && (rc == -EOPNOTSUPP))
zio->io_vd->vdev_nowritecache = B_TRUE;
bio_put(bio);
+ ASSERT3S(zio->io_error, >=, 0);
+ if (zio->io_error)
+ vdev_disk_error(zio);
zio_interrupt(zio);
BIO_END_IO_RETURN(0);
bio->bi_end_io = vdev_disk_io_flush_completion;
bio->bi_private = zio;
bio->bi_bdev = bdev;
+ zio->io_delay = jiffies_64;
submit_bio(WRITE_BARRIER, bio);
return 0;
return ZIO_PIPELINE_CONTINUE;
}
-#ifdef BIO_RW_FAILFAST
- if (zio->io_flags & (ZIO_FLAG_IO_RETRY | ZIO_FLAG_TRYHARD))
- flags |= (1 << BIO_RW_FAILFAST);
-#endif /* BIO_RW_FAILFAST */
-
error = __vdev_disk_physio(vd->vd_bdev, zio, zio->io_data,
zio->io_size, zio->io_offset, flags);
if (error) {