summaryrefslogtreecommitdiffstats
path: root/zfs/lib/libzpool/vdev_file.c
diff options
context:
space:
mode:
Diffstat (limited to 'zfs/lib/libzpool/vdev_file.c')
-rw-r--r--zfs/lib/libzpool/vdev_file.c164
1 files changed, 6 insertions, 158 deletions
diff --git a/zfs/lib/libzpool/vdev_file.c b/zfs/lib/libzpool/vdev_file.c
index 974c4cdab..dc0e920bf 100644
--- a/zfs/lib/libzpool/vdev_file.c
+++ b/zfs/lib/libzpool/vdev_file.c
@@ -19,28 +19,28 @@
* CDDL HEADER END
*/
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "@(#)vdev_file.c 1.7 07/11/27 SMI"
-
#include <sys/zfs_context.h>
#include <sys/spa.h>
#include <sys/vdev_file.h>
#include <sys/vdev_impl.h>
#include <sys/zio.h>
#include <sys/fs/zfs.h>
+#include <sys/fm/fs/zfs.h>
/*
* Virtual device vector for files.
*/
static int
-vdev_file_open_common(vdev_t *vd)
+vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift)
{
vdev_file_t *vf;
vnode_t *vp;
+ vattr_t vattr;
int error;
/*
@@ -79,22 +79,6 @@ vdev_file_open_common(vdev_t *vd)
return (ENODEV);
}
#endif
-
- return (0);
-}
-
-static int
-vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift)
-{
- vdev_file_t *vf;
- vattr_t vattr;
- int error;
-
- if ((error = vdev_file_open_common(vd)) != 0)
- return (error);
-
- vf = vd->vdev_tsd;
-
/*
* Determine the physical size of the file.
*/
@@ -130,102 +114,13 @@ vdev_file_close(vdev_t *vd)
}
static int
-vdev_file_probe_io(vdev_t *vd, caddr_t data, size_t size, uint64_t offset,
- enum uio_rw rw)
-{
- vdev_file_t *vf = vd->vdev_tsd;
- ssize_t resid;
- int error = 0;
-
- if (vd == NULL || vf == NULL || vf->vf_vnode == NULL)
- return (EINVAL);
-
- ASSERT(rw == UIO_READ || rw == UIO_WRITE);
-
- error = vn_rdwr(rw, vf->vf_vnode, data, size, offset, UIO_SYSSPACE,
- 0, RLIM64_INFINITY, kcred, &resid);
- if (error || resid != 0)
- return (EIO);
- return (0);
-}
-
-/*
- * Determine if the underlying device is accessible by reading and writing
- * to a known location. We must be able to do this during syncing context
- * and thus we cannot set the vdev state directly.
- */
-static int
-vdev_file_probe(vdev_t *vd)
-{
- vdev_t *nvd;
- char *vl_boot;
- uint64_t offset;
- int l, error = 0, retries = 0;
-
- if (vd == NULL)
- return (EINVAL);
-
- /* Hijack the current vdev */
- nvd = vd;
-
- /*
- * Pick a random label to rewrite.
- */
- l = spa_get_random(VDEV_LABELS);
- ASSERT(l < VDEV_LABELS);
-
- offset = vdev_label_offset(vd->vdev_psize, l,
- offsetof(vdev_label_t, vl_boot_header));
-
- vl_boot = kmem_alloc(VDEV_BOOT_HEADER_SIZE, KM_SLEEP);
-
- while ((error = vdev_file_probe_io(nvd, vl_boot, VDEV_BOOT_HEADER_SIZE,
- offset, UIO_READ)) != 0 && retries == 0) {
-
- /*
- * If we failed with the vdev that was passed in then
- * try allocating a new one and try again.
- */
- nvd = kmem_zalloc(sizeof (vdev_t), KM_SLEEP);
- if (vd->vdev_path)
- nvd->vdev_path = spa_strdup(vd->vdev_path);
- retries++;
-
- error = vdev_file_open_common(nvd);
- if (error)
- break;
- }
-
- if ((spa_mode & FWRITE) && !error) {
- error = vdev_file_probe_io(nvd, vl_boot, VDEV_BOOT_HEADER_SIZE,
- offset, UIO_WRITE);
- }
-
- if (retries) {
- vdev_file_close(nvd);
- if (nvd->vdev_path)
- spa_strfree(nvd->vdev_path);
- kmem_free(nvd, sizeof (vdev_t));
- }
- kmem_free(vl_boot, VDEV_BOOT_HEADER_SIZE);
-
- if (!error)
- vd->vdev_is_failing = B_FALSE;
-
- return (error);
-}
-
-static int
vdev_file_io_start(zio_t *zio)
{
vdev_t *vd = zio->io_vd;
vdev_file_t *vf = vd->vdev_tsd;
ssize_t resid;
- int error;
if (zio->io_type == ZIO_TYPE_IOCTL) {
- zio_vdev_io_bypass(zio);
-
/* XXPOLICY */
if (!vdev_readable(vd)) {
zio->io_error = ENXIO;
@@ -236,8 +131,6 @@ vdev_file_io_start(zio_t *zio)
case DKIOCFLUSHWRITECACHE:
zio->io_error = VOP_FSYNC(vf->vf_vnode, FSYNC | FDSYNC,
kcred, NULL);
- dprintf("fsync(%s) = %d\n", vdev_description(vd),
- zio->io_error);
break;
default:
zio->io_error = ENOTSUP;
@@ -246,30 +139,6 @@ vdev_file_io_start(zio_t *zio)
return (ZIO_PIPELINE_CONTINUE);
}
- /*
- * In the kernel, don't bother double-caching, but in userland,
- * we want to test the vdev_cache code.
- */
-#ifndef _KERNEL
- if (zio->io_type == ZIO_TYPE_READ && vdev_cache_read(zio) == 0)
- return (ZIO_PIPELINE_STOP);
-#endif
-
- if ((zio = vdev_queue_io(zio)) == NULL)
- return (ZIO_PIPELINE_STOP);
-
- /* XXPOLICY */
- if (zio->io_type == ZIO_TYPE_WRITE)
- error = vdev_writeable(vd) ? vdev_error_inject(vd, zio) : ENXIO;
- else
- error = vdev_readable(vd) ? vdev_error_inject(vd, zio) : ENXIO;
- error = (vd->vdev_remove_wanted || vd->vdev_is_failing) ? ENXIO : error;
- if (error) {
- zio->io_error = error;
- zio_interrupt(zio);
- return (ZIO_PIPELINE_STOP);
- }
-
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,
@@ -283,35 +152,15 @@ vdev_file_io_start(zio_t *zio)
return (ZIO_PIPELINE_STOP);
}
-static int
+/* ARGSUSED */
+static void
vdev_file_io_done(zio_t *zio)
{
- vdev_t *vd = zio->io_vd;
-
- if (zio_injection_enabled && zio->io_error == 0)
- zio->io_error = zio_handle_device_injection(vd, EIO);
-
- /*
- * If an error has been encountered then attempt to probe the device
- * to determine if it's still accessible.
- */
- if (zio->io_error == EIO && vdev_probe(vd) != 0)
- vd->vdev_is_failing = B_TRUE;
-
- vdev_queue_io_done(zio);
-
-#ifndef _KERNEL
- if (zio->io_type == ZIO_TYPE_WRITE)
- vdev_cache_write(zio);
-#endif
-
- return (ZIO_PIPELINE_CONTINUE);
}
vdev_ops_t vdev_file_ops = {
vdev_file_open,
vdev_file_close,
- vdev_file_probe,
vdev_default_asize,
vdev_file_io_start,
vdev_file_io_done,
@@ -328,7 +177,6 @@ vdev_ops_t vdev_file_ops = {
vdev_ops_t vdev_disk_ops = {
vdev_file_open,
vdev_file_close,
- vdev_file_probe,
vdev_default_asize,
vdev_file_io_start,
vdev_file_io_done,