aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2012-10-15 18:15:18 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2012-10-15 18:15:18 +0000
commit36c6f3aaae06e02110e8dd67bb5c777e179ae797 (patch)
tree0777a45974b8aafc2270db97bfb2c2cb6e84c65a
parentc4acc58d1ded72269e64daea510e94c85d7e675c (diff)
Notes
-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 7dafc58aba376..a1b26ce838083 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);
}