X-Git-Url: https://git.camperquake.de/gitweb.cgi?a=blobdiff_plain;f=module%2Fzfs%2Fvdev_file.c;h=3c0ce53cdf80b1c344bca9d309159aba3422b6c3;hb=1c24b699b0c7590e135f4701b50a4c933ebe0499;hp=dc0e920bfc5218455f8e8189db0bc9b84bb7ef78;hpb=172bb4bd5e4afef721dd4d2972d8680d983f144b;p=zfs.git diff --git a/module/zfs/vdev_file.c b/module/zfs/vdev_file.c index dc0e920..3c0ce53 100644 --- a/module/zfs/vdev_file.c +++ b/module/zfs/vdev_file.c @@ -19,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright 2008 Sun Microsystems, Inc. All rights reserved. - * Use is subject to license terms. + * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012 by Delphix. All rights reserved. */ #include @@ -35,8 +35,21 @@ * Virtual device vector for files. */ +static void +vdev_file_hold(vdev_t *vd) +{ + ASSERT(vd->vdev_path != NULL); +} + +static void +vdev_file_rele(vdev_t *vd) +{ + ASSERT(vd->vdev_path != NULL); +} + 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; @@ -51,7 +64,17 @@ vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift) return (EINVAL); } - vf = vd->vdev_tsd = kmem_zalloc(sizeof (vdev_file_t), KM_SLEEP); + /* + * Reopen the device if it's not currently open. Otherwise, + * just update the physical size of the device. + */ + if (vd->vdev_tsd != NULL) { + ASSERT(vd->vdev_reopening); + vf = vd->vdev_tsd; + goto skip_open; + } + + 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 @@ -61,7 +84,7 @@ vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift) */ ASSERT(vd->vdev_path != NULL && vd->vdev_path[0] == '/'); error = vn_openat(vd->vdev_path + 1, UIO_SYSSPACE, - spa_mode | FOFFMAX, 0, &vp, 0, 0, rootdir, -1); + spa_mode(vd->vdev_spa) | FOFFMAX, 0, &vp, 0, 0, rootdir, -1); if (error) { vd->vdev_stat.vs_aux = VDEV_AUX_OPEN_FAILED; @@ -79,6 +102,8 @@ vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift) return (ENODEV); } #endif + +skip_open: /* * Determine the physical size of the file. */ @@ -89,7 +114,7 @@ vdev_file_open(vdev_t *vd, uint64_t *psize, uint64_t *ashift) return (error); } - *psize = vattr.va_size; + *max_psize = *psize = vattr.va_size; *ashift = SPA_MINBLOCKSHIFT; return (0); @@ -100,15 +125,16 @@ vdev_file_close(vdev_t *vd) { vdev_file_t *vf = vd->vdev_tsd; - if (vf == NULL) + if (vd->vdev_reopening || vf == NULL) return; if (vf->vf_vnode != NULL) { (void) VOP_PUTPAGE(vf->vf_vnode, 0, 0, B_INVAL, kcred, NULL); - (void) VOP_CLOSE(vf->vf_vnode, spa_mode, 1, 0, kcred, NULL); - VN_RELE(vf->vf_vnode); + (void) VOP_CLOSE(vf->vf_vnode, spa_mode(vd->vdev_spa), 1, 0, + kcred, NULL); } + vd->vdev_delayed_close = B_FALSE; kmem_free(vf, sizeof (vdev_file_t)); vd->vdev_tsd = NULL; } @@ -117,16 +143,17 @@ 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; + vdev_file_t *vf; + ssize_t resid = 0; - if (zio->io_type == ZIO_TYPE_IOCTL) { - /* XXPOLICY */ - if (!vdev_readable(vd)) { - zio->io_error = ENXIO; - return (ZIO_PIPELINE_CONTINUE); - } + if (!vdev_readable(vd)) { + zio->io_error = ENXIO; + return (ZIO_PIPELINE_CONTINUE); + } + vf = vd->vdev_tsd; + + if (zio->io_type == ZIO_TYPE_IOCTL) { switch (zio->io_cmd) { case DKIOCFLUSHWRITECACHE: zio->io_error = VOP_FSYNC(vf->vf_vnode, FSYNC | FDSYNC, @@ -165,6 +192,8 @@ vdev_ops_t vdev_file_ops = { vdev_file_io_start, vdev_file_io_done, NULL, + vdev_file_hold, + vdev_file_rele, VDEV_TYPE_FILE, /* name of this vdev type */ B_TRUE /* leaf vdev */ }; @@ -181,6 +210,8 @@ vdev_ops_t vdev_disk_ops = { vdev_file_io_start, vdev_file_io_done, NULL, + vdev_file_hold, + vdev_file_rele, VDEV_TYPE_DISK, /* name of this vdev type */ B_TRUE /* leaf vdev */ };