From 24d44898020531c24ba8914b294876e52f304e4f Mon Sep 17 00:00:00 2001 From: pjd Date: Sat, 21 Apr 2007 12:02:57 +0000 Subject: MFp4: @118370 Correct typo. @118371 Integrate changes from vendor. @118491 Show backtrace on unexpected code paths. @118494 Integrate changes from vendor. @118504 Fix sendfile(2). I had two ways of fixing it: 1. Fixing sendfile(2) itself to use VOP_GETPAGES() instead of hacking around with vn_rdwr(UIO_NOCOPY), which was suggested by ups. 2. Modify ZFS behaviour to handle this special case. Although 1 is more correct, I've choosen 2, because hack from 1 have a side-effect of beeing faster - it reads ahead MAXBSIZE bytes instead of reading page by page. This is not easy to implement with VOP_GETPAGES(), at least not for me in this very moment. Reported by: Andrey V. Elsukov @118525 Reorganize the code to reduce diff. @118526 This code path is expected. It is simply when file is opened with O_FSYNC flag. Reported by: kris Reported by: Michal Suszko --- cddl/contrib/opensolaris/cmd/zdb/zdb.c | 12 +++++----- .../lib/libzfs/common/libzfs_changelist.c | 15 ++++-------- .../opensolaris/lib/libzfs/common/libzfs_config.c | 28 ++++++---------------- .../opensolaris/lib/libzfs/common/libzfs_import.c | 4 +--- contrib/opensolaris/cmd/zdb/zdb.c | 12 +++++----- .../lib/libzfs/common/libzfs_changelist.c | 15 ++++-------- .../opensolaris/lib/libzfs/common/libzfs_config.c | 28 ++++++---------------- .../opensolaris/lib/libzfs/common/libzfs_import.c | 4 +--- sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c | 2 +- .../contrib/opensolaris/uts/common/fs/zfs/spa.c | 9 +++---- .../contrib/opensolaris/uts/common/fs/zfs/vdev.c | 4 ++-- .../opensolaris/uts/common/fs/zfs/zfs_vnops.c | 28 +++++++++++++++------- .../contrib/opensolaris/uts/common/fs/zfs/zio.c | 20 ++++++++++------ sys/compat/opensolaris/kern/opensolaris_vfs.c | 2 +- sys/contrib/opensolaris/uts/common/fs/zfs/spa.c | 9 +++---- sys/contrib/opensolaris/uts/common/fs/zfs/vdev.c | 4 ++-- .../opensolaris/uts/common/fs/zfs/zfs_vnops.c | 28 +++++++++++++++------- sys/contrib/opensolaris/uts/common/fs/zfs/zio.c | 20 ++++++++++------ 18 files changed, 112 insertions(+), 132 deletions(-) diff --git a/cddl/contrib/opensolaris/cmd/zdb/zdb.c b/cddl/contrib/opensolaris/cmd/zdb/zdb.c index bb7a52e..03abc3a 100644 --- a/cddl/contrib/opensolaris/cmd/zdb/zdb.c +++ b/cddl/contrib/opensolaris/cmd/zdb/zdb.c @@ -932,11 +932,11 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header) if (doi.doi_checksum != ZIO_CHECKSUM_INHERIT || verbosity >= 6) (void) snprintf(aux + strlen(aux), sizeof (aux), " (K=%s)", - zio_checksum_table[doi.doi_checksum].ci_name); + zio_checksum_table[doi.doi_checksum].ci_name); if (doi.doi_compress != ZIO_COMPRESS_INHERIT || verbosity >= 6) (void) snprintf(aux + strlen(aux), sizeof (aux), " (Z=%s)", - zio_compress_table[doi.doi_compress].ci_name); + zio_compress_table[doi.doi_compress].ci_name); (void) printf("%10lld %3u %5s %5s %5s %5s %s%s\n", (u_longlong_t)object, doi.doi_indirection, iblk, dblk, lsize, @@ -1441,7 +1441,7 @@ zdb_blkptr_cb(traverse_blk_cache_t *bc, spa_t *spa, void *arg) (u_longlong_t)zb->zb_objset, (u_longlong_t)zb->zb_object, (u_longlong_t)blkid2offset(bc->bc_dnode, - zb->zb_level, zb->zb_blkid), + zb->zb_level, zb->zb_blkid), blkbuf); } @@ -1951,8 +1951,8 @@ zdb_read_block(char *thing, spa_t **spap) spa_close(spa, (void *)zdb_read_block); error = spa_open(spa_name, spap, (void *)zdb_read_block); if (error) - fatal("Failed to open pool '%s': errno = %d\n", - spa_name, error); + fatal("Failed to open pool '%s': %s", + spa_name, strerror(error)); spa = *spap; } @@ -2156,7 +2156,7 @@ main(int argc, char **argv) } if (error) - fatal("can't open %s: error %d", argv[0], error); + fatal("can't open %s: %s", argv[0], strerror(error)); argv++; if (--argc > 0) { diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c index d68c420..5e6de6d 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c @@ -339,22 +339,15 @@ void changelist_free(prop_changelist_t *clp) { prop_changenode_t *cn; - uu_list_walk_t *walk; + void *cookie; if (clp->cl_list) { - verify((walk = uu_list_walk_start(clp->cl_list, - UU_WALK_ROBUST)) != NULL); - - while ((cn = uu_list_walk_next(walk)) != NULL) { - - uu_list_remove(clp->cl_list, cn); - + cookie = NULL; + while ((cn = uu_list_teardown(clp->cl_list, &cookie)) != NULL) { zfs_close(cn->cn_handle); free(cn); } - uu_list_walk_end(walk); - uu_list_destroy(clp->cl_list); } if (clp->cl_pool) @@ -418,7 +411,7 @@ change_one(zfs_handle_t *zhp, void *data) } else { ASSERT(!clp->cl_alldependents); verify(uu_list_insert_before(clp->cl_list, - uu_list_first(clp->cl_list), cn) == 0); + uu_list_first(clp->cl_list), cn) == 0); } if (!clp->cl_alldependents) diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c index 45e2920..94640d1 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_config.c @@ -74,22 +74,16 @@ void namespace_clear(libzfs_handle_t *hdl) { if (hdl->libzfs_ns_avl) { - uu_avl_walk_t *walk; config_node_t *cn; + void *cookie = NULL; - if ((walk = uu_avl_walk_start(hdl->libzfs_ns_avl, - UU_WALK_ROBUST)) == NULL) - return; - - while ((cn = uu_avl_walk_next(walk)) != NULL) { - uu_avl_remove(hdl->libzfs_ns_avl, cn); + while ((cn = uu_avl_teardown(hdl->libzfs_ns_avl, + &cookie)) != NULL) { nvlist_free(cn->cn_config); free(cn->cn_name); free(cn); } - uu_avl_walk_end(walk); - uu_avl_destroy(hdl->libzfs_ns_avl); hdl->libzfs_ns_avl = NULL; } @@ -110,7 +104,7 @@ namespace_reload(libzfs_handle_t *hdl) config_node_t *cn; nvpair_t *elem; zfs_cmd_t zc = { 0 }; - uu_avl_walk_t *walk; + void *cookie; if (hdl->libzfs_ns_gen == 0) { /* @@ -172,21 +166,13 @@ namespace_reload(libzfs_handle_t *hdl) /* * Clear out any existing configuration information. */ - if ((walk = uu_avl_walk_start(hdl->libzfs_ns_avl, - UU_WALK_ROBUST)) == NULL) { - nvlist_free(config); - return (no_memory(hdl)); - } - - while ((cn = uu_avl_walk_next(walk)) != NULL) { - uu_avl_remove(hdl->libzfs_ns_avl, cn); + cookie = NULL; + while ((cn = uu_avl_teardown(hdl->libzfs_ns_avl, &cookie)) != NULL) { nvlist_free(cn->cn_config); free(cn->cn_name); free(cn); } - uu_avl_walk_end(walk); - elem = NULL; while ((elem = nvlist_next_nvpair(config, elem)) != NULL) { nvlist_t *child; @@ -222,7 +208,7 @@ namespace_reload(libzfs_handle_t *hdl) } /* - * Retrive the configuration for the given pool. The configuration is a nvlist + * Retrieve the configuration for the given pool. The configuration is a nvlist * describing the vdevs, as well as the statistics associated with each one. */ nvlist_t * diff --git a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c index 26d15e9..1c77045 100644 --- a/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c +++ b/cddl/contrib/opensolaris/lib/libzfs/common/libzfs_import.c @@ -220,7 +220,7 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path, &state) == 0 && state == POOL_STATE_SPARE && nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID, &vdev_guid) == 0) { if ((ne = zfs_alloc(hdl, sizeof (name_entry_t))) == NULL) - return (-1); + return (-1); if ((ne->ne_name = zfs_strdup(hdl, path)) == NULL) { free(ne); @@ -748,7 +748,6 @@ nvlist_t * zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv) { int i; - DIR *dirp; char path[MAXPATHLEN]; nvlist_t *ret = NULL, *config; int fd; @@ -824,7 +823,6 @@ error: free(ne); } - return (ret); } diff --git a/contrib/opensolaris/cmd/zdb/zdb.c b/contrib/opensolaris/cmd/zdb/zdb.c index bb7a52e..03abc3a 100644 --- a/contrib/opensolaris/cmd/zdb/zdb.c +++ b/contrib/opensolaris/cmd/zdb/zdb.c @@ -932,11 +932,11 @@ dump_object(objset_t *os, uint64_t object, int verbosity, int *print_header) if (doi.doi_checksum != ZIO_CHECKSUM_INHERIT || verbosity >= 6) (void) snprintf(aux + strlen(aux), sizeof (aux), " (K=%s)", - zio_checksum_table[doi.doi_checksum].ci_name); + zio_checksum_table[doi.doi_checksum].ci_name); if (doi.doi_compress != ZIO_COMPRESS_INHERIT || verbosity >= 6) (void) snprintf(aux + strlen(aux), sizeof (aux), " (Z=%s)", - zio_compress_table[doi.doi_compress].ci_name); + zio_compress_table[doi.doi_compress].ci_name); (void) printf("%10lld %3u %5s %5s %5s %5s %s%s\n", (u_longlong_t)object, doi.doi_indirection, iblk, dblk, lsize, @@ -1441,7 +1441,7 @@ zdb_blkptr_cb(traverse_blk_cache_t *bc, spa_t *spa, void *arg) (u_longlong_t)zb->zb_objset, (u_longlong_t)zb->zb_object, (u_longlong_t)blkid2offset(bc->bc_dnode, - zb->zb_level, zb->zb_blkid), + zb->zb_level, zb->zb_blkid), blkbuf); } @@ -1951,8 +1951,8 @@ zdb_read_block(char *thing, spa_t **spap) spa_close(spa, (void *)zdb_read_block); error = spa_open(spa_name, spap, (void *)zdb_read_block); if (error) - fatal("Failed to open pool '%s': errno = %d\n", - spa_name, error); + fatal("Failed to open pool '%s': %s", + spa_name, strerror(error)); spa = *spap; } @@ -2156,7 +2156,7 @@ main(int argc, char **argv) } if (error) - fatal("can't open %s: error %d", argv[0], error); + fatal("can't open %s: %s", argv[0], strerror(error)); argv++; if (--argc > 0) { diff --git a/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c b/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c index d68c420..5e6de6d 100644 --- a/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c +++ b/contrib/opensolaris/lib/libzfs/common/libzfs_changelist.c @@ -339,22 +339,15 @@ void changelist_free(prop_changelist_t *clp) { prop_changenode_t *cn; - uu_list_walk_t *walk; + void *cookie; if (clp->cl_list) { - verify((walk = uu_list_walk_start(clp->cl_list, - UU_WALK_ROBUST)) != NULL); - - while ((cn = uu_list_walk_next(walk)) != NULL) { - - uu_list_remove(clp->cl_list, cn); - + cookie = NULL; + while ((cn = uu_list_teardown(clp->cl_list, &cookie)) != NULL) { zfs_close(cn->cn_handle); free(cn); } - uu_list_walk_end(walk); - uu_list_destroy(clp->cl_list); } if (clp->cl_pool) @@ -418,7 +411,7 @@ change_one(zfs_handle_t *zhp, void *data) } else { ASSERT(!clp->cl_alldependents); verify(uu_list_insert_before(clp->cl_list, - uu_list_first(clp->cl_list), cn) == 0); + uu_list_first(clp->cl_list), cn) == 0); } if (!clp->cl_alldependents) diff --git a/contrib/opensolaris/lib/libzfs/common/libzfs_config.c b/contrib/opensolaris/lib/libzfs/common/libzfs_config.c index 45e2920..94640d1 100644 --- a/contrib/opensolaris/lib/libzfs/common/libzfs_config.c +++ b/contrib/opensolaris/lib/libzfs/common/libzfs_config.c @@ -74,22 +74,16 @@ void namespace_clear(libzfs_handle_t *hdl) { if (hdl->libzfs_ns_avl) { - uu_avl_walk_t *walk; config_node_t *cn; + void *cookie = NULL; - if ((walk = uu_avl_walk_start(hdl->libzfs_ns_avl, - UU_WALK_ROBUST)) == NULL) - return; - - while ((cn = uu_avl_walk_next(walk)) != NULL) { - uu_avl_remove(hdl->libzfs_ns_avl, cn); + while ((cn = uu_avl_teardown(hdl->libzfs_ns_avl, + &cookie)) != NULL) { nvlist_free(cn->cn_config); free(cn->cn_name); free(cn); } - uu_avl_walk_end(walk); - uu_avl_destroy(hdl->libzfs_ns_avl); hdl->libzfs_ns_avl = NULL; } @@ -110,7 +104,7 @@ namespace_reload(libzfs_handle_t *hdl) config_node_t *cn; nvpair_t *elem; zfs_cmd_t zc = { 0 }; - uu_avl_walk_t *walk; + void *cookie; if (hdl->libzfs_ns_gen == 0) { /* @@ -172,21 +166,13 @@ namespace_reload(libzfs_handle_t *hdl) /* * Clear out any existing configuration information. */ - if ((walk = uu_avl_walk_start(hdl->libzfs_ns_avl, - UU_WALK_ROBUST)) == NULL) { - nvlist_free(config); - return (no_memory(hdl)); - } - - while ((cn = uu_avl_walk_next(walk)) != NULL) { - uu_avl_remove(hdl->libzfs_ns_avl, cn); + cookie = NULL; + while ((cn = uu_avl_teardown(hdl->libzfs_ns_avl, &cookie)) != NULL) { nvlist_free(cn->cn_config); free(cn->cn_name); free(cn); } - uu_avl_walk_end(walk); - elem = NULL; while ((elem = nvlist_next_nvpair(config, elem)) != NULL) { nvlist_t *child; @@ -222,7 +208,7 @@ namespace_reload(libzfs_handle_t *hdl) } /* - * Retrive the configuration for the given pool. The configuration is a nvlist + * Retrieve the configuration for the given pool. The configuration is a nvlist * describing the vdevs, as well as the statistics associated with each one. */ nvlist_t * diff --git a/contrib/opensolaris/lib/libzfs/common/libzfs_import.c b/contrib/opensolaris/lib/libzfs/common/libzfs_import.c index 26d15e9..1c77045 100644 --- a/contrib/opensolaris/lib/libzfs/common/libzfs_import.c +++ b/contrib/opensolaris/lib/libzfs/common/libzfs_import.c @@ -220,7 +220,7 @@ add_config(libzfs_handle_t *hdl, pool_list_t *pl, const char *path, &state) == 0 && state == POOL_STATE_SPARE && nvlist_lookup_uint64(config, ZPOOL_CONFIG_GUID, &vdev_guid) == 0) { if ((ne = zfs_alloc(hdl, sizeof (name_entry_t))) == NULL) - return (-1); + return (-1); if ((ne->ne_name = zfs_strdup(hdl, path)) == NULL) { free(ne); @@ -748,7 +748,6 @@ nvlist_t * zpool_find_import(libzfs_handle_t *hdl, int argc, char **argv) { int i; - DIR *dirp; char path[MAXPATHLEN]; nvlist_t *ret = NULL, *config; int fd; @@ -824,7 +823,6 @@ error: free(ne); } - return (ret); } diff --git a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c index 35404ca..ef184b4 100644 --- a/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c +++ b/sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c @@ -206,7 +206,7 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath, mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE | MNT_ROOTFS); /* * Unprivileged user can trigger mounting a snapshot, but we don't want - * him to unmount it, so we switch to privileged credential. + * him to unmount it, so we switch to privileged credentials. */ crfree(mp->mnt_cred); mp->mnt_cred = crdup(kcred); diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c index f8d9465..c6a95a1 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c @@ -499,10 +499,9 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) /* * Try to open all vdevs, loading each label in the process. */ - if (vdev_open(rvd) != 0) { - error = ENXIO; + error = vdev_open(rvd); + if (error != 0) goto out; - } /* * Validate the labels for all leaf vdevs. We need to grab the config @@ -513,10 +512,8 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) error = vdev_validate(rvd); spa_config_exit(spa, FTAG); - if (error != 0) { - error = EBADF; + if (error != 0) goto out; - } if (rvd->vdev_state <= VDEV_STATE_CANT_OPEN) { error = ENXIO; diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c index 0fceb8d..d15f6e2 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c @@ -931,7 +931,7 @@ vdev_validate(vdev_t *vd) for (c = 0; c < vd->vdev_children; c++) if (vdev_validate(vd->vdev_child[c]) != 0) - return (-1); + return (EBADF); /* * If the device has already failed, or was marked offline, don't do @@ -974,7 +974,7 @@ vdev_validate(vdev_t *vd) if (spa->spa_load_state == SPA_LOAD_OPEN && state != POOL_STATE_ACTIVE) - return (-1); + return (EBADF); } /* diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index 5f74eb8..7af6b20 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -165,10 +165,8 @@ zfs_open(ap) int flag = ap->a_mode; /* Keep a count of the synchronous opens in the znode */ - if (flag & FFSYNC) { + if (flag & FFSYNC) atomic_inc_32(&zp->z_sync_cnt); - ZFS_LOG(0, "Unexpected code path, report to pjd@FreeBSD.org"); - } vnode_create_vobject(vp, zp->z_phys->zp_size, ap->a_td); return (0); @@ -188,10 +186,8 @@ zfs_close(ap) int flag = ap->a_fflag; /* Decrement the synchronous opens in the znode */ - if (flag & FFSYNC) { + if (flag & FFSYNC) atomic_dec_32(&zp->z_sync_cnt); - ZFS_LOG(0, "Unexpected code path, report to pjd@FreeBSD.org"); - } return (0); } @@ -362,6 +358,7 @@ mappedread(vnode_t *vp, int nbytes, uio_t *uio) vm_page_t m; struct sf_buf *sf; int64_t start, off; + caddr_t va; int len = nbytes; int error = 0; @@ -378,8 +375,6 @@ mappedread(vnode_t *vp, int nbytes, uio_t *uio) again: if ((m = vm_page_lookup(obj, OFF_TO_IDX(start))) != NULL && vm_page_is_valid(m, (vm_offset_t)off, bytes)) { - caddr_t va; - if (vm_page_sleep_if_busy(m, FALSE, "zfsmrb")) goto again; vm_page_busy(m); @@ -392,6 +387,21 @@ again: sched_unpin(); VM_OBJECT_LOCK(obj); vm_page_wakeup(m); + } else if (m != NULL && uio->uio_segflg == UIO_NOCOPY) { + if (vm_page_sleep_if_busy(m, FALSE, "zfsmrb")) + goto again; + vm_page_busy(m); + VM_OBJECT_UNLOCK(obj); + sched_pin(); + sf = sf_buf_alloc(m, SFB_CPUPRIVATE); + va = (caddr_t)sf_buf_kva(sf); + error = dmu_read(os, zp->z_id, start + off, bytes, + (void *)(va + off)); + sf_buf_free(sf); + sched_unpin(); + VM_OBJECT_LOCK(obj); + vm_page_wakeup(m); + uio->uio_resid -= bytes; } else { VM_OBJECT_UNLOCK(obj); error = dmu_read_uio(os, zp->z_id, uio, bytes); @@ -2461,7 +2471,7 @@ top: if (tvp) vrele(tvp); else { - ZFS_LOG(0, "Unexpected code path, report to pjd@FreeBSD.org"); + ZFS_LOG(0x100, "Unexpected code path, report to pjd@FreeBSD.org"); tvp = ZTOV(tzp); vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY, curthread); } diff --git a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c index 6bc4a36..99c0dd3 100644 --- a/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c +++ b/sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c @@ -79,12 +79,13 @@ zio_sync_pass_t zio_sync_pass = { 1, /* zp_rewrite */ }; -#ifdef ZIO_USE_UMA /* * ========================================================================== * I/O kmem caches * ========================================================================== */ +kmem_cache_t *zio_cache; +#ifdef ZIO_USE_UMA kmem_cache_t *zio_buf_cache[SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT]; kmem_cache_t *zio_data_buf_cache[SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT]; #endif @@ -107,6 +108,9 @@ zio_init(void) #endif #endif + zio_cache = kmem_cache_create("zio_cache", sizeof (zio_t), 0, + NULL, NULL, NULL, NULL, NULL, 0); + #ifdef ZIO_USE_UMA /* * For small buffers, we want a cache for each multiple of @@ -183,6 +187,8 @@ zio_fini(void) } #endif + kmem_cache_destroy(zio_cache); + zio_inject_fini(); } @@ -329,7 +335,8 @@ zio_create(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, ASSERT3U(size, <=, SPA_MAXBLOCKSIZE); ASSERT(P2PHASE(size, SPA_MINBLOCKSIZE) == 0); - zio = kmem_zalloc(sizeof (zio_t), KM_SLEEP); + zio = kmem_cache_alloc(zio_cache, KM_SLEEP); + bzero(zio, sizeof (zio_t)); zio->io_parent = pio; zio->io_spa = spa; zio->io_txg = txg; @@ -777,7 +784,7 @@ zio_wait(zio_t *zio) error = zio->io_error; cv_destroy(&zio->io_cv); mutex_destroy(&zio->io_lock); - kmem_free(zio, sizeof (zio_t)); + kmem_cache_free(zio_cache, zio); return (error); } @@ -957,9 +964,8 @@ zio_done(zio_t *zio) } /* - * Note: this I/O is now done, and will shortly be - * kmem_free()'d, so there is no need to clear this (or any - * other) flag. + * Note: this I/O is now done, and will shortly be freed, so there is no + * need to clear this (or any other) flag. */ if (zio->io_flags & ZIO_FLAG_CONFIG_GRABBED) spa_config_exit(spa, zio); @@ -971,7 +977,7 @@ zio_done(zio_t *zio) cv_broadcast(&zio->io_cv); mutex_exit(&zio->io_lock); } else { - kmem_free(zio, sizeof (zio_t)); + kmem_cache_free(zio_cache, zio); } } diff --git a/sys/compat/opensolaris/kern/opensolaris_vfs.c b/sys/compat/opensolaris/kern/opensolaris_vfs.c index 35404ca..ef184b4 100644 --- a/sys/compat/opensolaris/kern/opensolaris_vfs.c +++ b/sys/compat/opensolaris/kern/opensolaris_vfs.c @@ -206,7 +206,7 @@ domount(kthread_t *td, vnode_t *vp, const char *fstype, char *fspath, mp->mnt_flag |= fsflags & (MNT_UPDATEMASK | MNT_FORCE | MNT_ROOTFS); /* * Unprivileged user can trigger mounting a snapshot, but we don't want - * him to unmount it, so we switch to privileged credential. + * him to unmount it, so we switch to privileged credentials. */ crfree(mp->mnt_cred); mp->mnt_cred = crdup(kcred); diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/spa.c b/sys/contrib/opensolaris/uts/common/fs/zfs/spa.c index f8d9465..c6a95a1 100644 --- a/sys/contrib/opensolaris/uts/common/fs/zfs/spa.c +++ b/sys/contrib/opensolaris/uts/common/fs/zfs/spa.c @@ -499,10 +499,9 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) /* * Try to open all vdevs, loading each label in the process. */ - if (vdev_open(rvd) != 0) { - error = ENXIO; + error = vdev_open(rvd); + if (error != 0) goto out; - } /* * Validate the labels for all leaf vdevs. We need to grab the config @@ -513,10 +512,8 @@ spa_load(spa_t *spa, nvlist_t *config, spa_load_state_t state, int mosconfig) error = vdev_validate(rvd); spa_config_exit(spa, FTAG); - if (error != 0) { - error = EBADF; + if (error != 0) goto out; - } if (rvd->vdev_state <= VDEV_STATE_CANT_OPEN) { error = ENXIO; diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/vdev.c b/sys/contrib/opensolaris/uts/common/fs/zfs/vdev.c index 0fceb8d..d15f6e2 100644 --- a/sys/contrib/opensolaris/uts/common/fs/zfs/vdev.c +++ b/sys/contrib/opensolaris/uts/common/fs/zfs/vdev.c @@ -931,7 +931,7 @@ vdev_validate(vdev_t *vd) for (c = 0; c < vd->vdev_children; c++) if (vdev_validate(vd->vdev_child[c]) != 0) - return (-1); + return (EBADF); /* * If the device has already failed, or was marked offline, don't do @@ -974,7 +974,7 @@ vdev_validate(vdev_t *vd) if (spa->spa_load_state == SPA_LOAD_OPEN && state != POOL_STATE_ACTIVE) - return (-1); + return (EBADF); } /* diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c b/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c index 5f74eb8..7af6b20 100644 --- a/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c +++ b/sys/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c @@ -165,10 +165,8 @@ zfs_open(ap) int flag = ap->a_mode; /* Keep a count of the synchronous opens in the znode */ - if (flag & FFSYNC) { + if (flag & FFSYNC) atomic_inc_32(&zp->z_sync_cnt); - ZFS_LOG(0, "Unexpected code path, report to pjd@FreeBSD.org"); - } vnode_create_vobject(vp, zp->z_phys->zp_size, ap->a_td); return (0); @@ -188,10 +186,8 @@ zfs_close(ap) int flag = ap->a_fflag; /* Decrement the synchronous opens in the znode */ - if (flag & FFSYNC) { + if (flag & FFSYNC) atomic_dec_32(&zp->z_sync_cnt); - ZFS_LOG(0, "Unexpected code path, report to pjd@FreeBSD.org"); - } return (0); } @@ -362,6 +358,7 @@ mappedread(vnode_t *vp, int nbytes, uio_t *uio) vm_page_t m; struct sf_buf *sf; int64_t start, off; + caddr_t va; int len = nbytes; int error = 0; @@ -378,8 +375,6 @@ mappedread(vnode_t *vp, int nbytes, uio_t *uio) again: if ((m = vm_page_lookup(obj, OFF_TO_IDX(start))) != NULL && vm_page_is_valid(m, (vm_offset_t)off, bytes)) { - caddr_t va; - if (vm_page_sleep_if_busy(m, FALSE, "zfsmrb")) goto again; vm_page_busy(m); @@ -392,6 +387,21 @@ again: sched_unpin(); VM_OBJECT_LOCK(obj); vm_page_wakeup(m); + } else if (m != NULL && uio->uio_segflg == UIO_NOCOPY) { + if (vm_page_sleep_if_busy(m, FALSE, "zfsmrb")) + goto again; + vm_page_busy(m); + VM_OBJECT_UNLOCK(obj); + sched_pin(); + sf = sf_buf_alloc(m, SFB_CPUPRIVATE); + va = (caddr_t)sf_buf_kva(sf); + error = dmu_read(os, zp->z_id, start + off, bytes, + (void *)(va + off)); + sf_buf_free(sf); + sched_unpin(); + VM_OBJECT_LOCK(obj); + vm_page_wakeup(m); + uio->uio_resid -= bytes; } else { VM_OBJECT_UNLOCK(obj); error = dmu_read_uio(os, zp->z_id, uio, bytes); @@ -2461,7 +2471,7 @@ top: if (tvp) vrele(tvp); else { - ZFS_LOG(0, "Unexpected code path, report to pjd@FreeBSD.org"); + ZFS_LOG(0x100, "Unexpected code path, report to pjd@FreeBSD.org"); tvp = ZTOV(tzp); vn_lock(tvp, LK_EXCLUSIVE | LK_RETRY, curthread); } diff --git a/sys/contrib/opensolaris/uts/common/fs/zfs/zio.c b/sys/contrib/opensolaris/uts/common/fs/zfs/zio.c index 6bc4a36..99c0dd3 100644 --- a/sys/contrib/opensolaris/uts/common/fs/zfs/zio.c +++ b/sys/contrib/opensolaris/uts/common/fs/zfs/zio.c @@ -79,12 +79,13 @@ zio_sync_pass_t zio_sync_pass = { 1, /* zp_rewrite */ }; -#ifdef ZIO_USE_UMA /* * ========================================================================== * I/O kmem caches * ========================================================================== */ +kmem_cache_t *zio_cache; +#ifdef ZIO_USE_UMA kmem_cache_t *zio_buf_cache[SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT]; kmem_cache_t *zio_data_buf_cache[SPA_MAXBLOCKSIZE >> SPA_MINBLOCKSHIFT]; #endif @@ -107,6 +108,9 @@ zio_init(void) #endif #endif + zio_cache = kmem_cache_create("zio_cache", sizeof (zio_t), 0, + NULL, NULL, NULL, NULL, NULL, 0); + #ifdef ZIO_USE_UMA /* * For small buffers, we want a cache for each multiple of @@ -183,6 +187,8 @@ zio_fini(void) } #endif + kmem_cache_destroy(zio_cache); + zio_inject_fini(); } @@ -329,7 +335,8 @@ zio_create(zio_t *pio, spa_t *spa, uint64_t txg, blkptr_t *bp, ASSERT3U(size, <=, SPA_MAXBLOCKSIZE); ASSERT(P2PHASE(size, SPA_MINBLOCKSIZE) == 0); - zio = kmem_zalloc(sizeof (zio_t), KM_SLEEP); + zio = kmem_cache_alloc(zio_cache, KM_SLEEP); + bzero(zio, sizeof (zio_t)); zio->io_parent = pio; zio->io_spa = spa; zio->io_txg = txg; @@ -777,7 +784,7 @@ zio_wait(zio_t *zio) error = zio->io_error; cv_destroy(&zio->io_cv); mutex_destroy(&zio->io_lock); - kmem_free(zio, sizeof (zio_t)); + kmem_cache_free(zio_cache, zio); return (error); } @@ -957,9 +964,8 @@ zio_done(zio_t *zio) } /* - * Note: this I/O is now done, and will shortly be - * kmem_free()'d, so there is no need to clear this (or any - * other) flag. + * Note: this I/O is now done, and will shortly be freed, so there is no + * need to clear this (or any other) flag. */ if (zio->io_flags & ZIO_FLAG_CONFIG_GRABBED) spa_config_exit(spa, zio); @@ -971,7 +977,7 @@ zio_done(zio_t *zio) cv_broadcast(&zio->io_cv); mutex_exit(&zio->io_lock); } else { - kmem_free(zio, sizeof (zio_t)); + kmem_cache_free(zio_cache, zio); } } -- cgit v1.1