summaryrefslogtreecommitdiff
path: root/usr/src/uts/common/fs/zfs/vdev_file.c
diff options
context:
space:
mode:
authorGeorge Wilson <george.wilson@delphix.com>2012-09-07 17:29:12 -0700
committerChristopher Siden <chris.siden@delphix.com>2012-11-02 13:57:48 -0700
commit31d7e8fa33fae995f558673adb22641b5aa8b6e1 (patch)
treed9c24f7c89681abcaca5171f8352393da290144f /usr/src/uts/common/fs/zfs/vdev_file.c
parent5c68564d80b7e4acff16ce069e5e3d412d73ce69 (diff)
downloadillumos-gate-31d7e8fa33fae995f558673adb22641b5aa8b6e1.tar.gz
3306 zdb should be able to issue reads in parallel
3321 'zpool reopen' command should be documented in the man page and help message Reviewed by: Adam Leventhal <ahl@delphix.com> Reviewed by: Matt Ahrens <matthew.ahrens@delphix.com> Reviewed by: Christopher Siden <chris.siden@delphix.com> Approved by: Garrett D'Amore <garrett@damore.org>
Diffstat (limited to 'usr/src/uts/common/fs/zfs/vdev_file.c')
-rw-r--r--usr/src/uts/common/fs/zfs/vdev_file.c67
1 files changed, 59 insertions, 8 deletions
diff --git a/usr/src/uts/common/fs/zfs/vdev_file.c b/usr/src/uts/common/fs/zfs/vdev_file.c
index 043fa51294..1fbce5e542 100644
--- a/usr/src/uts/common/fs/zfs/vdev_file.c
+++ b/usr/src/uts/common/fs/zfs/vdev_file.c
@@ -25,6 +25,7 @@
#include <sys/zfs_context.h>
#include <sys/spa.h>
+#include <sys/spa_impl.h>
#include <sys/vdev_file.h>
#include <sys/vdev_impl.h>
#include <sys/zio.h>
@@ -140,12 +141,55 @@ vdev_file_close(vdev_t *vd)
vd->vdev_tsd = NULL;
}
+/*
+ * Implements the interrupt side for file vdev types. This routine will be
+ * called when the I/O completes allowing us to transfer the I/O to the
+ * interrupt taskqs. For consistency, the code structure mimics disk vdev
+ * types.
+ */
+static void
+vdev_file_io_intr(buf_t *bp)
+{
+ vdev_buf_t *vb = (vdev_buf_t *)bp;
+ zio_t *zio = vb->vb_io;
+
+ zio->io_error = (geterror(bp) != 0 ? EIO : 0);
+ if (zio->io_error == 0 && bp->b_resid != 0)
+ zio->io_error = ENOSPC;
+
+ kmem_free(vb, sizeof (vdev_buf_t));
+ zio_interrupt(zio);
+}
+
+static void
+vdev_file_io_strategy(void *arg)
+{
+ buf_t *bp = arg;
+ vnode_t *vp = bp->b_private;
+ ssize_t resid;
+ int error;
+
+ error = vn_rdwr((bp->b_flags & B_READ) ? UIO_READ : UIO_WRITE,
+ vp, bp->b_un.b_addr, bp->b_bcount, ldbtob(bp->b_lblkno),
+ UIO_SYSSPACE, 0, RLIM64_INFINITY, kcred, &resid);
+
+ if (error == 0) {
+ bp->b_resid = resid;
+ biodone(bp);
+ } else {
+ bioerror(bp, error);
+ biodone(bp);
+ }
+}
+
static int
vdev_file_io_start(zio_t *zio)
{
+ spa_t *spa = zio->io_spa;
vdev_t *vd = zio->io_vd;
vdev_file_t *vf = vd->vdev_tsd;
- ssize_t resid;
+ vdev_buf_t *vb;
+ buf_t *bp;
if (zio->io_type == ZIO_TYPE_IOCTL) {
/* XXPOLICY */
@@ -166,15 +210,22 @@ vdev_file_io_start(zio_t *zio)
return (ZIO_PIPELINE_CONTINUE);
}
- zio->io_error = vn_rdwr(zio->io_type == ZIO_TYPE_READ ?
- UIO_READ : UIO_WRITE, vf->vf_vnode, zio->io_data,
- zio->io_size, zio->io_offset, UIO_SYSSPACE,
- 0, RLIM64_INFINITY, kcred, &resid);
+ vb = kmem_alloc(sizeof (vdev_buf_t), KM_SLEEP);
- if (resid != 0 && zio->io_error == 0)
- zio->io_error = ENOSPC;
+ vb->vb_io = zio;
+ bp = &vb->vb_buf;
- zio_interrupt(zio);
+ bioinit(bp);
+ bp->b_flags = (zio->io_type == ZIO_TYPE_READ ? B_READ : B_WRITE);
+ bp->b_bcount = zio->io_size;
+ bp->b_un.b_addr = zio->io_data;
+ bp->b_lblkno = lbtodb(zio->io_offset);
+ bp->b_bufsize = zio->io_size;
+ bp->b_private = vf->vf_vnode;
+ bp->b_iodone = (int (*)())vdev_file_io_intr;
+
+ taskq_dispatch_ent(spa->spa_zio_taskq[ZIO_TYPE_FREE][ZIO_TASKQ_ISSUE],
+ vdev_file_io_strategy, bp, 0, &zio->io_tqent);
return (ZIO_PIPELINE_STOP);
}