preadv() / pwritev()
Marc Olzheim
marcolz at stack.nl
Mon Apr 25 08:23:17 PDT 2005
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
-------------- next part --------------
--- sys/kern/syscalls.master Mon Apr 25 16:56:40 2005
+++ sys/kern/syscalls.master Mon Apr 25 17:05:07 2005
@@ -646,6 +646,10 @@
454 MSTD { int _umtx_op(struct umtx *umtx, int op, long id, void *uaddr,\
void *uaddr2); }
455 MSTD { int thr_new(struct thr_param *param, int param_size); }
+456 MSTD { ssize_t preadv(struct thread *td, int fd, struct uio * auio,\
+ u_int iovcnt, off_t offset, int flags); }
+457 MSTD { 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.master Mon Apr 25 16:56:52 2005
+++ sys/compat/freebsd32/syscalls.master Mon Apr 25 17:05:31 2005
@@ -620,3 +620,9 @@
452 UNIMPL setaudit_addr
453 UNIMPL auditctl
454 UNIMPL _umtx_op
+456 STD { 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
+457 STD { 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 void doselwakeup(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;
+ auio->uio_offset = offset;
#ifdef KTRACE
if (KTRPOINT(td, KTR_GENIO))
ktruio = cloneuio(auio);
@@ -452,7 +534,7 @@
cnt = auio->uio_resid;
if (fp->f_type == DTYPE_VNODE)
bwillwrite();
- if ((error = fo_write(fp, auio, td->td_ucred, 0, td))) {
+ if ((error = fo_write(fp, auio, td->td_ucred, flags, td))) {
if (auio->uio_resid != cnt && (error == ERESTART ||
error == EINTR || error == EWOULDBLOCK))
error = 0;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-hackers/attachments/20050425/f39c0e31/attachment.bin
More information about the freebsd-hackers
mailing list