diff options
author | George Wilson <[email protected]> | 2013-05-02 16:36:32 -0700 |
---|---|---|
committer | Brian Behlendorf <[email protected]> | 2013-05-03 16:53:52 -0700 |
commit | 5853fe790d1df58c5dd85ea52c5e165b6d43013c (patch) | |
tree | a17c4c13e3dba02ef842b408b9b2dfc76387422c /module/zfs/vdev_file.c | |
parent | 5165473737e488447edfe25209c68704e08b3a2d (diff) |
Illumos #3306, #3321
3306 zdb should be able to issue reads in parallel
3321 'zpool reopen' command should be documented in the man
page and help
Reviewed by: Adam Leventhal <[email protected]>
Reviewed by: Matt Ahrens <[email protected]>
Reviewed by: Christopher Siden <[email protected]>
Approved by: Garrett D'Amore <[email protected]>
References:
illumos/illumos-gate@31d7e8fa33fae995f558673adb22641b5aa8b6e1
https://www.illumos.org/issues/3306
https://www.illumos.org/issues/3321
The vdev_file.c implementation in this patch diverges significantly
from the upstream version. For consistenty with the vdev_disk.c
code the upstream version leverages the Illumos bio interfaces.
This makes sense for Illumos but not for ZoL for two reasons.
1) The vdev_disk.c code in ZoL has been rewritten to use the
Linux block device interfaces which differ significantly
from those in Illumos. Therefore, updating the vdev_file.c
to use the Illumos interfaces doesn't get you consistency
with vdev_disk.c.
2) Using the upstream patch as is would requiring implementing
compatibility code for those Solaris block device interfaces
in user and kernel space. That additional complexity could
lead to confusion and doesn't buy us anything.
For these reasons I've opted to simply move the existing vn_rdwr()
as is in to the taskq function. This has the advantage of being
low risk and easy to understand. Moving the vn_rdwr() function
in to its own taskq thread also neatly avoids the possibility of
a stack overflow.
Finally, because of the additional work which is being handled by
the free taskq the number of threads has been increased. The
thread count under Illumos defaults to 100 but was decreased to 2
in commit 08d08e due to contention. We increase it to 8 until
the contention can be address by porting Illumos #3581.
Ported-by: Brian Behlendorf <[email protected]>
Closes #1354
Diffstat (limited to 'module/zfs/vdev_file.c')
-rw-r--r-- | module/zfs/vdev_file.c | 48 |
1 files changed, 30 insertions, 18 deletions
diff --git a/module/zfs/vdev_file.c b/module/zfs/vdev_file.c index 3c0ce53cd..45c917b09 100644 --- a/module/zfs/vdev_file.c +++ b/module/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> @@ -139,21 +140,39 @@ vdev_file_close(vdev_t *vd) vd->vdev_tsd = NULL; } -static int -vdev_file_io_start(zio_t *zio) +static void +vdev_file_io_strategy(void *arg) { + zio_t *zio = (zio_t *)arg; vdev_t *vd = zio->io_vd; - vdev_file_t *vf; - ssize_t resid = 0; + vdev_file_t *vf = vd->vdev_tsd; + ssize_t resid; - if (!vdev_readable(vd)) { - zio->io_error = ENXIO; - 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); + + if (resid != 0 && zio->io_error == 0) + zio->io_error = ENOSPC; - vf = vd->vdev_tsd; + zio_interrupt(zio); +} + +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; if (zio->io_type == ZIO_TYPE_IOCTL) { + /* XXPOLICY */ + if (!vdev_readable(vd)) { + zio->io_error = ENXIO; + return (ZIO_PIPELINE_CONTINUE); + } + switch (zio->io_cmd) { case DKIOCFLUSHWRITECACHE: zio->io_error = VOP_FSYNC(vf->vf_vnode, FSYNC | FDSYNC, @@ -166,15 +185,8 @@ 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); - - if (resid != 0 && zio->io_error == 0) - zio->io_error = ENOSPC; - - zio_interrupt(zio); + taskq_dispatch_ent(spa->spa_zio_taskq[ZIO_TYPE_FREE][ZIO_TASKQ_ISSUE], + vdev_file_io_strategy, zio, 0, &zio->io_tqent); return (ZIO_PIPELINE_STOP); } |