summaryrefslogtreecommitdiffstats
path: root/sys/cddl
diff options
context:
space:
mode:
authorpjd <pjd@FreeBSD.org>2007-04-21 12:02:57 +0000
committerpjd <pjd@FreeBSD.org>2007-04-21 12:02:57 +0000
commit24d44898020531c24ba8914b294876e52f304e4f (patch)
tree932d85fefa7fcb86834f441607b2a4438d5b0c0f /sys/cddl
parente60ce7e12076f27ac5471441a6940e2254378506 (diff)
downloadFreeBSD-src-24d44898020531c24ba8914b294876e52f304e4f.zip
FreeBSD-src-24d44898020531c24ba8914b294876e52f304e4f.tar.gz
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 <bu7cher@yandex.ru> @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 <dry@dry.pl>
Diffstat (limited to 'sys/cddl')
-rw-r--r--sys/cddl/compat/opensolaris/kern/opensolaris_vfs.c2
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/spa.c9
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/vdev.c4
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zfs_vnops.c28
-rw-r--r--sys/cddl/contrib/opensolaris/uts/common/fs/zfs/zio.c20
5 files changed, 38 insertions, 25 deletions
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);
}
}
OpenPOWER on IntegriCloud