#include <linux/wait.h>
#include <linux/eventpoll.h>
#include <linux/mount.h>
-#include <asm/bitops.h>
+#include <linux/bitops.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/io.h>
/* Get the "struct epitem" from an epoll queue wrapper */
#define EP_ITEM_FROM_EPQUEUE(p) (container_of(p, struct ep_pqueue, pt)->epi)
+/* Tells if the epoll_ctl(2) operation needs an event copy from userspace */
+#define EP_OP_HASH_EVENT(op) ((op) != EPOLL_CTL_DEL)
+
struct epoll_filefd {
struct file *file;
current, epfd, op, fd, event));
error = -EFAULT;
- if (copy_from_user(&epds, event, sizeof(struct epoll_event)))
+ if (EP_OP_HASH_EVENT(op) &&
+ copy_from_user(&epds, event, sizeof(struct epoll_event)))
goto eexit_1;
/* Get the "struct file *" for the eventpoll file */
dentry->d_op = &eventpollfs_dentry_operations;
d_add(dentry, inode);
file->f_vfsmnt = mntget(eventpoll_mnt);
- file->f_dentry = dget(dentry);
+ file->f_dentry = dentry;
file->f_mapping = inode->i_mapping;
file->f_pos = 0;
* write-holding "sem" we can be sure that no file cleanup code will hit
* us during this operation. So we can avoid the lock on "ep->lock".
*/
- while ((rbp = rb_first(&ep->rbr))) {
+ while ((rbp = rb_first(&ep->rbr)) != 0) {
epi = rb_entry(rbp, struct epitem, rbn);
ep_remove(ep, epi);
}