summaryrefslogtreecommitdiff
path: root/sys/kern
diff options
context:
space:
mode:
authorMatthew Dempsky <matthew@cvs.openbsd.org>2011-07-06 04:41:17 +0000
committerMatthew Dempsky <matthew@cvs.openbsd.org>2011-07-06 04:41:17 +0000
commit48f0c4d99fa1f45a0662bbfdca2eaabab685d4f3 (patch)
tree9b67d1e60f991589dd29e3853809ceb7c3e46405 /sys/kern
parent6baf6e4279bc4c53268717004e48ffe1c79c17c9 (diff)
VOP_GETATTR() can sleep when accessing a file over NFS, so use
FREF()/FRELE() in lseek() so our struct file doesn't disappear in the mean time. Incorporating suggestions from tedu@ and guenther@; ok guenther@
Diffstat (limited to 'sys/kern')
-rw-r--r--sys/kern/vfs_syscalls.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index 35555030b9e..facd5f2e85c 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_syscalls.c,v 1.166 2011/07/05 21:38:58 matthew Exp $ */
+/* $OpenBSD: vfs_syscalls.c,v 1.167 2011/07/06 04:41:16 matthew Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */
/*
@@ -1381,6 +1381,7 @@ sys_lseek(struct proc *p, void *v, register_t *retval)
vp = (struct vnode *)fp->f_data;
if (vp->v_type == VFIFO)
return (ESPIPE);
+ FREF(fp);
if (vp->v_type == VCHR)
special = 1;
else
@@ -1392,25 +1393,30 @@ sys_lseek(struct proc *p, void *v, register_t *retval)
newoff = fp->f_offset + offarg;
break;
case SEEK_END:
- error = VOP_GETATTR((struct vnode *)fp->f_data, &vattr,
- cred, p);
+ error = VOP_GETATTR(vp, &vattr, cred, p);
if (error)
- return (error);
+ goto bad;
newoff = offarg + (off_t)vattr.va_size;
break;
case SEEK_SET:
newoff = offarg;
break;
default:
- return (EINVAL);
+ error = EINVAL;
+ goto bad;
}
if (!special) {
- if (newoff < 0)
- return (EINVAL);
+ if (newoff < 0) {
+ error = EINVAL;
+ goto bad;
+ }
}
*(off_t *)retval = fp->f_offset = newoff;
fp->f_seek++;
- return (0);
+ error = 0;
+ bad:
+ FRELE(fp);
+ return (error);
}
/*