Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 26 Apr 2005 21:33:20 +0200
From:      Marc Olzheim <marcolz@stack.nl>
To:        freebsd-hackers@freebsd.org
Subject:   Re: preadv() / pwritev()
Message-ID:  <20050426193320.GA72028@stack.nl>
In-Reply-To: <20050426133115.GA52753@stack.nl>
References:  <20050425101008.GA57542@stack.nl> <20050425135044.GD769@empiric.icir.org> <20050425152314.GB58044@stack.nl> <20050425165041.GA71899@stack.nl> <20050426133115.GA52753@stack.nl>

next in thread | previous in thread | raw e-mail | index | archive | help

--E39vaYmALEf/7YXx
Content-Type: multipart/mixed; boundary="OXfL5xGRrasGEqWY"
Content-Disposition: inline


--OXfL5xGRrasGEqWY
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

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

--OXfL5xGRrasGEqWY
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="preadv.stable.patch"
Content-Transfer-Encoding: quoted-printable

--- /usr/src/lib/libc/sys/read.2	Sat Nov 13 12:55:41 2004
+++ /usr/src/lib/libc/sys/read.2	Tue 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);
 int	kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg,
 	    int name);
+int	kern_preadv(struct thread *td, int fd, struct uio *auio, off_t offset,
+	    int flags);
 int	kern_ptrace(struct thread *td, int req, pid_t pid, void *addr,
 	    int data);
+int	kern_pwritev(struct thread *td, int fd, struct uio *auio, off_t offset,
+	    int flags);
 int	kern_readlink(struct thread *td, char *path, enum uio_seg pathseg,
 	    char *buf, enum uio_seg bufseg, int count);
 int	kern_readv(struct thread *td, int fd, struct uio *auio);
--- /usr/src/sys/sys/uio.h	Tue Feb  1 00:26:57 2005
+++ /usr/src/sys/sys/uio.h	Tue Apr 26 21:16:37 2005
@@ -42,6 +42,11 @@
 #define	_SSIZE_T_DECLARED
 #endif
=20
+#ifndef _OFF_T_DECLARED
+typedef	__off_t	off_t;
+#define	_OFF_T_DECLARED
+#endif
+
 #if __BSD_VISIBLE
 enum	uio_rw { UIO_READ, UIO_WRITE };
=20
@@ -102,6 +107,8 @@
 __BEGIN_DECLS
 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
=20
 #endif /* _KERNEL */
--- /usr/src/sys/kern/syscalls.master	Tue Apr 26 11:28:55 2005
+++ /usr/src/sys/kern/syscalls.master	Tue Apr 26 11:31:56 2005
@@ -411,8 +411,11 @@
 286	UNIMPL	nosys
 287	UNIMPL	nosys
 288	UNIMPL	nosys
-289	UNIMPL	nosys
-290	UNIMPL	nosys
+; 289 and 290 from NetBSD (OpenBSD: 267 and 268)
+289	MSTD	{ ssize_t preadv(int fd, struct iovec *iovp, u_int iovcnt,\
+		    off_t offset); }
+290	MSTD	{ ssize_t pwritev(int fd, struct iovec *iovp, u_int iovcnt,\
+		    off_t offset); }
 291	UNIMPL	nosys
 292	UNIMPL	nosys
 293	UNIMPL	nosys
--- /usr/src/sys/kern/sys_generic.c	Tue Apr 26 11:28:55 2005
+++ /usr/src/sys/kern/sys_generic.c	Tue Apr 26 13:37:57 2005
@@ -232,9 +232,47 @@
 	return (error);
 }
