diff options
author | Mark Kettenis <kettenis@cvs.openbsd.org> | 2018-07-03 20:40:26 +0000 |
---|---|---|
committer | Mark Kettenis <kettenis@cvs.openbsd.org> | 2018-07-03 20:40:26 +0000 |
commit | 7172f60910c3353e8a649d297b80d3bcab9cabfe (patch) | |
tree | da1b4649fcf0d17b6d56cff207990e21be67cd8e /sys/kern/vfs_syscalls.c | |
parent | 9decf10757b69d8f3d9fc71615993eb79208ce45 (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.c | 47 |
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); |