summaryrefslogtreecommitdiffstats
path: root/sys/kern/vfs_syscalls.c
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2012-10-15 18:15:18 +0000
committerkib <kib@FreeBSD.org>2012-10-15 18:15:18 +0000
commit867cb9c7c5cc7bd4b0932bfb72e53222b2059854 (patch)
tree0777a45974b8aafc2270db97bfb2c2cb6e84c65a /sys/kern/vfs_syscalls.c
parent01647c1f15cf0ee1054cfc03644b5fc4f8aaf28e (diff)
downloadFreeBSD-src-867cb9c7c5cc7bd4b0932bfb72e53222b2059854.zip
FreeBSD-src-867cb9c7c5cc7bd4b0932bfb72e53222b2059854.tar.gz
Acquire the rangelock for truncate(2) as well.
Reported and reviewed by: avg Tested by: pho MFC after: 1 week
Diffstat (limited to 'sys/kern/vfs_syscalls.c')
-rw-r--r--sys/kern/vfs_syscalls.c10
1 files changed, 7 insertions, 3 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 7dafc58..a1b26ce 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -3433,10 +3433,10 @@ kern_truncate(struct thread *td, char *path, enum uio_seg pathseg, off_t length)
{
struct mount *mp;
struct vnode *vp;
+ void *rl_cookie;
struct vattr vattr;
- int error;
struct nameidata nd;
- int vfslocked;
+ int error, vfslocked;
if (length < 0)
return(EINVAL);
@@ -3445,7 +3445,9 @@ kern_truncate(struct thread *td, char *path, enum uio_seg pathseg, off_t length)
return (error);
vfslocked = NDHASGIANT(&nd);
vp = nd.ni_vp;
+ rl_cookie = vn_rangelock_wlock(vp, 0, OFF_MAX);
if ((error = vn_start_write(vp, &mp, V_WAIT | PCATCH)) != 0) {
+ vn_rangelock_unlock(vp, rl_cookie);
vrele(vp);
VFS_UNLOCK_GIANT(vfslocked);
return (error);
@@ -3464,8 +3466,10 @@ kern_truncate(struct thread *td, char *path, enum uio_seg pathseg, off_t length)
vattr.va_size = length;
error = VOP_SETATTR(vp, &vattr, td->td_ucred);
}
- vput(vp);
+ VOP_UNLOCK(vp, 0);
vn_finished_write(mp);
+ vn_rangelock_unlock(vp, rl_cookie);
+ vrele(vp);
VFS_UNLOCK_GIANT(vfslocked);
return (error);
}
OpenPOWER on IntegriCloud