=20
+/*
+ * 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 =3D copyinuio(uap->iovp, uap->iovcnt, &auio);
+	if (error)
+		return (error);
+	error =3D kern_preadv(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 (kern_preadv(td, fd, auio, (off_t)-1, 0));
+}
+
+int
+kern_preadv(td, fd, auio, offset, flags)
+	struct thread *td;
+	struct uio *auio;
+	int fd, flags;
+	off_t offset;
+{
 	struct file *fp;
 	long cnt;
 	int error;
@@ -252,13 +290,14 @@
 		return(0);
 	}
 	auio->uio_rw =3D UIO_READ;
+	auio->uio_offset =3D offset;
 	auio->uio_td =3D td;
 #ifdef KTRACE
 	if (KTRPOINT(td, KTR_GENIO))=20
 		ktruio =3D cloneuio(auio);
 #endif
 	cnt =3D auio->uio_resid;
-	if ((error =3D fo_read(fp, auio, td->td_ucred, 0, td))) {
+	if ((error =3D fo_read(fp, auio, td->td_ucred, flags, td))) {
 		if (auio->uio_resid !=3D cnt && (error =3D=3D ERESTART ||
 		    error =3D=3D EINTR || error =3D=3D EWOULDBLOCK))
 			error =3D 0;
@@ -428,9 +467,47 @@
 	return (error);
 }
=20
+/*
+ * Gather positioned 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 =3D copyinuio(uap->iovp, uap->iovcnt, &auio);
+	if (error)
+		return (error);
+	error =3D kern_pwritev(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 (kern_pwritev(td, fd, auio, (off_t)-1, 0));
+}
+
+int
+kern_pwritev(td, fd, auio, offset, flags)
+	struct thread *td;
+	struct uio *auio;
+	int fd, flags;
+	off_t offset;
+{
 	struct file *fp;
 	long cnt;
 	int error;
@@ -443,6 +520,7 @@
 		return (EBADF);
 	auio->uio_rw =3D UIO_WRITE;
 	auio->uio_td =3D td;
+	auio->uio_offset =3D offset;
 #ifdef KTRACE
 	if (KTRPOINT(td, KTR_GENIO))
 		ktruio =3D cloneuio(auio);
@@ -450,7 +528,7 @@
 	cnt =3D auio->uio_resid;
 	if (fp->f_type =3D=3D DTYPE_VNODE)
 		bwillwrite();
-	if ((error =3D fo_write(fp, auio, td->td_ucred, 0, td))) {
+	if ((error =3D fo_write(fp, auio, td->td_ucred, flags, td))) {
 		if (auio->uio_resid !=3D cnt && (error =3D=3D ERESTART ||
 		    error =3D=3D EINTR || error =3D=3D EWOULDBLOCK))
 			error =3D 0;
--- /usr/src/sys/compat/freebsd32/syscalls.master	Tue Apr 26 11:28:51 2005
+++ /usr/src/sys/compat/freebsd32/syscalls.master	Tue Apr 26 13:52:46 2005
@@ -406,8 +406,13 @@
 286	UNIMPL	nosys
 287	UNIMPL	nosys
 288	UNIMPL	nosys
-289	UNIMPL	nosys
-290	UNIMPL	nosys
+; 289 and 290 from NetBSD (OpenBSD: 267 and 268)
+289	STD { ssize_t freebsd32_preadv(int fd, struct iovec32 *iovp,\
+		    u_int iovcnt, off_t offset); }
+; XXX note - bigendian is different
+290	STD { ssize_t freebsd32_pwritev(int fd, struct iovec32 *iovp,\
+		    u_int iovcnt, off_t offset); }
+; XXX note - bigendian is different
 291	UNIMPL	nosys
 292	UNIMPL	nosys
 293	UNIMPL	nosys
--- /usr/src/sys/compat/freebsd32/freebsd32_misc.c	Tue Apr 26 13:38:38 2005
+++ /usr/src/sys/compat/freebsd32/freebsd32_misc.c	Tue Apr 26 13:45:17 2005
@@ -694,7 +694,7 @@
 	error =3D freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
 	if (error)
 		return (error);
-	error =3D kern_readv(td, uap->fd, auio);
+	error =3D kern_preadv(td, uap->fd, auio, (off_t)-1, 0);
 	free(auio, M_IOV);
 	return (error);
 }
@@ -708,7 +708,35 @@
 	error =3D freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
 	if (error)
 		return (error);
-	error =3D kern_writev(td, uap->fd, auio);
+	error =3D kern_pwritev(td, uap->fd, auio, (off_t)-1, 0);
+	free(auio, M_IOV);
+	return (error);
+}
+
+int
+freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
+{
+	struct uio *auio;
+	int error;
+
+	error =3D freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
+	if (error)
+		return (error);
+	error =3D kern_preadv(td, uap->fd, auio, uap->offset, FOF_OFFSET);
+	free(auio, M_IOV);
+	return (error);
+}
+
+int
+freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
+{
+	struct uio *auio;
+	int error;
+
+	error =3D freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
+	if (error)
+		return (error);
+	error =3D kern_pwritev(td, uap->fd, auio, uap->offset, FOF_OFFSET);
 	free(auio, M_IOV);
 	return (error);
 }

--OXfL5xGRrasGEqWY
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="preadv.current.patch"
Content-Transfer-Encoding: quoted-printable

--- /usr/src/lib/libc/sys/read.2	Tue Apr 26 12:15:30 2005
+++ /usr/src/lib/libc/sys/read.2	Tue Apr 26 14:03:07 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
@@ -189,6 +198,8 @@
 .Pp
 In addition,
 .Fn readv
+and
+.Fn preadv
 may return one of the following errors:
 .Bl -tag -width Er
 .It Bq Er EINVAL
@@ -217,7 +228,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
@@ -249,6 +262,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	Tue Apr 26 12:15:43 2005
+++ /usr/src/lib/libc/sys/write.2	Tue Apr 26 12:30:34 2005
@@ -50,9 +50,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
@@ -74,12 +76,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:
@@ -144,8 +150,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
@@ -202,6 +209,8 @@
 .Pp
 In addition,
 .Fn writev
+and
+.Fn pwritev
 may return one of the following errors:
 .Bl -tag -width Er
 .It Bq Er EDESTADDRREQ
@@ -234,7 +243,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
@@ -261,6 +272,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:22:49 2005
+++ /usr/src/sys/sys/syscallsubr.h	Tue Apr 26 13:22:27 2005
@@ -96,8 +96,12 @@
 	    int flags, int mode);
 int	kern_pathconf(struct thread *td, char *path, enum uio_seg pathseg,
 	    int name);
+int	kern_preadv(struct thread *td, int fd, struct uio *auio, off_t offset,
+	    int flags);
 int	kern_ptrace(struct thread *td, int req, pid_t pid, void *addr,
 	    int data);
+int	kern_pwritev(struct thread *td, int fd, struct uio *auio, off_t offset,
+	    int flags);
 int	kern_readlink(struct thread *td, char *path, enum uio_seg pathseg,
 	    char *buf, enum uio_seg bufseg, int count);
 int	kern_readv(struct thread *td, int fd, struct uio *auio);
--- /usr/src/sys/sys/uio.h	Fri Jan  7 03:29:24 2005
+++ /usr/src/sys/sys/uio.h	Tue Apr 26 21:19:52 2005
@@ -42,6 +42,11 @@
 #define	_SSIZE_T_DECLARED
 #endif
=20
+#ifndef _OFF_T_DECLARED
+typedef	__off_t	off_t;
+#define	_OFF_T_DECLARED
+#endif
+
 #if __BSD_VISIBLE
 enum	uio_rw { UIO_READ, UIO_WRITE };
=20
@@ -101,6 +106,8 @@
 __BEGIN_DECLS
 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
=20
 #endif /* _KERNEL */
