summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_vnops.c
diff options
context:
space:
mode:
authorps <ps@FreeBSD.org>2009-06-04 16:18:07 +0000
committerps <ps@FreeBSD.org>2009-06-04 16:18:07 +0000
commit4505aa56ed32ff6b2aae71255797c497389ad7bc (patch)
tree56f9b7fa8f8be5dc72885c1179f12e95f70105cc /sys/kern/vfs_vnops.c
parente673d3b5e90d6ec6fe0c6bca82c4b813b1af6e3d (diff)
downloadFreeBSD-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.c23
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);
OpenPOWER on IntegriCloud