diff options
Diffstat (limited to 'zfs/lib/libzpool/vdev_file.c')
-rw-r--r-- | zfs/lib/libzpool/vdev_file.c | 164 |
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, |