Illumos #3581 spa_zio_taskq[ZIO_TYPE_FREE][ZIO_TASKQ_ISSUE]->tq_lock contention
[zfs.git] / module / zfs / vdev_file.c
index f31389a..06999a8 100644 (file)
  */
 /*
  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012 by Delphix. All rights reserved.
  */
 
 #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>
@@ -47,7 +49,8 @@ vdev_file_rele(vdev_t *vd)
 }
 
 static int
-vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift)
+vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *max_psize,
+    uint64_t *ashift)
 {
        vdev_file_t *vf;
        vnode_t *vp;
@@ -72,7 +75,7 @@ vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift)
                goto skip_open;
        }
 
-       vf = vd->vdev_tsd = kmem_zalloc(sizeof (vdev_file_t), KM_SLEEP);
+       vf = vd->vdev_tsd = kmem_zalloc(sizeof (vdev_file_t), KM_PUSHPAGE);
 
        /*
         * We always open the files from the root of the global zone, even if
@@ -112,7 +115,7 @@ skip_open:
                return (error);
        }
 
-       *psize = vattr.va_size;
+       *max_psize = *psize = vattr.va_size;
        *ashift = SPA_MINBLOCKSHIFT;
 
        return (0);
@@ -130,7 +133,6 @@ vdev_file_close(vdev_t *vd)
                (void) VOP_PUTPAGE(vf->vf_vnode, 0, 0, B_INVAL, kcred, NULL);
                (void) VOP_CLOSE(vf->vf_vnode, spa_mode(vd->vdev_spa), 1, 0,
                    kcred, NULL);
-               VN_RELE(vf->vf_vnode);
        }
 
        vd->vdev_delayed_close = B_FALSE;
@@ -138,12 +140,31 @@ vdev_file_close(vdev_t *vd)
        vd->vdev_tsd = NULL;
 }
 
+static void
+vdev_file_io_strategy(void *arg)
+{
+       zio_t *zio = (zio_t *)arg;
+       vdev_t *vd = zio->io_vd;
+       vdev_file_t *vf = vd->vdev_tsd;
+       ssize_t resid;
+
+       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);
+}
+
 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 = 0;
 
        if (zio->io_type == ZIO_TYPE_IOCTL) {
                /* XXPOLICY */
@@ -164,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);
+       spa_taskq_dispatch_ent(spa, ZIO_TYPE_FREE, ZIO_TASKQ_ISSUE,
+           vdev_file_io_strategy, zio, 0, &zio->io_tqent);
 
        return (ZIO_PIPELINE_STOP);
 }