From: Matthew Dillon Date: Wed, 26 Apr 2006 17:17:57 +0000 (+0000) Subject: Add the preadv() and pwritev() systems and regenerate. X-Git-Tag: v2.0.1~5035 X-Git-Url: https://gitweb.dragonflybsd.org/dragonfly.git/commitdiff_plain/7f83ed38fa0657d32c9fa4a25344c35edc778aee Add the preadv() and pwritev() systems and regenerate. Submitted-by: Chuck Tuffli Loosely-based-on: FreeBSD --- diff --git a/sys/kern/init_sysent.c b/sys/kern/init_sysent.c index 7676228b76..158fa1ac8a 100644 --- a/sys/kern/init_sysent.c +++ b/sys/kern/init_sysent.c @@ -2,8 +2,8 @@ * System call switch table. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/kern/init_sysent.c,v 1.34 2005/11/16 02:24:30 dillon Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.27 2005/08/27 20:23:05 joerg Exp + * $DragonFly: src/sys/kern/init_sysent.c,v 1.35 2006/04/26 17:17:56 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.31 2006/03/24 06:45:04 dillon Exp */ #include "opt_compat.h" @@ -323,8 +323,8 @@ struct sysent sysent[] = { { 0, (sy_call_t *)nosys }, /* 286 = nosys */ { 0, (sy_call_t *)nosys }, /* 287 = nosys */ { 0, (sy_call_t *)nosys }, /* 288 = nosys */ - { 0, (sy_call_t *)nosys }, /* 289 = nosys */ - { 0, (sy_call_t *)nosys }, /* 290 = nosys */ + { AS(preadv_args), (sy_call_t *)preadv }, /* 289 = preadv */ + { AS(pwritev_args), (sy_call_t *)pwritev }, /* 290 = pwritev */ { 0, (sy_call_t *)nosys }, /* 291 = nosys */ { 0, (sy_call_t *)nosys }, /* 292 = nosys */ { 0, (sy_call_t *)nosys }, /* 293 = nosys */ diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c index e3c877e0c0..224ea9f628 100644 --- a/sys/kern/sys_generic.c +++ b/sys/kern/sys_generic.c @@ -37,7 +37,7 @@ * * @(#)sys_generic.c 8.5 (Berkeley) 1/21/94 * $FreeBSD: src/sys/kern/sys_generic.c,v 1.55.2.10 2001/03/17 10:39:32 peter Exp $ - * $DragonFly: src/sys/kern/sys_generic.c,v 1.23 2005/11/14 18:50:05 dillon Exp $ + * $DragonFly: src/sys/kern/sys_generic.c,v 1.24 2006/04/26 17:17:56 dillon Exp $ */ #include "opt_ktrace.h" @@ -80,6 +80,9 @@ MALLOC_DEFINE(M_IOV, "iov", "large iov's"); static int pollscan (struct proc *, struct pollfd *, u_int, int *); static int selscan (struct proc *, fd_mask **, fd_mask **, int, int *); +static int dofileread(int, struct file *, struct uio *, int, int *); +static int dofilewrite(int, struct file *, struct uio *, int, int *); + struct file* holdfp(fdp, fd, flag) @@ -108,6 +111,8 @@ read(struct read_args *uap) struct iovec aiov; int error; + if (uap->nbyte > INT_MAX) + return (EINVAL); aiov.iov_base = uap->buf; aiov.iov_len = uap->nbyte; auio.uio_iov = &aiov; @@ -118,13 +123,13 @@ read(struct read_args *uap) auio.uio_segflg = UIO_USERSPACE; auio.uio_td = td; - error = kern_readv(uap->fd, &auio, 0, &uap->sysmsg_result); + error = kern_preadv(uap->fd, &auio, 0, &uap->sysmsg_result); return(error); } /* - * Pread system call + * Positioned (Pread) read system call */ int pread(struct pread_args *uap) @@ -134,6 +139,8 @@ pread(struct pread_args *uap) struct iovec aiov; int error; + if (uap->nbyte > INT_MAX) + return (EINVAL); aiov.iov_base = uap->buf; aiov.iov_len = uap->nbyte; auio.uio_iov = &aiov; @@ -144,11 +151,14 @@ pread(struct pread_args *uap) auio.uio_segflg = UIO_USERSPACE; auio.uio_td = td; - error = kern_readv(uap->fd, &auio, FOF_OFFSET, &uap->sysmsg_result); + error = kern_preadv(uap->fd, &auio, FOF_OFFSET, &uap->sysmsg_result); return(error); } +/* + * Scatter read system call. + */ int readv(struct readv_args *uap) { @@ -168,24 +178,49 @@ readv(struct readv_args *uap) auio.uio_segflg = UIO_USERSPACE; auio.uio_td = td; - error = kern_readv(uap->fd, &auio, 0, &uap->sysmsg_result); + error = kern_preadv(uap->fd, &auio, 0, &uap->sysmsg_result); iovec_free(&iov, aiov); return (error); } + +/* + * Scatter positioned read system call. + */ int -kern_readv(int fd, struct uio *auio, int flags, int *res) +preadv(struct preadv_args *uap) +{ + struct thread *td = curthread; + struct uio auio; + struct iovec aiov[UIO_SMALLIOV], *iov = NULL; + int error; + + error = iovec_copyin(uap->iovp, &iov, aiov, uap->iovcnt, + &auio.uio_resid); + if (error) + return (error); + auio.uio_iov = iov; + auio.uio_iovcnt = uap->iovcnt; + auio.uio_offset = uap->offset; + auio.uio_rw = UIO_READ; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_td = td; + + error = kern_preadv(uap->fd, &auio, FOF_OFFSET, &uap->sysmsg_result); + + iovec_free(&iov, aiov); + return(error); +} + +int +kern_preadv(int fd, struct uio *auio, int flags, int *res) { struct thread *td = curthread; struct proc *p = td->td_proc; struct file *fp; struct filedesc *fdp = p->p_fd; - int len, error; -#ifdef KTRACE - struct iovec *ktriov = NULL; - struct uio ktruio; -#endif + int error; KKASSERT(p); @@ -194,12 +229,31 @@ kern_readv(int fd, struct uio *auio, int flags, int *res) return (EBADF); if (flags & FOF_OFFSET && fp->f_type != DTYPE_VNODE) { error = ESPIPE; - goto done; - } - if (auio->uio_resid < 0) { + } else if (auio->uio_resid < 0) { error = EINVAL; - goto done; + } else { + error = dofileread(fd, fp, auio, flags, res); } + fdrop(fp, td); + return(error); +} + +/* + * Common code for readv and preadv that reads data in + * from a file using the passed in uio, offset, and flags. + */ +static int +dofileread(int fd, struct file *fp, struct uio *auio, int flags, int *res) +{ + struct thread *td = curthread; + struct proc *p = td->td_proc; + ssize_t len; + int error; +#ifdef KTRACE + struct iovec *ktriov = NULL; + struct uio ktruio; +#endif + #ifdef KTRACE /* * if tracing, save a copy of iovec @@ -231,9 +285,8 @@ kern_readv(int fd, struct uio *auio, int flags, int *res) #endif if (error == 0) *res = len - auio->uio_resid; -done: - fdrop(fp, td); - return (error); + + return(error); } /* @@ -257,7 +310,7 @@ write(struct write_args *uap) auio.uio_segflg = UIO_USERSPACE; auio.uio_td = td; - error = kern_writev(uap->fd, &auio, 0, &uap->sysmsg_result); + error = kern_pwritev(uap->fd, &auio, 0, &uap->sysmsg_result); return(error); } @@ -283,7 +336,7 @@ pwrite(struct pwrite_args *uap) auio.uio_segflg = UIO_USERSPACE; auio.uio_td = td; - error = kern_writev(uap->fd, &auio, FOF_OFFSET, &uap->sysmsg_result); + error = kern_pwritev(uap->fd, &auio, FOF_OFFSET, &uap->sysmsg_result); return(error); } @@ -307,41 +360,85 @@ writev(struct writev_args *uap) auio.uio_segflg = UIO_USERSPACE; auio.uio_td = td; - error = kern_writev(uap->fd, &auio, 0, &uap->sysmsg_result); + error = kern_pwritev(uap->fd, &auio, 0, &uap->sysmsg_result); iovec_free(&iov, aiov); return (error); } + /* - * Gather write system call + * Gather positioned write system call */ int -kern_writev(int fd, struct uio *auio, int flags, int *res) +pwritev(struct pwritev_args *uap) +{ + struct thread *td = curthread; + struct uio auio; + struct iovec aiov[UIO_SMALLIOV], *iov = NULL; + int error; + + error = iovec_copyin(uap->iovp, &iov, aiov, uap->iovcnt, + &auio.uio_resid); + if (error) + return (error); + auio.uio_iov = iov; + auio.uio_iovcnt = uap->iovcnt; + auio.uio_offset = uap->offset; + auio.uio_rw = UIO_WRITE; + auio.uio_segflg = UIO_USERSPACE; + auio.uio_td = td; + + error = kern_pwritev(uap->fd, &auio, FOF_OFFSET, &uap->sysmsg_result); + + iovec_free(&iov, aiov); + return(error); +} + +int +kern_pwritev(int fd, struct uio *auio, int flags, int *res) { struct thread *td = curthread; struct proc *p = td->td_proc; struct file *fp; struct filedesc *fdp = p->p_fd; - long len, error; -#ifdef KTRACE - struct iovec *ktriov = NULL; - struct uio ktruio; -#endif + int error; KKASSERT(p); fp = holdfp(fdp, fd, FWRITE); if (fp == NULL) return (EBADF); - if ((flags & FOF_OFFSET) && fp->f_type != DTYPE_VNODE) { + else if ((flags & FOF_OFFSET) && fp->f_type != DTYPE_VNODE) { error = ESPIPE; - goto done; + } else { + error = dofilewrite(fd, fp, auio, flags, res); } + + fdrop(fp, td); + return (error); +} + +/* + * Common code for writev and pwritev that writes data to + * a file using the passed in uio, offset, and flags. + */ +static int +dofilewrite(int fd, struct file *fp, struct uio *auio, int flags, int *res) +{ + struct thread *td = curthread; + struct proc *p = td->td_proc; + ssize_t len; + int error; +#ifdef KTRACE + struct iovec *ktriov = NULL; + struct uio ktruio; +#endif + if (auio->uio_resid < 0) { - error = EINVAL; - goto done; + return(EINVAL); } + #ifdef KTRACE /* * if tracing, save a copy of iovec and uio @@ -362,6 +459,7 @@ kern_writev(int fd, struct uio *auio, int flags, int *res) if (auio->uio_resid != len && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; + /* Socket layer is responsible for issuing SIGPIPE. */ if (error == EPIPE) psignal(p, SIGPIPE); } @@ -377,9 +475,8 @@ kern_writev(int fd, struct uio *auio, int flags, int *res) #endif if (error == 0) *res = len - auio->uio_resid; -done: - fdrop(fp, td); - return (error); + + return(error); } /* diff --git a/sys/kern/syscalls.c b/sys/kern/syscalls.c index 76f87803db..aa16e40777 100644 --- a/sys/kern/syscalls.c +++ b/sys/kern/syscalls.c @@ -2,8 +2,8 @@ * System call names. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/kern/syscalls.c,v 1.33 2005/11/16 02:24:30 dillon Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.27 2005/08/27 20:23:05 joerg Exp + * $DragonFly: src/sys/kern/syscalls.c,v 1.34 2006/04/26 17:17:56 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.31 2006/03/24 06:45:04 dillon Exp */ char *syscallnames[] = { @@ -298,8 +298,8 @@ char *syscallnames[] = { "#286", /* 286 = nosys */ "#287", /* 287 = nosys */ "#288", /* 288 = nosys */ - "#289", /* 289 = nosys */ - "#290", /* 290 = nosys */ + "preadv", /* 289 = preadv */ + "pwritev", /* 290 = pwritev */ "#291", /* 291 = nosys */ "#292", /* 292 = nosys */ "#293", /* 293 = nosys */ diff --git a/sys/kern/syscalls.master b/sys/kern/syscalls.master index d5502d0cb2..0108af9a50 100644 --- a/sys/kern/syscalls.master +++ b/sys/kern/syscalls.master @@ -1,4 +1,4 @@ - $DragonFly: src/sys/kern/syscalls.master,v 1.31 2006/03/24 06:45:04 dillon Exp $ + $DragonFly: src/sys/kern/syscalls.master,v 1.32 2006/04/26 17:17:56 dillon Exp $ ; @(#)syscalls.master 8.2 (Berkeley) 1/13/94 ; $FreeBSD: src/sys/kern/syscalls.master,v 1.72.2.10 2002/07/12 08:22:46 alfred Exp $ @@ -428,8 +428,9 @@ 286 UNIMPL NOHIDE nosys 287 UNIMPL NOHIDE nosys 288 UNIMPL NOHIDE nosys -289 UNIMPL NOHIDE nosys -290 UNIMPL NOHIDE nosys +; 289 and 290 from NetBSD (OpenBSD: 267 and 268) +289 STD BSD { ssize_t preadv(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); } +290 STD BSD { ssize_t pwritev(int fd, struct iovec *iovp, u_int iovcnt, off_t offset); } 291 UNIMPL NOHIDE nosys 292 UNIMPL NOHIDE nosys 293 UNIMPL NOHIDE nosys diff --git a/sys/sys/kern_syscall.h b/sys/sys/kern_syscall.h index e059be08d5..5ad863b815 100644 --- a/sys/sys/kern_syscall.h +++ b/sys/sys/kern_syscall.h @@ -25,7 +25,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $DragonFly: src/sys/sys/kern_syscall.h,v 1.28 2005/08/09 20:14:16 joerg Exp $ + * $DragonFly: src/sys/sys/kern_syscall.h,v 1.29 2006/04/26 17:17:57 dillon Exp $ */ #ifndef _SYS_KERN_SYSCALL_H_ @@ -91,8 +91,8 @@ int kern_kill(int sig, int id); /* * Prototypes for syscalls in kern/sys_generic.c */ -int kern_readv(int fd, struct uio *auio, int flags, int *res); -int kern_writev(int fd, struct uio *auio, int flags, int *res); +int kern_preadv(int fd, struct uio *auio, int flags, int *res); +int kern_pwritev(int fd, struct uio *auio, int flags, int *res); /* * Prototypes for syscalls in kern/kern_resource.c diff --git a/sys/sys/syscall-args b/sys/sys/syscall-args index f078081b87..4d9c3cb904 100644 --- a/sys/sys/syscall-args +++ b/sys/sys/syscall-args @@ -1,8 +1,8 @@ # System call argument table. # DO NOT EDIT-- this file is automatically generated. -# $DragonFly: src/sys/sys/Attic/syscall-args,v 1.19 2005/11/16 02:24:33 dillon Exp $ +# $DragonFly: src/sys/sys/Attic/syscall-args,v 1.20 2006/04/26 17:17:57 dillon Exp $ -# Created from DragonFly: src/sys/kern/syscalls.master,v 1.27 2005/08/27 20:23:05 joerg Exp +# Created from DragonFly: src/sys/kern/syscalls.master,v 1.31 2006/03/24 06:45:04 dillon Exp int syscall nosys nosys_args void exit sys_exit sys_exit_args int rval @@ -166,6 +166,8 @@ int lchmod lchmod lchmod_args char * path mode_t mode int netbsd_lchown lchown lchown_args char * path uid_t uid gid_t gid int lutimes lutimes lutimes_args char * path struct timeval * tptr int netbsd_msync msync msync_args void * addr size_t len int flags +int preadv preadv preadv_args int fd struct iovec * iovp u_int iovcnt off_t offset +int pwritev pwritev pwritev_args int fd struct iovec * iovp u_int iovcnt off_t offset int fhstatfs fhstatfs fhstatfs_args const struct fhandle * u_fhp struct statfs * buf int fhopen fhopen fhopen_args const struct fhandle * u_fhp int flags int modnext modnext modnext_args int modid diff --git a/sys/sys/syscall-hide.h b/sys/sys/syscall-hide.h index a196f7c120..2021caf7dd 100644 --- a/sys/sys/syscall-hide.h +++ b/sys/sys/syscall-hide.h @@ -2,8 +2,8 @@ * System call hiders. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/syscall-hide.h,v 1.35 2005/11/16 02:24:33 dillon Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.27 2005/08/27 20:23:05 joerg Exp + * $DragonFly: src/sys/sys/syscall-hide.h,v 1.36 2006/04/26 17:17:57 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.31 2006/03/24 06:45:04 dillon Exp */ #ifdef COMPAT_43 @@ -211,6 +211,8 @@ HIDE_BSD(lchown) HIDE_BSD(lutimes) HIDE_BSD(msync) HIDE_BSD({) +HIDE_BSD(preadv) +HIDE_BSD(pwritev) HIDE_BSD(fhstatfs) HIDE_BSD(fhopen) HIDE_POSIX(fhstat) diff --git a/sys/sys/syscall.h b/sys/sys/syscall.h index 3fed3af85e..78af2dacbb 100644 --- a/sys/sys/syscall.h +++ b/sys/sys/syscall.h @@ -2,8 +2,8 @@ * System call numbers. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/syscall.h,v 1.35 2005/11/16 02:24:33 dillon Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.27 2005/08/27 20:23:05 joerg Exp + * $DragonFly: src/sys/sys/syscall.h,v 1.36 2006/04/26 17:17:57 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.31 2006/03/24 06:45:04 dillon Exp */ #define SYS_syscall 0 @@ -221,6 +221,8 @@ /* 278 is obsolete { */ /* 279 is obsolete { */ /* 280 is obsolete { */ +#define SYS_preadv 289 +#define SYS_pwritev 290 #define SYS_fhstatfs 297 #define SYS_fhopen 298 /* 299 is old fhstat */ diff --git a/sys/sys/syscall.mk b/sys/sys/syscall.mk index b74666a732..4b3b17bbd4 100644 --- a/sys/sys/syscall.mk +++ b/sys/sys/syscall.mk @@ -1,7 +1,7 @@ # DragonFly system call names. # DO NOT EDIT-- this file is automatically generated. -# $DragonFly: src/sys/sys/syscall.mk,v 1.35 2005/11/16 02:24:33 dillon Exp $ -# created from DragonFly: src/sys/kern/syscalls.master,v 1.27 2005/08/27 20:23:05 joerg Exp +# $DragonFly: src/sys/sys/syscall.mk,v 1.36 2006/04/26 17:17:57 dillon Exp $ +# created from DragonFly: src/sys/kern/syscalls.master,v 1.31 2006/03/24 06:45:04 dillon Exp MIASM = \ syscall.o \ exit.o \ @@ -165,6 +165,8 @@ MIASM = \ netbsd_lchown.o \ lutimes.o \ netbsd_msync.o \ + preadv.o \ + pwritev.o \ fhstatfs.o \ fhopen.o \ modnext.o \ diff --git a/sys/sys/sysproto.h b/sys/sys/sysproto.h index f836028ae7..b37232431b 100644 --- a/sys/sys/sysproto.h +++ b/sys/sys/sysproto.h @@ -2,8 +2,8 @@ * System call prototypes. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/sysproto.h,v 1.35 2005/11/16 02:24:33 dillon Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.27 2005/08/27 20:23:05 joerg Exp + * $DragonFly: src/sys/sys/sysproto.h,v 1.36 2006/04/26 17:17:57 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.31 2006/03/24 06:45:04 dillon Exp */ #ifndef _SYS_SYSPROTO_H_ @@ -1382,6 +1382,26 @@ struct lutimes_args { char * path; char path_[PAD_(char *)]; struct timeval * tptr; char tptr_[PAD_(struct timeval *)]; }; +struct preadv_args { +#ifdef _KERNEL + struct sysmsg sysmsg; +#endif + union usrmsg usrmsg; + int fd; char fd_[PAD_(int)]; + struct iovec * iovp; char iovp_[PAD_(struct iovec *)]; + u_int iovcnt; char iovcnt_[PAD_(u_int)]; + off_t offset; char offset_[PAD_(off_t)]; +}; +struct pwritev_args { +#ifdef _KERNEL + struct sysmsg sysmsg; +#endif + union usrmsg usrmsg; + int fd; char fd_[PAD_(int)]; + struct iovec * iovp; char iovp_[PAD_(struct iovec *)]; + u_int iovcnt; char iovcnt_[PAD_(u_int)]; + off_t offset; char offset_[PAD_(off_t)]; +}; struct fhstatfs_args { #ifdef _KERNEL struct sysmsg sysmsg; @@ -2689,6 +2709,8 @@ int issetugid (struct issetugid_args *); int lchown (struct lchown_args *); int lchmod (struct lchmod_args *); int lutimes (struct lutimes_args *); +int preadv (struct preadv_args *); +int pwritev (struct pwritev_args *); int fhstatfs (struct fhstatfs_args *); int fhopen (struct fhopen_args *); int modnext (struct modnext_args *); diff --git a/sys/sys/sysunion.h b/sys/sys/sysunion.h index bd288e3e10..079ec5f176 100644 --- a/sys/sys/sysunion.h +++ b/sys/sys/sysunion.h @@ -2,8 +2,8 @@ * Union of syscall args for messaging. * * DO NOT EDIT-- this file is automatically generated. - * $DragonFly: src/sys/sys/sysunion.h,v 1.32 2005/11/16 02:24:33 dillon Exp $ - * created from DragonFly: src/sys/kern/syscalls.master,v 1.27 2005/08/27 20:23:05 joerg Exp + * $DragonFly: src/sys/sys/sysunion.h,v 1.33 2006/04/26 17:17:57 dillon Exp $ + * created from DragonFly: src/sys/kern/syscalls.master,v 1.31 2006/03/24 06:45:04 dillon Exp */ union sysunion { @@ -266,6 +266,8 @@ union sysunion { #endif struct lchmod_args lchmod; struct lutimes_args lutimes; + struct preadv_args preadv; + struct pwritev_args pwritev; struct fhstatfs_args fhstatfs; struct fhopen_args fhopen; #ifdef COMPAT_DF12 diff --git a/sys/sys/uio.h b/sys/sys/uio.h index c14b1d76d2..0faedfd202 100644 --- a/sys/sys/uio.h +++ b/sys/sys/uio.h @@ -32,7 +32,7 @@ * * @(#)uio.h 8.5 (Berkeley) 2/22/94 * $FreeBSD: src/sys/sys/uio.h,v 1.11.2.1 2001/09/28 16:58:35 dillon Exp $ - * $DragonFly: src/sys/sys/uio.h,v 1.9 2004/07/27 13:11:22 hmp Exp $ + * $DragonFly: src/sys/sys/uio.h,v 1.10 2006/04/26 17:17:57 dillon Exp $ */ #ifndef _SYS_UIO_H_ @@ -110,8 +110,10 @@ iovec_free(struct iovec **kiov, struct iovec *siov) #include __BEGIN_DECLS -ssize_t readv (int, const struct iovec *, int); -ssize_t writev (int, const struct iovec *, int); +ssize_t readv(int, const struct iovec *, int); +ssize_t writev(int, const struct iovec *, int); +ssize_t preadv(int, const struct iovec *, int, off_t); +ssize_t pwritev(int, const struct iovec *, int, off_t); __END_DECLS #endif /* _KERNEL */