diff options
author | kib <kib@FreeBSD.org> | 2012-10-15 18:15:18 +0000 |
---|---|---|
committer | kib <kib@FreeBSD.org> | 2012-10-15 18:15:18 +0000 |
commit | 867cb9c7c5cc7bd4b0932bfb72e53222b2059854 (patch) | |
tree | 0777a45974b8aafc2270db97bfb2c2cb6e84c65a /sys/kern/vfs_syscalls.c | |
parent | 01647c1f15cf0ee1054cfc03644b5fc4f8aaf28e (diff) | |
download | FreeBSD-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.c | 10 |
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); } |