--- /usr/src/sys/kern/syscalls.master	Sat Apr 23 04:36:07 2005
+++ /usr/src/sys/kern/syscalls.master	Tue Apr 26 12:14:46 2005
@@ -411,8 +411,11 @@
 286	UNIMPL	nosys
 287	UNIMPL	nosys
 288	UNIMPL	nosys
-289	UNIMPL	nosys
-290	UNIMPL	nosys
+; 289 and 290 from NetBSD (OpenBSD: 267 and 268)
+289	MSTD	{ ssize_t preadv(int fd, struct iovec *iovp, u_int iovcnt,\
+		    off_t offset); }
+290	MSTD	{ ssize_t pwritev(int fd, struct iovec *iovp, u_int iovcnt,\
+		    off_t offset); }
 291	UNIMPL	nosys
 292	UNIMPL	nosys
 293	UNIMPL	nosys
--- /usr/src/sys/kern/sys_generic.c	Fri Apr  1 00:51:18 2005
+++ /usr/src/sys/kern/sys_generic.c	Tue Apr 26 13:21:15 2005
@@ -233,9 +233,47 @@
 	return (error);
 }
=20
+/*
+ * 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 =3D copyinuio(uap->iovp, uap->iovcnt, &auio);
+	if (error)
+		return (error);
+	error =3D kern_preadv(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 (kern_preadv(td, fd, auio, (off_t)-1, 0));
+}
+
+int
+kern_preadv(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 +291,14 @@
 		return(0);
 	}
 	auio->uio_rw =3D UIO_READ;
+	auio->uio_offset =3D offset;
 	auio->uio_td =3D td;
 #ifdef KTRACE
 	if (KTRPOINT(td, KTR_GENIO))=20
 		ktruio =3D cloneuio(auio);
 #endif
 	cnt =3D auio->uio_resid;
-	if ((error =3D fo_read(fp, auio, td->td_ucred, 0, td))) {
+	if ((error =3D fo_read(fp, auio, td->td_ucred, flags, td))) {
 		if (auio->uio_resid !=3D cnt && (error =3D=3D ERESTART ||
 		    error =3D=3D EINTR || error =3D=3D EWOULDBLOCK))
 			error =3D 0;
@@ -430,9 +469,47 @@
 	return (error);
 }
=20
+/*
+ * Gather positioned 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 =3D copyinuio(uap->iovp, uap->iovcnt, &auio);
+	if (error)
+		return (error);
+	error =3D kern_pwritev(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 (kern_pwritev(td, fd, auio, (off_t)-1, 0));
+}
+
+int
+kern_pwritev(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 +522,7 @@
 		return (EBADF);
 	auio->uio_rw =3D UIO_WRITE;
 	auio->uio_td =3D td;
+	auio->uio_offset =3D offset;
 #ifdef KTRACE
 	if (KTRPOINT(td, KTR_GENIO))
 		ktruio =3D cloneuio(auio);
@@ -452,7 +530,7 @@
 	cnt =3D auio->uio_resid;
 	if (fp->f_type =3D=3D DTYPE_VNODE)
 		bwillwrite();
-	if ((error =3D fo_write(fp, auio, td->td_ucred, 0, td))) {
+	if ((error =3D fo_write(fp, auio, td->td_ucred, flags, td))) {
 		if (auio->uio_resid !=3D cnt && (error =3D=3D ERESTART ||
 		    error =3D=3D EINTR || error =3D=3D EWOULDBLOCK))
 			error =3D 0;
--- /usr/src/sys/compat/freebsd32/syscalls.master	Tue Mar  1 07:32:53 2005
+++ /usr/src/sys/compat/freebsd32/syscalls.master	Tue Apr 26 13:52:24 2005
@@ -406,8 +406,13 @@
 286	UNIMPL	nosys
 287	UNIMPL	nosys
 288	UNIMPL	nosys
-289	UNIMPL	nosys
-290	UNIMPL	nosys
+; 289 and 290 from NetBSD (OpenBSD: 267 and 268)
+289	STD { ssize_t freebsd32_preadv(int fd, struct iovec32 *iovp,\
+		    u_int iovcnt, off_t offset); }
+; XXX note - bigendian is different
+290	STD { ssize_t freebsd32_pwritev(int fd, struct iovec32 *iovp,\
+		    u_int iovcnt, off_t offset); }
+; XXX note - bigendian is different
 291	UNIMPL	nosys
 292	UNIMPL	nosys
 293	UNIMPL	nosys
--- /usr/src/sys/compat/freebsd32/freebsd32_misc.c	Tue Apr 26 13:14:09 2005
+++ /usr/src/sys/compat/freebsd32/freebsd32_misc.c	Tue Apr 26 13:32:54 2005
@@ -733,7 +733,7 @@
 	error =3D freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
 	if (error)
 		return (error);
-	error =3D kern_readv(td, uap->fd, auio);
+	error =3D kern_preadv(td, uap->fd, auio, (off_t)-1, 0);
 	free(auio, M_IOV);
 	return (error);
 }
@@ -747,7 +747,35 @@
 	error =3D freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
 	if (error)
 		return (error);
-	error =3D kern_writev(td, uap->fd, auio);
+	error =3D kern_pwritev(td, uap->fd, auio, (off_t)-1, 0);
+	free(auio, M_IOV);
+	return (error);
+}
+
+int
+freebsd32_preadv(struct thread *td, struct freebsd32_preadv_args *uap)
+{
+	struct uio *auio;
+	int error;
+
+	error =3D freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
+	if (error)
+		return (error);
+	error =3D kern_preadv(td, uap->fd, auio, uap->offset, FOF_OFFSET);
+	free(auio, M_IOV);
+	return (error);
+}
+
+int
+freebsd32_pwritev(struct thread *td, struct freebsd32_pwritev_args *uap)
+{
+	struct uio *auio;
+	int error;
+
+	error =3D freebsd32_copyinuio(uap->iovp, uap->iovcnt, &auio);
+	if (error)
+		return (error);
+	error =3D kern_pwritev(td, uap->fd, auio, uap->offset, FOF_OFFSET);
 	free(auio, M_IOV);
 	return (error);
 }

--OXfL5xGRrasGEqWY--

--E39vaYmALEf/7YXx
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.1 (FreeBSD)

iD8DBQFCbpeAezjnobFOgrERAoO6AJ9mgp/pH3KtwWYtqL6bAfwmOkT1MQCfTW7/
xuOCYUgzHGl/T4F6AMYtn/c=
=kuqO
-----END PGP SIGNATURE-----

--E39vaYmALEf/7YXx--



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050426193320.GA72028>