Page MenuHomeFreeBSD

D38497.id117055.diff
No OneTemporary

D38497.id117055.diff

diff --git a/sys/compat/linux/linux_event.c b/sys/compat/linux/linux_event.c
--- a/sys/compat/linux/linux_event.c
+++ b/sys/compat/linux/linux_event.c
@@ -633,24 +633,18 @@
int
linux_eventfd(struct thread *td, struct linux_eventfd_args *args)
{
- struct specialfd_eventfd ae;
-
- bzero(&ae, sizeof(ae));
- ae.initval = args->initval;
- return (kern_specialfd(td, SPECIALFD_EVENTFD, &ae));
+ return (eventfd_create_file(td, args->initval, 0));
}
#endif
int
linux_eventfd2(struct thread *td, struct linux_eventfd2_args *args)
{
- struct specialfd_eventfd ae;
- int flags;
+ int flags = 0;
if ((args->flags & ~(LINUX_O_CLOEXEC | LINUX_O_NONBLOCK |
LINUX_EFD_SEMAPHORE)) != 0)
return (EINVAL);
- flags = 0;
if ((args->flags & LINUX_O_CLOEXEC) != 0)
flags |= EFD_CLOEXEC;
if ((args->flags & LINUX_O_NONBLOCK) != 0)
@@ -658,10 +652,7 @@
if ((args->flags & LINUX_EFD_SEMAPHORE) != 0)
flags |= EFD_SEMAPHORE;
- bzero(&ae, sizeof(ae));
- ae.flags = flags;
- ae.initval = args->initval;
- return (kern_specialfd(td, SPECIALFD_EVENTFD, &ae));
+ return (eventfd_create_file(td, args->initval, flags));
}
int
diff --git a/sys/kern/sys_eventfd.c b/sys/kern/sys_eventfd.c
--- a/sys/kern/sys_eventfd.c
+++ b/sys/kern/sys_eventfd.c
@@ -106,15 +106,24 @@
};
int
-eventfd_create_file(struct thread *td, struct file *fp, uint32_t initval,
- int flags)
+eventfd_create_file(struct thread *td, uint32_t initval, int flags)
{
struct eventfd *efd;
- int fflags;
+ struct file *fp;
+ int error, fd, fflags = 0;
AUDIT_ARG_FFLAGS(flags);
AUDIT_ARG_VALUE(initval);
+ if ((flags & ~(EFD_CLOEXEC | EFD_NONBLOCK | EFD_SEMAPHORE)) != 0)
+ return (EINVAL);
+ if ((flags & EFD_CLOEXEC) != 0)
+ fflags |= O_CLOEXEC;
+
+ error = falloc(td, &fp, &fd, fflags);
+ if (error != 0)
+ return (error);
+
efd = malloc(sizeof(*efd), M_EVENTFD, M_WAITOK | M_ZERO);
efd->efd_flags = flags;
efd->efd_count = initval;
@@ -124,9 +133,12 @@
fflags = FREAD | FWRITE;
if ((flags & EFD_NONBLOCK) != 0)
fflags |= FNONBLOCK;
+
finit(fp, fflags, DTYPE_EVENTFD, efd, &eventfdops);
+ fdrop(fp, td);
- return (0);
+ td->td_retval[0] = fd;
+ return (error);
}
static int
diff --git a/sys/kern/sys_generic.c b/sys/kern/sys_generic.c
--- a/sys/kern/sys_generic.c
+++ b/sys/kern/sys_generic.c
@@ -936,64 +936,37 @@
}
int
-kern_specialfd(struct thread *td, int type, void *arg)
+user_eventfd(struct thread *td, const void *arg)
{
- struct file *fp;
- struct specialfd_eventfd *ae;
- int error, fd, fflags;
+ struct specialfd_eventfd efd;
+ int error;
- fflags = 0;
- error = falloc_noinstall(td, &fp);
+ error = copyin(arg, &efd, sizeof(efd));
if (error != 0)
return (error);
- switch (type) {
- case SPECIALFD_EVENTFD:
- ae = arg;
- if ((ae->flags & EFD_CLOEXEC) != 0)
- fflags |= O_CLOEXEC;
- error = eventfd_create_file(td, fp, ae->initval, ae->flags);
- break;
- default:
- error = EINVAL;
- break;
- }
-
- if (error == 0)
- error = finstall(td, fp, &fd, fflags, NULL);
- fdrop(fp, td);
- if (error == 0)
- td->td_retval[0] = fd;
- return (error);
+ return (eventfd_create_file(td, efd.initval, efd.flags));
}
int
sys___specialfd(struct thread *td, struct __specialfd_args *args)
{
- struct specialfd_eventfd ae;
- int error;
+ size_t arg_size;
+ int (*specialfd_func)(struct thread *, const void *);
switch (args->type) {
case SPECIALFD_EVENTFD:
- if (args->len != sizeof(struct specialfd_eventfd)) {
- error = EINVAL;
- break;
- }
- error = copyin(args->req, &ae, sizeof(ae));
- if (error != 0)
- break;
- if ((ae.flags & ~(EFD_CLOEXEC | EFD_NONBLOCK |
- EFD_SEMAPHORE)) != 0) {
- error = EINVAL;
- break;
- }
- error = kern_specialfd(td, args->type, &ae);
+ arg_size = sizeof(struct specialfd_eventfd);
+ specialfd_func = user_eventfd;
break;
default:
- error = EINVAL;
- break;
+ return (EINVAL);
}
- return (error);
+
+ if (args->len != arg_size)
+ return (EINVAL);
+
+ return (specialfd_func(td, args->req));
}
int
diff --git a/sys/sys/eventfd.h b/sys/sys/eventfd.h
--- a/sys/sys/eventfd.h
+++ b/sys/sys/eventfd.h
@@ -38,8 +38,7 @@
#ifdef _KERNEL
-int eventfd_create_file(struct thread *td, struct file *fp, uint32_t initval,
- int flags);
+int eventfd_create_file(struct thread *td, uint32_t initval, int flags);
#else
diff --git a/sys/sys/syscallsubr.h b/sys/sys/syscallsubr.h
--- a/sys/sys/syscallsubr.h
+++ b/sys/sys/syscallsubr.h
@@ -321,7 +321,7 @@
int kern_statat(struct thread *td, int flag, int fd, const char *path,
enum uio_seg pathseg, struct stat *sbp,
void (*hook)(struct vnode *vp, struct stat *sbp));
-int kern_specialfd(struct thread *td, int type, void *arg);
+int user_eventfd(struct thread *td, const void *arg);
int kern_statfs(struct thread *td, const char *path, enum uio_seg pathseg,
struct statfs *buf);
int kern_symlinkat(struct thread *td, const char *path1, int fd,

File Metadata

Mime Type
text/plain
Expires
Fri, Jan 23, 11:08 PM (11 h, 16 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27891112
Default Alt Text
D38497.id117055.diff (4 KB)

Event Timeline