diff options
author | ps <ps@FreeBSD.org> | 2009-06-04 16:18:07 +0000 |
---|---|---|
committer | ps <ps@FreeBSD.org> | 2009-06-04 16:18:07 +0000 |
commit | 4505aa56ed32ff6b2aae71255797c497389ad7bc (patch) | |
tree | 56f9b7fa8f8be5dc72885c1179f12e95f70105cc /sys/kern/vfs_vnops.c | |
parent | e673d3b5e90d6ec6fe0c6bca82c4b813b1af6e3d (diff) | |
download | FreeBSD-src-4505aa56ed32ff6b2aae71255797c497389ad7bc.zip FreeBSD-src-4505aa56ed32ff6b2aae71255797c497389ad7bc.tar.gz |
Support shared vnode locks for write operations when the offset is
provided on filesystems that support it. This really improves mysql
+ innodb performance on ZFS.
Reviewed by: jhb, kmacy, jeffr
Diffstat (limited to 'sys/kern/vfs_vnops.c')
-rw-r--r-- | sys/kern/vfs_vnops.c | 23 |
1 files changed, 19 insertions, 4 deletions
diff --git a/sys/kern/vfs_vnops.c b/sys/kern/vfs_vnops.c index 3cc6f22..e92150e 100644 --- a/sys/kern/vfs_vnops.c +++ b/sys/kern/vfs_vnops.c @@ -367,7 +367,7 @@ vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, active_cred, file_cred, struct iovec aiov; struct mount *mp; struct ucred *cred; - int error; + int error, lock_flags; VFS_ASSERT_GIANT(vp->v_mount); @@ -378,7 +378,13 @@ vn_rdwr(rw, vp, base, len, offset, segflg, ioflg, active_cred, file_cred, (error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) return (error); - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + if (mp != NULL && + (mp->mnt_kern_flag & MNTK_SHARED_WRITES)) { + lock_flags = LK_SHARED; + } else { + lock_flags = LK_EXCLUSIVE; + } + vn_lock(vp, lock_flags | LK_RETRY); } else vn_lock(vp, LK_SHARED | LK_RETRY); @@ -564,7 +570,7 @@ vn_write(fp, uio, active_cred, flags, td) { struct vnode *vp; struct mount *mp; - int error, ioflag; + int error, ioflag, lock_flags; int vfslocked; KASSERT(uio->uio_td == td, ("uio_td %p is not td %p", @@ -587,7 +593,16 @@ vn_write(fp, uio, active_cred, flags, td) if (vp->v_type != VCHR && (error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) goto unlock; - vn_lock(vp, LK_EXCLUSIVE | LK_RETRY); + + if (vp->v_mount != NULL && + (vp->v_mount->mnt_kern_flag & MNTK_SHARED_WRITES) && + (flags & FOF_OFFSET) != 0) { + lock_flags = LK_SHARED; + } else { + lock_flags = LK_EXCLUSIVE; + } + + vn_lock(vp, lock_flags | LK_RETRY); if ((flags & FOF_OFFSET) == 0) uio->uio_offset = fp->f_offset; ioflag |= sequential_heuristic(uio, fp); |