Re: preadv() / pwritev()
Now that 5.4-release has settled, who is willing to commit the preadv() patch at http://www.stack.nl/~marcolz/FreeBSD/ ? Btw: Why are the files generated by 'make syscalls.c' in /usr/src/sys/kern and 'make sysent' in /usr/src/sys/compat/freebsd32 in CVS and not just generated at build time ? Should I include those files in the patch as well ? Marc pgpxXFR8wqpWq.pgp Description: PGP signature
Re: preadv() / pwritev()
And a man page link fix to top it off... Marc --- src/lib/libc/sys/Makefile.inc Wed Apr 7 11:07:47 2004 +++ src/lib/libc/sys/Makefile.inc Wed Apr 27 11:02:02 2005 @@ -127,7 +127,7 @@ MLINKS+=modnext.2 modfnext.2 MLINKS+=mount.2 nmount.2 mount.2 unmount.2 MLINKS+=pathconf.2 fpathconf.2 -MLINKS+=read.2 pread.2 read.2 readv.2 +MLINKS+=read.2 pread.2 read.2 readv.2 preadv.2 MLINKS+=recv.2 recvfrom.2 recv.2 recvmsg.2 MLINKS+=send.2 sendmsg.2 send.2 sendto.2 MLINKS+=setpgid.2 setpgrp.2 @@ -141,7 +141,7 @@ MLINKS+=truncate.2 ftruncate.2 MLINKS+=utimes.2 futimes.2 utimes.2 lutimes.2 MLINKS+=wait.2 wait3.2 wait.2 wait4.2 wait.2 waitpid.2 -MLINKS+=write.2 pwrite.2 write.2 writev.2 +MLINKS+=write.2 pwrite.2 write.2 writev.2 pwritev.2 .if !defined(NO_P1003_1B) MLINKS+=sched_get_priority_max.2 sched_get_priority_min.2 \ sched_get_priority_max.2 sched_rr_get_interval.2 pgpPvqd2ELntG.pgp Description: PGP signature
Re: preadv() / pwritev()
On Tuesday 26 April 2005 09:31 am, Marc Olzheim wrote: > On Mon, Apr 25, 2005 at 06:50:41PM +0200, Marc Olzheim wrote: > > On Mon, Apr 25, 2005 at 05:23:14PM +0200, Marc Olzheim wrote: > > > On Mon, Apr 25, 2005 at 02:50:45PM +0100, Bruce M Simpson wrote: > > > > I don't do enough thread-based programming at the moment to make this > > > > worth my while, though, but I'm happy to look at a patch. > > > > > > Ok, something like this ? > > > I'm a bit puzzled by the coding style in the file, but I think I got > > > the spirit of it. ;-) > > > > More like this then... > > Ok, I cleaned up the patch, got the freebsd32-compat working and filed a > PR: http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/80362 Looks fine to me! -- John Baldwin <[EMAIL PROTECTED]> <>< http://www.FreeBSD.org/~jhb/ "Power Users Use the Power to Serve" = http://www.FreeBSD.org ___ freebsd-hackers@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-hackers To unsubscribe, send any mail to "[EMAIL PROTECTED]"
Re: preadv() / pwritev()
On Tue, Apr 26, 2005 at 03:31:15PM +0200, Marc Olzheim wrote: > Ok, I cleaned up the patch, got the freebsd32-compat working and filed a > PR: http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/80362 Thanks to some people commenting, I've fixed a typo and added the off_t typedef in sys/uio.h, so that a buildworld now survives as well. :-) The diffs between the current- and stable- patch are now purely line number differences. I've got it running on my company's servers and everything seems to work ok. We don't use the freebsd32 compat part though, so I hope I've done that ok. Marc --- /usr/src/lib/libc/sys/read.2Sat Nov 13 12:55:41 2004 +++ /usr/src/lib/libc/sys/read.2Tue Apr 26 14:01:23 2005 @@ -38,7 +38,8 @@ .Sh NAME .Nm read , .Nm readv , -.Nm pread +.Nm pread , +.Nm preadv .Nd read input .Sh LIBRARY .Lb libc @@ -49,9 +50,11 @@ .Ft ssize_t .Fn read "int d" "void *buf" "size_t nbytes" .Ft ssize_t +.Fn pread "int d" "void *buf" "size_t nbytes" "off_t offset" +.Ft ssize_t .Fn readv "int d" "const struct iovec *iov" "int iovcnt" .Ft ssize_t -.Fn pread "int d" "void *buf" "size_t nbytes" "off_t offset" +.Fn preadv "int d" "const struct iovec *iov" "int iovcnt" "off_t offset" .Sh DESCRIPTION The .Fn read @@ -73,12 +76,16 @@ array: iov[0], iov[1], ..., iov[iovcnt\|\-\|1]. The .Fn pread -system call -performs the same function, but reads from the specified position in +and +.Fn preadv +system calls +perform the same functions, but read from the specified position in the file without modifying the file pointer. .Pp For -.Fn readv , +.Fn readv +and +.Fn preadv , the .Fa iovec structure is defined as: @@ -119,8 +126,9 @@ Upon successful completion, .Fn read , .Fn readv , -and .Fn pread +and +.Fn preadv return the number of bytes actually read and placed in the buffer. The system guarantees to read the number of bytes requested if the descriptor references a normal file that has that many bytes left @@ -137,8 +145,9 @@ The .Fn read , .Fn readv , -and .Fn pread +and +.Fn preadv system calls will succeed unless: .Bl -tag -width Er @@ -184,6 +193,8 @@ .Pp In addition, .Fn readv +and +.Fn preadv may return one of the following errors: .Bl -tag -width Er .It Bq Er EINVAL @@ -212,7 +223,9 @@ .Pp The .Fn pread -system call may also return the following errors: +and +.Fn preadv +system calls may also return the following errors: .Bl -tag -width Er .It Bq Er EINVAL The @@ -244,6 +257,10 @@ system calls are expected to conform to .St -xpg4.2 . .Sh HISTORY +The +.Fn preadv +system call appeared in +.Fx 5.4 . The .Fn pread function appeared in --- /usr/src/lib/libc/sys/write.2 Sat Nov 13 12:55:41 2004 +++ /usr/src/lib/libc/sys/write.2 Tue Apr 26 13:59:59 2005 @@ -49,9 +49,11 @@ .Ft ssize_t .Fn write "int d" "const void *buf" "size_t nbytes" .Ft ssize_t +.Fn pwrite "int d" "const void *buf" "size_t nbytes" "off_t offset" +.Ft ssize_t .Fn writev "int d" "const struct iovec *iov" "int iovcnt" .Ft ssize_t -.Fn pwrite "int d" "const void *buf" "size_t nbytes" "off_t offset" +.Fn pwritev "int d" "const struct iovec *iov" "int iovcnt" "off_t offset" .Sh DESCRIPTION The .Fn write @@ -73,12 +75,16 @@ array: iov[0], iov[1], ..., iov[iovcnt\|-\|1]. The .Fn pwrite -system call -performs the same function, but writes to the specified position in +and +.Fn pwritev +system calls +perform the same functions, but write to the specified position in the file without modifying the file pointer. .Pp For -.Fn writev , +.Fn writev +and +.Fn pwritev, the .Fa iovec structure is defined as: @@ -143,8 +149,9 @@ The .Fn write , .Fn writev , -and .Fn pwrite +and +.Fn pwritev system calls will fail and the file pointer will remain unchanged if: .Bl -tag -width Er @@ -196,6 +203,8 @@ .Pp In addition, .Fn writev +and +.Fn pwritev may return one of the following errors: .Bl -tag -width Er .It Bq Er EDESTADDRREQ @@ -228,7 +237,9 @@ .Pp The .Fn pwrite -system call may also return the following errors: +and +.Fn pwritev +system calls may also return the following errors: .Bl -tag -width Er .It Bq Er EINVAL The @@ -255,6 +266,10 @@ system calls are expected to conform to .St -xpg4.2 . .Sh HISTORY +The +.Fn pwritev +system call appeared in +.Fx 5.4 . The .Fn pwrite function appeared in --- /usr/src/sys/sys/syscallsubr.h Tue Apr 26 13:35:50 2005 +++ /usr/src/sys/sys/syscallsubr.h Tue Apr 26 13:36:56 2005 @@ -91,8 +91,12 @@ int flags, int mode); intkern_pathconf(struct thread *td, char *path, enum uio_seg pathseg, int name); +intkern_preadv(struct thread *td, int fd, struct uio *auio, off_t offset, + int flags); intkern_ptrace(struct thread *td, int req, pid_t pid, void *addr, int data); +intkern_pwritev(struct thread *td, int fd, struct uio *auio, off_t offset, + int flags); intkern_readlink(struct thread *td, char *path, enum uio_seg pathseg,
Re: preadv() / pwritev()
On Mon, Apr 25, 2005 at 06:50:41PM +0200, Marc Olzheim wrote: > On Mon, Apr 25, 2005 at 05:23:14PM +0200, Marc Olzheim wrote: > > On Mon, Apr 25, 2005 at 02:50:45PM +0100, Bruce M Simpson wrote: > > > I don't do enough thread-based programming at the moment to make this > > > worth > > > my while, though, but I'm happy to look at a patch. > > > > Ok, something like this ? > > I'm a bit puzzled by the coding style in the file, but I think I got the > > spirit of it. ;-) > > More like this then... Ok, I cleaned up the patch, got the freebsd32-compat working and filed a PR: http://www.freebsd.org/cgi/query-pr.cgi?pr=kern/80362 Marc pgpe0Ak3jOprn.pgp Description: PGP signature
Re: preadv() / pwritev()
On Mon, Apr 25, 2005 at 08:29:49PM +0100, Bruce M Simpson wrote: > > More like this then... > > Yep, something like that! Thanks, though I may not have time to commit > this at the moment. :-( Then should I file a PR after someone tells me what kind of naming scheme they'd rather have than dopreadv() and dopwritev() :-P ? Or should I combine all of the 4 read functions together (as well as all of the 4 write functions) ? The current patch is against 6-CURRENT, but applies almost perfectly against 5-STABLE as well, and works for me. ;-) Marc pgpCBcJPHwAma.pgp Description: PGP signature
Re: preadv() / pwritev()
On Mon, Apr 25, 2005 at 06:50:41PM +0200, Marc Olzheim wrote: > More like this then... Yep, something like that! Thanks, though I may not have time to commit this at the moment. :-( BMS pgpzcrqJRUpsG.pgp Description: PGP signature
Re: preadv() / pwritev()
On Mon, Apr 25, 2005 at 05:23:14PM +0200, Marc Olzheim wrote: > On Mon, Apr 25, 2005 at 02:50:45PM +0100, Bruce M Simpson wrote: > > I don't do enough thread-based programming at the moment to make this worth > > my while, though, but I'm happy to look at a patch. > > Ok, something like this ? > I'm a bit puzzled by the coding style in the file, but I think I got the > spirit of it. ;-) More like this then... Marc --- sys/sys/uio.h.orig Mon Apr 25 18:23:58 2005 +++ sys/sys/uio.h Mon Apr 25 18:30:54 2005 @@ -101,6 +101,8 @@ __BEGIN_DECLS ssize_treadv(int, const struct iovec *, int); ssize_twritev(int, const struct iovec *, int); +ssize_tpreadv(int, const struct iovec *, int, off_t); +ssize_tpwritev(int, const struct iovec *, int, off_t); __END_DECLS #endif /* _KERNEL */ --- sys/compat/freebsd32/syscalls.master.orig Mon Apr 25 16:56:52 2005 +++ sys/compat/freebsd32/syscalls.masterMon Apr 25 18:45:38 2005 @@ -406,8 +406,13 @@ 286UNIMPL nosys 287UNIMPL nosys 288UNIMPL nosys -289UNIMPL nosys -290UNIMPL nosys +; 289 and 290 from NetBSD (OpenBSD: 267 and 268) +289STD { ssize_t freebsd32_preadv(int fd, u_int iovcnt,\ + struct uio * auio, off_t offset); } +; XXX note - bigendian is different +290STD { ssize_t freebsd32_pwritev(int fd, u_int iovcnt,\ + struct uio * auio, off_t offset); } +; XXX note - bigendian is different 291UNIMPL nosys 292UNIMPL nosys 293UNIMPL nosys --- sys/kern/syscalls.master.orig Mon Apr 25 16:56:40 2005 +++ sys/kern/syscalls.masterMon Apr 25 18:45:47 2005 @@ -411,8 +411,11 @@ 286UNIMPL nosys 287UNIMPL nosys 288UNIMPL nosys -289UNIMPL nosys -290UNIMPL nosys +; 289 and 290 from NetBSD (OpenBSD: 267 and 268) +289MSTD{ ssize_t preadv(int fd, struct iovec *iovp, u_int iovcnt,\ + off_t offset); } +290MSTD{ ssize_t pwritev(int fd, struct iovec *iovp, u_int iovcnt,\ + off_t offset); } 291UNIMPL nosys 292UNIMPL nosys 293UNIMPL nosys --- sys/kern/sys_generic.c.orig Mon Apr 25 16:12:58 2005 +++ sys/kern/sys_generic.c Mon Apr 25 18:32:03 2005 @@ -80,6 +80,8 @@ size_t, off_t, int); static int dofilewrite(struct thread *, struct file *, int, const void *, size_t, off_t, int); +static int dopreadv(struct thread *, int, struct uio *, off_t, int); +static int dopwritev(struct thread *, int, struct uio *, off_t, int); static voiddoselwakeup(struct selinfo *, int); /* @@ -233,9 +235,47 @@ return (error); } +/* + * Scatter positioned read system call. + */ +#ifndef _SYS_SYSPROTO_H_ +struct preadv_args { + int fd; + struct iovec *iovp; + u_int iovcnt; + off_t offset; +}; +#endif +/* + * MPSAFE + */ +int +preadv(struct thread *td, struct preadv_args *uap) +{ + struct uio *auio; + int error; + + error = copyinuio(uap->iovp, uap->iovcnt, &auio); + if (error) + return (error); + error = dopreadv(td, uap->fd, auio, uap->offset, FOF_OFFSET); + free(auio, M_IOV); + return (error); +} + int kern_readv(struct thread *td, int fd, struct uio *auio) { + return (dopreadv(td, fd, auio, (off_t)-1, 0)); +} + +static int +dopreadv(td, fd, auio, offset, flags) + struct thread *td; + struct uio *auio; + int fd, flags; + off_t offset; +{ struct file *fp; long cnt; int error; @@ -253,13 +293,14 @@ return(0); } auio->uio_rw = UIO_READ; + auio->uio_offset = offset; auio->uio_td = td; #ifdef KTRACE if (KTRPOINT(td, KTR_GENIO)) ktruio = cloneuio(auio); #endif cnt = auio->uio_resid; - if ((error = fo_read(fp, auio, td->td_ucred, 0, td))) { + if ((error = fo_read(fp, auio, td->td_ucred, flags, td))) { if (auio->uio_resid != cnt && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; @@ -430,9 +471,47 @@ return (error); } +/* + * Gather posiotioned write system call + */ +#ifndef _SYS_SYSPROTO_H_ +struct pwritev_args { + int fd; + struct iovec *iovp; + u_int iovcnt; + off_t offset; +}; +#endif +/* + * MPSAFE + */ +int +pwritev(struct thread *td, struct pwritev_args *uap) +{ + struct uio *auio; + int error; + + error = copyinuio(uap->iovp, uap->iovcnt, &auio); + if (error) + return (error); + error = dopwritev(td, uap->fd, auio, uap->offset, FOF_OFFSET); + free(auio, M_IOV); + return (error); +} + int kern_writev(struct thread *td, int fd, struct uio *auio) { + return (dopwritev(td, fd, auio, (off_t)-1 , 0)); +} + +static int +dopwritev(td, fd, auio, offset, flags) + struct thread *td;
Re: preadv() / pwritev()
On Mon, Apr 25, 2005 at 05:23:14PM +0200, Marc Olzheim wrote: > int > kern_readv(struct thread *td, int fd, struct uio *auio) > { > + return (preadv(td, fd, auio, (off_t)-1, 0)); > +} ->dopreadv() Hit the send button too quickly, I'll submit a new one after testing. Marc pgpoFklMqNhu2.pgp Description: PGP signature
Re: preadv() / pwritev()
On Mon, Apr 25, 2005 at 02:50:45PM +0100, Bruce M Simpson wrote: > I don't do enough thread-based programming at the moment to make this worth > my while, though, but I'm happy to look at a patch. Ok, something like this ? I'm a bit puzzled by the coding style in the file, but I think I got the spirit of it. ;-) Possibly more of dofileread() and dopreadv() and their write-cousins could be merged into each other, but this patch is better readable... Marc --- sys/kern/syscalls.masterMon Apr 25 16:56:40 2005 +++ sys/kern/syscalls.masterMon Apr 25 17:05:07 2005 @@ -646,6 +646,10 @@ 454MSTD{ int _umtx_op(struct umtx *umtx, int op, long id, void *uaddr,\ void *uaddr2); } 455MSTD{ int thr_new(struct thr_param *param, int param_size); } +456MSTD{ ssize_t preadv(struct thread *td, int fd, struct uio * auio,\ + u_int iovcnt, off_t offset, int flags); } +457MSTD{ ssize_t pwritev(struct thread *td, int fd, struct uio * auio,\ + u_int iovcnt, off_t offset, int flags); } ; Please copy any additions and changes to the following compatability tables: ; sys/compat/freebsd32/syscalls.master --- sys/compat/freebsd32/syscalls.masterMon Apr 25 16:56:52 2005 +++ sys/compat/freebsd32/syscalls.masterMon Apr 25 17:05:31 2005 @@ -620,3 +620,9 @@ 452UNIMPL setaudit_addr 453UNIMPL auditctl 454UNIMPL _umtx_op +456STD { ssize_t freebsd32_preadv(struct thread *td, int fd,\ + u_int iovcnt, struct uio * auio, off_t offset, int flags); } +; XXX note - bigendian is different +457STD { ssize_t freebsd32_pwritev(struct thread *td, int fd,\ + u_int iovcnt, struct uio * auio, off_t offset, int flags); } +; XXX note - bigendian is different --- sys/kern/sys_generic.c Mon Apr 25 16:12:58 2005 +++ sys/kern/sys_generic.c Mon Apr 25 17:19:49 2005 @@ -80,6 +80,8 @@ size_t, off_t, int); static int dofilewrite(struct thread *, struct file *, int, const void *, size_t, off_t, int); +static int dopreadv(struct thread *, int, struct uio *, off_t, int); +static int dopwritev(struct thread *, int, struct uio *, off_t, int); static voiddoselwakeup(struct selinfo *, int); /* @@ -233,9 +235,48 @@ return (error); } +/* + * Scatter positioned read system call. + */ +#ifndef _SYS_SYSPROTO_H_ +struct preadv_args { + struct thread *td; + int fd; + struct iovec *iovp; + u_int iovcnt; + off_t offset; +}; +#endif +/* + * MPSAFE + */ +int +preadv(struct thread *td, struct preadv_args *uap) +{ + struct uio *auio; + int error; + + error = copyinuio(uap->iovp, uap->iovcnt, &auio); + if (error) + return (error); + error = dopreadv(td, uap->fd, auio, uap->offset, FOF_OFFSET); + free(auio, M_IOV); + return (error); +} + int kern_readv(struct thread *td, int fd, struct uio *auio) { + return (preadv(td, fd, auio, (off_t)-1, 0)); +} + +static int +dopreadv(td, fd, auio, offset, flags) + struct thread *td; + struct uio *auio; + int fd, flags; + off_t offset; +{ struct file *fp; long cnt; int error; @@ -253,13 +294,14 @@ return(0); } auio->uio_rw = UIO_READ; + auio->uio_offset = offset; auio->uio_td = td; #ifdef KTRACE if (KTRPOINT(td, KTR_GENIO)) ktruio = cloneuio(auio); #endif cnt = auio->uio_resid; - if ((error = fo_read(fp, auio, td->td_ucred, 0, td))) { + if ((error = fo_read(fp, auio, td->td_ucred, flags, td))) { if (auio->uio_resid != cnt && (error == ERESTART || error == EINTR || error == EWOULDBLOCK)) error = 0; @@ -430,9 +472,48 @@ return (error); } +/* + * Gather posiotioned write system call + */ +#ifndef _SYS_SYSPROTO_H_ +struct pwritev_args { + struct thread *td; + int fd; + struct iovec *iovp; + u_int iovcnt; + off_t offset; +}; +#endif +/* + * MPSAFE + */ +int +pwritev(struct thread *td, struct pwritev_args *uap) +{ + struct uio *auio; + int error; + + error = copyinuio(uap->iovp, uap->iovcnt, &auio); + if (error) + return (error); + error = dopwritev(td, uap->fd, auio, uap->offset, FOF_OFFSET); + free(auio, M_IOV); + return (error); +} + int kern_writev(struct thread *td, int fd, struct uio *auio) { + return (dopwritev(td, fd, auio, (off_t)-1 , 0)); +} + +static int +dopwritev(td, fd, auio, offset, flags) + struct thread *td; + struct uio *auio; + int fd, flags; + off_t offset; +{ struct file *fp; long cnt; int error; @@ -445,6 +526,7 @@ return (EBADF); auio->uio_rw = UIO_WRITE; auio->uio_td = td; + aui
Re: preadv() / pwritev()
On Mon, Apr 25, 2005 at 12:10:08PM +0200, Marc Olzheim wrote: > Are there plans on implementing preadv() and pwritev() ? I kind of miss > the functionality and I saw NetBSD had it already... By the looks of pwrite() and writev() it could probably be implemented fairly easily; it would largely be a matter of rototiling pwrite() to accept an array of iovecs, as writev() currently does, as pwrite() already knows how to pass a single uio/iovec on the stack with the desired start offset. Looking at the man page for pwritev() it only accepts a start offset, rather than an individual offset for each scatter/gather element. I don't do enough thread-based programming at the moment to make this worth my while, though, but I'm happy to look at a patch. BMS pgpClgMnMoRjH.pgp Description: PGP signature
preadv() / pwritev()
Are there plans on implementing preadv() and pwritev() ? I kind of miss the functionality and I saw NetBSD had it already... Are there any issues with it that I'm not aware of ? Marc pgpMrCgB7FChi.pgp Description: PGP signature