summaryrefslogtreecommitdiff
path: root/sys/kern/vfs_syscalls.c
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2018-07-03 20:40:26 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2018-07-03 20:40:26 +0000
commit7172f60910c3353e8a649d297b80d3bcab9cabfe (patch)
treeda1b4649fcf0d17b6d56cff207990e21be67cd8e /sys/kern/vfs_syscalls.c
parent9decf10757b69d8f3d9fc71615993eb79208ce45 (diff)
Add a new so_seek member to "struct file" such that we can have seekable
files that aren't vnodes. Move the vnode-specific code into its own function. Add an implementation for the "DMA buffers" that can be used by DRI3/prime code to find out the size of the graphics buffer. This implementation is very limited and only supports offset 0 and only for SEEK_SET and SEEK_END. This doesn't really make sense; implementing stat(2) would be a more obvious choice. But this is what Linux does. ok guenther@, visa@
Diffstat (limited to 'sys/kern/vfs_syscalls.c')
-rw-r--r--sys/kern/vfs_syscalls.c47
1 files changed, 10 insertions, 37 deletions
diff --git a/sys/kern/vfs_syscalls.c b/sys/kern/vfs_syscalls.c
index ffc171b6576..da74978c8da 100644
--- a/sys/kern/vfs_syscalls.c
+++ b/sys/kern/vfs_syscalls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vfs_syscalls.c,v 1.291 2018/06/25 16:06:27 visa Exp $ */
+/* $OpenBSD: vfs_syscalls.c,v 1.292 2018/07/03 20:40:25 kettenis Exp $ */
/* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */
/*
@@ -1621,51 +1621,24 @@ sys_lseek(struct proc *p, void *v, register_t *retval)
syscallarg(off_t) offset;
syscallarg(int) whence;
} */ *uap = v;
- struct ucred *cred = p->p_ucred;
struct filedesc *fdp = p->p_fd;
struct file *fp;
- struct vattr vattr;
- struct vnode *vp;
- off_t offarg, newoff;
- int error, special;
+ off_t offset;
+ int error;
if ((fp = fd_getfile(fdp, SCARG(uap, fd))) == NULL)
return (EBADF);
- vp = fp->f_data;
- if (fp->f_type != DTYPE_VNODE || vp->v_type == VFIFO) {
+ if (fp->f_ops->fo_seek == NULL) {
error = ESPIPE;
goto bad;
}
- if (vp->v_type == VCHR)
- special = 1;
- else
- special = 0;
- offarg = SCARG(uap, offset);
-
- switch (SCARG(uap, whence)) {
- case SEEK_CUR:
- newoff = fp->f_offset + offarg;
- break;
- case SEEK_END:
- error = VOP_GETATTR(vp, &vattr, cred, p);
- if (error)
- goto bad;
- newoff = offarg + (off_t)vattr.va_size;
- break;
- case SEEK_SET:
- newoff = offarg;
- break;
- default:
- error = EINVAL;
+ offset = SCARG(uap, offset);
+
+ error = (*fp->f_ops->fo_seek)(fp, &offset, SCARG(uap, whence), p);
+ if (error)
goto bad;
- }
- if (!special) {
- if (newoff < 0) {
- error = EINVAL;
- goto bad;
- }
- }
- *(off_t *)retval = fp->f_offset = newoff;
+
+ *(off_t *)retval = offset;
mtx_enter(&fp->f_mtx);
fp->f_seek++;
mtx_leave(&fp->f_mtx);