PERFORCE change 77914 for review
Peter Wemm
peter at FreeBSD.org
Thu Jun 2 23:42:43 PDT 2005
http://perforce.freebsd.org/chv.cgi?CH=77914
Change 77914 by peter at 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,
More information about the p4-projects
mailing list