Date: Fri, 3 Jun 2005 06:42:41 GMT From: Peter Wemm <peter@FreeBSD.org> To: Perforce Change Reviews <perforce@freebsd.org> Subject: PERFORCE change 77914 for review Message-ID: <200506030642.j536gfmn025037@repoman.freebsd.org>
next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=77914 Change 77914 by peter@peter_daintree on 2005/06/03 06:42:15 On second thoughts, lets see if I can get the kernel to boot at all first! Affected files ... .. //depot/projects/hammer/sys/compat/freebsd32/freebsd32_misc.c#26 edit .. //depot/projects/hammer/sys/kern/kern_event.c#34 edit .. //depot/projects/hammer/sys/sys/event.h#9 edit .. //depot/projects/hammer/sys/sys/syscallsubr.h#20 edit Differences ... ==== //depot/projects/hammer/sys/compat/freebsd32/freebsd32_misc.c#26 (text+ko) ==== @@ -52,7 +52,6 @@ #include <sys/resource.h> #include <sys/resourcevar.h> #include <sys/selinfo.h> -#include <sys/eventvar.h> /* Must come after sys/selinfo.h */ #include <sys/pipe.h> /* Must come after sys/selinfo.h */ #include <sys/signal.h> #include <sys/signalvar.h> @@ -553,75 +552,16 @@ }; CTASSERT(sizeof(struct kevent32) == 20); -static int freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count); -static int freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count); - -/* - * Copy 'count' items into the destination list pointed to by uap->eventlist. - */ -static int -freebsd32_kevent_copyout(void *arg, struct kevent *kevp, int count) -{ - struct freebsd32_kevent_args *uap; - struct kevent32 ks32[KQ_NEVENTS]; - int i, error = 0; - - KASSERT(count <= KQ_NEVENTS, "count > KQ_NEVENTS"); - uap = (struct freebsd32_kevent_args *)arg; - - for (i = 0; i < count; i++) { - CP(kevp[i], ks32[i], ident); - CP(kevp[i], ks32[i], filter); - CP(kevp[i], ks32[i], flags); - CP(kevp[i], ks32[i], fflags); - CP(kevp[i], ks32[i], data); - PTROUT_CP(kevp[i], ks32[i], udata); - } - error = copyout(ks32, uap->eventlist, count * sizeof *ks32); - if (error == 0) - uap->eventlist += count; - return (error); -} -/* - * Copy 'count' items from the list pointed to by uap->changelist. - */ -static int -freebsd32_kevent_copyin(void *arg, struct kevent *kevp, int count) -{ - struct freebsd32_kevent_args *uap; - struct kevent32 ks32[KQ_NEVENTS]; - int i, error = 0; - - KASSERT(count <= KQ_NEVENTS, "count > KQ_NEVENTS"); - uap = (struct freebsd32_kevent_args *)arg; - - error = copyin(uap->changelist, ks32, count * sizeof *ks32); - if (error) - goto done; - uap->changelist += count; - - for (i = 0; i < count; i++) { - CP(ks32[i], kevp[i], ident); - CP(ks32[i], kevp[i], filter); - CP(ks32[i], kevp[i], flags); - CP(ks32[i], kevp[i], fflags); - CP(ks32[i], kevp[i], data); - PTRIN_CP(ks32[i], kevp[i], udata); - } -done: - return (error); -} - int freebsd32_kevent(struct thread *td, struct freebsd32_kevent_args *uap) { struct timespec32 ts32; struct timespec ts, *tsp; - struct kevent_copyops k_ops = { uap, - freebsd32_kevent_copyout, - freebsd32_kevent_copyin}; - int error; + struct kevent *ks; + struct kevent32 ks32; + struct kevent *changes, *events; + int error, i; if (uap->timeout) { @@ -633,8 +573,51 @@ tsp = &ts; } else tsp = NULL; - error = kern_kevent(td, uap->fd, uap->nchanges, uap->nevents, - &k_ops, tsp); + if (uap->changelist && uap->nchanges > 0) { + changes = malloc(sizeof(struct kevent) * uap->nchanges, M_TEMP, + M_WAITOK); + for (i = 0; i < uap->nchanges; i++) { + error = copyin(&uap->changelist[i], &ks32, + sizeof(ks32)); + if (error) { + free(changes, M_TEMP); + return (error); + } + ks = &changes[i]; + CP(ks32, *ks, ident); + CP(ks32, *ks, filter); + CP(ks32, *ks, flags); + CP(ks32, *ks, fflags); + CP(ks32, *ks, data); + PTRIN_CP(ks32, *ks, udata); + } + } else + changes = NULL; + if (uap->eventlist && uap->nevents > 0) + events = malloc(sizeof(struct kevent) * uap->nevents, M_TEMP, + M_WAITOK); + else + events = NULL; + error = kern_kevent(td, uap->fd, changes, uap->nchanges, UIO_SYSSPACE, + events, uap->nevents, UIO_SYSSPACE, tsp); + free(changes, M_TEMP); + if (uap->eventlist && events && td->td_retval[0] > 0) { + for (i = 0; i < td->td_retval[0]; i++) { + ks = &events[i]; + CP(*ks, ks32, ident); + CP(*ks, ks32, filter); + CP(*ks, ks32, flags); + CP(*ks, ks32, fflags); + CP(*ks, ks32, data); + PTROUT_CP(*ks, ks32, udata); + error = copyout(&ks32, &uap->eventlist[i], + sizeof(ks32)); + if (error) + break; + } + } + if (events) + free(events, M_TEMP); return (error); } ==== //depot/projects/hammer/sys/kern/kern_event.c#34 (text+ko) ==== @@ -81,17 +81,17 @@ TASKQUEUE_DEFINE_THREAD(kqueue); -static int kevent_copyout(void *arg, struct kevent *kevp, int count); -static int kevent_copyin(void *arg, struct kevent *kevp, int count); +static int kevent_copyout(struct kevent **eventlist, enum uio_seg eventseg, + struct kevent *kevp, int count); static int kqueue_aquire(struct file *fp, struct kqueue **kqp); static void kqueue_release(struct kqueue *kq, int locked); static int kqueue_expand(struct kqueue *kq, struct filterops *fops, uintptr_t ident, int waitok); static void kqueue_task(void *arg, int pending); static int kqueue_scan(struct kqueue *kq, int maxevents, - struct kevent_copyops *k_ops, - const struct timespec *timeout, - struct kevent *keva, struct thread *td); + struct kevent *eventlist, enum uio_seg eventseg, + const struct timespec *timeout, struct kevent *keva, + struct thread *td); static void kqueue_wakeup(struct kqueue *kq); static struct filterops *kqueue_fo_find(int filt); static void kqueue_fo_release(int filt); @@ -536,9 +536,6 @@ kevent(struct thread *td, struct kevent_args *uap) { struct timespec ts, *tsp; - struct kevent_copyops k_ops = { uap, - kevent_copyout, - kevent_copyin}; int error; if (uap->timeout != NULL) { @@ -549,49 +546,36 @@ } else tsp = NULL; - return (kern_kevent(td, uap->fd, uap->nchanges, uap->nevents, - &k_ops, tsp)); + return (kern_kevent(td, uap->fd, uap->changelist, uap->nchanges, + UIO_USERSPACE, uap->eventlist, uap->nevents, UIO_USERSPACE, tsp)); } /* - * Copy 'count' items into the destination list pointed to by uap->eventlist. + * Copy 'count' items into the destination list pointd to by *eventlist. The + * eventlist and nevents values are updated to point after the copied out + * item(s) upon return. */ static int -kevent_copyout(void *arg, struct kevent *kevp, int count) +kevent_copyout(struct kevent **eventlist, enum uio_seg eventseg, + struct kevent *kevp, int count) { - struct kevent_args *uap; int error; - KASSERT(count <= KQ_NEVENTS, "count > KQ_NEVENTS"); - uap = (struct kevent_args *)arg; - - error = copyout(kevp, uap->eventlist, count * sizeof *kevp); - if (error == 0) - uap->eventlist += count; + if (eventseg == UIO_USERSPACE) + error = copyout(kevp, *eventlist, + sizeof(struct kevent) * count); + else { + bcopy(kevp, *eventlist, sizeof(struct kevent) * count); + error = 0; + } + *eventlist += count; return (error); } -/* - * Copy 'count' items from the list pointed to by uap->changelist. - */ -static int -kevent_copyin(void *arg, struct kevent *kevp, int count) -{ - struct kevent_args *uap; - int error; - - KASSERT(count <= KQ_NEVENTS, "count > KQ_NEVENTS"); - uap = (struct kevent_args *)arg; - - error = copyin(uap->changelist, kevp, count * sizeof *kevp); - if (error == 0) - uap->changelist += count; - return (error); -} - int -kern_kevent(struct thread *td, int fd, int nchanges, int nevents, - struct kevent_copyops *k_ops, const struct timespec *timeout) +kern_kevent(struct thread *td, int fd, struct kevent *changelist, int nchanges, + enum uio_seg changeseg, struct kevent *eventlist, int nevents, + enum uio_seg eventseg, const struct timespec *timeout) { struct kevent keva[KQ_NEVENTS]; struct kevent *kevp, *changes; @@ -607,11 +591,16 @@ nerrors = 0; while (nchanges > 0) { - n = nchanges > KQ_NEVENTS ? KQ_NEVENTS : nchanges; - error = k_ops->k_copyin(k_ops->arg, keva, n); - if (error) - goto done; - changes = keva; + if (changeseg == UIO_USERSPACE) { + n = nchanges > KQ_NEVENTS ? KQ_NEVENTS : nchanges; + error = copyin(changelist, keva, n * sizeof *keva); + if (error) + goto done; + changes = keva; + } else { + changes = changelist; + n = nchanges; + } for (i = 0; i < n; i++) { kevp = &changes[i]; kevp->flags &= ~EV_SYSFLAGS; @@ -620,8 +609,8 @@ if (nevents != 0) { kevp->flags = EV_ERROR; kevp->data = error; - (void) k_ops->k_copyout(k_ops->arg, - kevp, 1); + (void) kevent_copyout(&eventlist, + eventseg, kevp, 1); nevents--; nerrors++; } else { @@ -630,6 +619,7 @@ } } nchanges -= n; + changelist += n; } if (nerrors) { td->td_retval[0] = nerrors; @@ -637,7 +627,8 @@ goto done; } - error = kqueue_scan(kq, nevents, k_ops, timeout, keva, td); + error = kqueue_scan(kq, nevents, eventlist, eventseg, timeout, + keva, td); done: kqueue_release(kq, 0); done_norel: @@ -1096,8 +1087,9 @@ * We treat KN_MARKER knotes as if they are INFLUX. */ static int -kqueue_scan(struct kqueue *kq, int maxevents, struct kevent_copyops *k_ops, - const struct timespec *tsp, struct kevent *keva, struct thread *td) +kqueue_scan(struct kqueue *kq, int maxevents, struct kevent *eventlist, + enum uio_seg eventseg, const struct timespec *tsp, struct kevent *keva, + struct thread *td) { struct kevent *kevp; struct timeval atv, rtv, ttv; @@ -1250,7 +1242,8 @@ if (nkev == KQ_NEVENTS) { KQ_UNLOCK_FLUX(kq); - error = k_ops->k_copyout(k_ops->arg, keva, nkev); + error = kevent_copyout(&eventlist, eventseg, keva, + nkev); nkev = 0; kevp = keva; KQ_LOCK(kq); @@ -1267,7 +1260,7 @@ done_nl: KQ_NOTOWNED(kq); if (nkev != 0) - error = k_ops->k_copyout(k_ops->arg, keva, nkev); + error = kevent_copyout(&eventlist, eventseg, keva, nkev); td->td_retval[0] = maxevents - count; return (error); } ==== //depot/projects/hammer/sys/sys/event.h#9 (text+ko) ==== @@ -192,11 +192,6 @@ #define kn_data kn_kevent.data #define kn_fp kn_ptr.p_fp }; -struct kevent_copyops { - void *arg; - int (*k_copyout)(void *arg, struct kevent *kevp, int count); - int (*k_copyin)(void *arg, struct kevent *kevp, int count); -}; struct thread; struct proc; ==== //depot/projects/hammer/sys/sys/syscallsubr.h#20 (text+ko) ==== @@ -44,7 +44,6 @@ struct sockaddr; struct stat; struct kevent; -struct kevent_copyops; int kern___getcwd(struct thread *td, u_char *buf, enum uio_seg bufseg, u_int buflen); @@ -73,8 +72,9 @@ int kern_getrusage(struct thread *td, int who, struct rusage *rup); int kern_getsockopt(struct thread *td, int s, int level, int name, void *optval, enum uio_seg valseg, socklen_t *valsize); -int kern_kevent(struct thread *td, int fd, int nchanges, int nevents, - struct kevent_copyops *k_ops, const struct timespec *timeout); +int kern_kevent(struct thread *td, int fd, struct kevent *changelist, + int nchanges, enum uio_seg changeseg, struct kevent *eventlist, + int nevents, enum uio_seg eventseg, const struct timespec *timeout); int kern_lchown(struct thread *td, char *path, enum uio_seg pathseg, int uid, int gid); int kern_link(struct thread *td, char *path, char *link,
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200506030642.j536gfmn025037>
