diff options
author | kstailey <kstailey@cvs.openbsd.org> | 1999-09-17 13:41:30 +0000 |
---|---|---|
committer | kstailey <kstailey@cvs.openbsd.org> | 1999-09-17 13:41:30 +0000 |
commit | 94614cae4576243ee91363ef921a364dc5abdc20 (patch) | |
tree | c1ec8445579da3ffc4183fe63fa91d30bdd63159 /sys/compat | |
parent | ba903d4dd684a871a55c21d616e2dcfab110e3c9 (diff) |
rest of pread() etc., fdatasync() hack
Diffstat (limited to 'sys/compat')
-rw-r--r-- | sys/compat/netbsd/netbsd_misc.c | 33 | ||||
-rw-r--r-- | sys/compat/netbsd/netbsd_pos_io.c | 217 | ||||
-rw-r--r-- | sys/compat/netbsd/syscalls.master | 5 |
3 files changed, 239 insertions, 16 deletions
diff --git a/sys/compat/netbsd/netbsd_misc.c b/sys/compat/netbsd/netbsd_misc.c index 45559be3ed4..6eadffd8da7 100644 --- a/sys/compat/netbsd/netbsd_misc.c +++ b/sys/compat/netbsd/netbsd_misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: netbsd_misc.c,v 1.3 1999/09/16 13:20:06 kstailey Exp $ */ +/* $OpenBSD: netbsd_misc.c,v 1.4 1999/09/17 13:41:29 kstailey Exp $ */ /* * Copyright (c) 1982, 1986, 1989, 1991, 1993 @@ -38,10 +38,14 @@ * SUCH DAMAGE. * * @(#)kern_fork.c 8.6 (Berkeley) 4/8/94 + * @(#)vfs_syscalls.c 8.28 (Berkeley) 12/10/94 */ #include <sys/param.h> +#include <sys/file.h> +#include <sys/mount.h> #include <sys/proc.h> +#include <sys/vnode.h> #include <compat/netbsd/netbsd_types.h> #include <compat/netbsd/netbsd_signal.h> @@ -57,3 +61,30 @@ netbsd_sys___vfork14(p, v, retval) { return (fork1(p, ISVFORK, 0, NULL, 0, retval)); } + +/* XXX syncs whole file */ +/*ARGSUSED*/ +int +netbsd_sys_fdatasync(p, v, retval) + struct proc *p; + void *v; + register_t *retval; +{ + struct netbsd_sys_fdatasync_args /* { + syscallarg(int) fd; + } */ *uap = v; + register struct vnode *vp; + struct file *fp; + int error; + + if ((error = getvnode(p->p_fd, SCARG(uap, fd), &fp)) != 0) + return (error); + vp = (struct vnode *)fp->f_data; + vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, p); + if ((error = VOP_FSYNC(vp, fp->f_cred, MNT_WAIT, p)) == 0 && + bioops.io_fsync != NULL) + error = (*bioops.io_fsync)(vp); + + VOP_UNLOCK(vp, 0, p); + return (error); +} diff --git a/sys/compat/netbsd/netbsd_pos_io.c b/sys/compat/netbsd/netbsd_pos_io.c index 7281901d72a..9cb98f9bff0 100644 --- a/sys/compat/netbsd/netbsd_pos_io.c +++ b/sys/compat/netbsd/netbsd_pos_io.c @@ -1,9 +1,10 @@ -/* $OpenBSD: netbsd_pos_io.c,v 1.2 1999/09/17 12:37:54 kstailey Exp $ */ +/* $OpenBSD: netbsd_pos_io.c,v 1.3 1999/09/17 13:41:29 kstailey Exp $ */ /* $NetBSD: vfs_syscalls.c,v 1.71 1996/04/23 10:29:02 mycroft Exp $ */ /* - * Copyright (c) 1989, 1993 + * Copyright (c) 1996 Theo de Raadt + * Copyright (c) 1982, 1986, 1989, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. * All or some portions of this file are derived from material licensed @@ -40,6 +41,7 @@ * SUCH DAMAGE. * * @(#)vfs_syscalls.c 8.28 (Berkeley) 12/10/94 + * @(#)sys_generic.c 8.5 (Berkeley) 1/21/94 */ #include <sys/param.h> @@ -47,8 +49,9 @@ #include <sys/filedesc.h> #include <sys/vnode.h> #include <sys/proc.h> +#include <sys/signalvar.h> #include <sys/uio.h> -/*#include <sys/malloc.h>*/ +#include <sys/malloc.h> #ifdef KTRACE #include <sys/ktrace.h> #endif @@ -162,16 +165,86 @@ netbsd_sys_preadv(p, v, retval) void *v; register_t *retval; { -#if 0 struct netbsd_sys_preadv_args /* { syscallarg(int) fd; syscallarg(const struct iovec *) iovp; syscallarg(int) iovcnt; syscallarg(off_t) offset; } */ *uap = v; -#else - return (0); + register struct file *fp; + register struct filedesc *fdp = p->p_fd; + struct uio auio; + register struct iovec *iov; + struct iovec *needfree; + struct iovec aiov[UIO_SMALLIOV]; + long i, cnt, error = 0; + u_int iovlen; +#ifdef KTRACE + struct iovec *ktriov = NULL; +#endif + + if ((error = netbsd_set_pos(p, SCARG(uap, fd), SCARG(uap, offset)))) + return (error); + fp = fdp->fd_ofiles[SCARG(uap, fd)]; + if (SCARG(uap, iovcnt) <= 0) + return (EINVAL); + /* note: can't use iovlen until iovcnt is validated */ + iovlen = SCARG(uap, iovcnt) * sizeof (struct iovec); + if (SCARG(uap, iovcnt) > UIO_SMALLIOV) { + if (SCARG(uap, iovcnt) > IOV_MAX) + return (EINVAL); + MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); + needfree = iov; + } else { + iov = aiov; + needfree = NULL; + } + auio.uio_iov = iov; + auio.uio_iovcnt = SCARG(uap, iovcnt); + auio.uio_rw = UIO_READ; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_procp = p; + error = copyin((caddr_t)SCARG(uap, iovp), (caddr_t)iov, iovlen); + if (error) + goto done; + auio.uio_resid = 0; + for (i = 0; i < SCARG(uap, iovcnt); i++, iov++) { + /* Don't allow sum > SSIZE_MAX */ + if (iov->iov_len > SSIZE_MAX || + (auio.uio_resid += iov->iov_len) > SSIZE_MAX) { + error = EINVAL; + goto done; + } + } +#ifdef KTRACE + /* + * if tracing, save a copy of iovec + */ + if (KTRPOINT(p, KTR_GENIO)) { + MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); + bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); + } +#endif + cnt = auio.uio_resid; + error = (*fp->f_ops->fo_read)(fp, &auio, fp->f_cred); + if (error) + if (auio.uio_resid != cnt && (error == ERESTART || + error == EINTR || error == EWOULDBLOCK)) + error = 0; + cnt -= auio.uio_resid; +#ifdef KTRACE + if (ktriov != NULL) { + if (error == 0) + ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_READ, ktriov, + cnt, error); + FREE(ktriov, M_TEMP); + } #endif + *retval = cnt; +done: + if (needfree) + FREE(needfree, M_IOV); + return (error); } /* @@ -184,16 +257,61 @@ netbsd_sys_pwrite(p, v, retval) void *v; register_t *retval; { -#if 0 struct netbsd_sys_pwrite_args /* { syscallarg(int) fd; syscallarg(const void *) buf; syscallarg(size_t) nbyte; syscallarg(off_t) offset; } */ *uap = v; -#else - return (0); + register struct file *fp; + register struct filedesc *fdp = p->p_fd; + struct uio auio; + struct iovec aiov; + long cnt, error = 0; +#ifdef KTRACE + struct iovec ktriov; +#endif + + if ((error = netbsd_set_pos(p, SCARG(uap, fd), SCARG(uap, offset)))) + return (error); + fp = fdp->fd_ofiles[SCARG(uap, fd)]; + if ((fp->f_flag & FWRITE) == 0) + return (EBADF); + /* Don't allow nbyte to be larger than max return val */ + if (SCARG(uap, nbyte) > SSIZE_MAX) + return(EINVAL); + aiov.iov_base = (caddr_t)SCARG(uap, buf); + aiov.iov_len = SCARG(uap, nbyte); + auio.uio_iov = &aiov; + auio.uio_iovcnt = 1; + auio.uio_resid = SCARG(uap, nbyte); + auio.uio_rw = UIO_WRITE; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_procp = p; +#ifdef KTRACE + /* + * if tracing, save a copy of iovec + */ + if (KTRPOINT(p, KTR_GENIO)) + ktriov = aiov; +#endif + cnt = SCARG(uap, nbyte); + error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred); + if (error) { + if (auio.uio_resid != cnt && (error == ERESTART || + error == EINTR || error == EWOULDBLOCK)) + error = 0; + if (error == EPIPE) + psignal(p, SIGPIPE); + } + cnt -= auio.uio_resid; +#ifdef KTRACE + if (KTRPOINT(p, KTR_GENIO) && error == 0) + ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_WRITE, + &ktriov, cnt, error); #endif + *retval = cnt; + return (error); } /* @@ -206,14 +324,89 @@ netbsd_sys_pwritev(p, v, retval) void *v; register_t *retval; { -#if 0 struct netbsd_sys_pwritev_args /* { syscallarg(int) fd; syscallarg(const struct iovec *) iovp; syscallarg(int) iovcnt; syscallarg(off_t) offset; } */ *uap = v; -#else - return (0); + register struct file *fp; + register struct filedesc *fdp = p->p_fd; + struct uio auio; + register struct iovec *iov; + struct iovec *needfree; + struct iovec aiov[UIO_SMALLIOV]; + long i, cnt, error = 0; + u_int iovlen; +#ifdef KTRACE + struct iovec *ktriov = NULL; +#endif + + if ((error = netbsd_set_pos(p, SCARG(uap, fd), SCARG(uap, offset)))) + return (error); + fp = fdp->fd_ofiles[SCARG(uap, fd)]; + if ((fp->f_flag & FWRITE) == 0) + return (EBADF); + if (SCARG(uap, iovcnt) <= 0) + return (EINVAL); + /* note: can't use iovlen until iovcnt is validated */ + iovlen = SCARG(uap, iovcnt) * sizeof (struct iovec); + if (SCARG(uap, iovcnt) > UIO_SMALLIOV) { + if (SCARG(uap, iovcnt) > IOV_MAX) + return (EINVAL); + MALLOC(iov, struct iovec *, iovlen, M_IOV, M_WAITOK); + needfree = iov; + } else { + iov = aiov; + needfree = NULL; + } + auio.uio_iov = iov; + auio.uio_iovcnt = SCARG(uap, iovcnt); + auio.uio_rw = UIO_WRITE; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_procp = p; + error = copyin((caddr_t)SCARG(uap, iovp), (caddr_t)iov, iovlen); + if (error) + goto done; + auio.uio_resid = 0; + for (i = 0; i < SCARG(uap, iovcnt); i++, iov++) { + /* Don't allow sum > SSIZE_MAX */ + if (iov->iov_len > SSIZE_MAX || + (auio.uio_resid += iov->iov_len) > SSIZE_MAX) { + error = EINVAL; + goto done; + } + } +#ifdef KTRACE + /* + * if tracing, save a copy of iovec + */ + if (KTRPOINT(p, KTR_GENIO)) { + MALLOC(ktriov, struct iovec *, iovlen, M_TEMP, M_WAITOK); + bcopy((caddr_t)auio.uio_iov, (caddr_t)ktriov, iovlen); + } +#endif + cnt = auio.uio_resid; + error = (*fp->f_ops->fo_write)(fp, &auio, fp->f_cred); + if (error) { + if (auio.uio_resid != cnt && (error == ERESTART || + error == EINTR || error == EWOULDBLOCK)) + error = 0; + if (error == EPIPE) + psignal(p, SIGPIPE); + } + cnt -= auio.uio_resid; +#ifdef KTRACE + if (ktriov != NULL) { + if (error == 0) + ktrgenio(p->p_tracep, SCARG(uap, fd), UIO_WRITE, + ktriov, cnt, error); + FREE(ktriov, M_TEMP); + } #endif + *retval = cnt; +done: + if (needfree) + FREE(needfree, M_IOV); + return (error); } diff --git a/sys/compat/netbsd/syscalls.master b/sys/compat/netbsd/syscalls.master index 5f96d87747a..c1b5a251691 100644 --- a/sys/compat/netbsd/syscalls.master +++ b/sys/compat/netbsd/syscalls.master @@ -1,4 +1,4 @@ -; $OpenBSD: syscalls.master,v 1.6 1999/09/17 12:13:47 kstailey Exp $ +; $OpenBSD: syscalls.master,v 1.7 1999/09/17 13:41:29 kstailey Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 @@ -506,8 +506,7 @@ ; 240 NOARGS { int sys_nanosleep(const struct timespec *rqtp, \ struct timespec *rmtp); } -241 UNIMPL -;241 STD { int sys_fdatasync(int fd); } +241 STD { int netbsd_sys_fdatasync(int fd); } 242 UNIMPL 243 UNIMPL 244 UNIMPL |