forked from mirrors/linux
		
	eventpoll: abstract out epoll_ctl() handler
No functional changes in this patch. Signed-off-by: Jens Axboe <axboe@kernel.dk>
This commit is contained in:
		
							parent
							
								
									f86cd20c94
								
							
						
					
					
						commit
						58e41a44c4
					
				
					 1 changed files with 25 additions and 20 deletions
				
			
		| 
						 | 
					@ -2074,27 +2074,15 @@ SYSCALL_DEFINE1(epoll_create, int, size)
 | 
				
			||||||
	return do_epoll_create(0);
 | 
						return do_epoll_create(0);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					static int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *epds)
 | 
				
			||||||
 * The following function implements the controller interface for
 | 
					 | 
				
			||||||
 * the eventpoll file that enables the insertion/removal/change of
 | 
					 | 
				
			||||||
 * file descriptors inside the interest set.
 | 
					 | 
				
			||||||
 */
 | 
					 | 
				
			||||||
SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
 | 
					 | 
				
			||||||
		struct epoll_event __user *, event)
 | 
					 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	int error;
 | 
						int error;
 | 
				
			||||||
	int full_check = 0;
 | 
						int full_check = 0;
 | 
				
			||||||
	struct fd f, tf;
 | 
						struct fd f, tf;
 | 
				
			||||||
	struct eventpoll *ep;
 | 
						struct eventpoll *ep;
 | 
				
			||||||
	struct epitem *epi;
 | 
						struct epitem *epi;
 | 
				
			||||||
	struct epoll_event epds;
 | 
					 | 
				
			||||||
	struct eventpoll *tep = NULL;
 | 
						struct eventpoll *tep = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	error = -EFAULT;
 | 
					 | 
				
			||||||
	if (ep_op_has_event(op) &&
 | 
					 | 
				
			||||||
	    copy_from_user(&epds, event, sizeof(struct epoll_event)))
 | 
					 | 
				
			||||||
		goto error_return;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	error = -EBADF;
 | 
						error = -EBADF;
 | 
				
			||||||
	f = fdget(epfd);
 | 
						f = fdget(epfd);
 | 
				
			||||||
	if (!f.file)
 | 
						if (!f.file)
 | 
				
			||||||
| 
						 | 
					@ -2112,7 +2100,7 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/* Check if EPOLLWAKEUP is allowed */
 | 
						/* Check if EPOLLWAKEUP is allowed */
 | 
				
			||||||
	if (ep_op_has_event(op))
 | 
						if (ep_op_has_event(op))
 | 
				
			||||||
		ep_take_care_of_epollwakeup(&epds);
 | 
							ep_take_care_of_epollwakeup(epds);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/*
 | 
						/*
 | 
				
			||||||
	 * We have to check that the file structure underneath the file descriptor
 | 
						 * We have to check that the file structure underneath the file descriptor
 | 
				
			||||||
| 
						 | 
					@ -2128,11 +2116,11 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
 | 
				
			||||||
	 * so EPOLLEXCLUSIVE is not allowed for a EPOLL_CTL_MOD operation.
 | 
						 * so EPOLLEXCLUSIVE is not allowed for a EPOLL_CTL_MOD operation.
 | 
				
			||||||
	 * Also, we do not currently supported nested exclusive wakeups.
 | 
						 * Also, we do not currently supported nested exclusive wakeups.
 | 
				
			||||||
	 */
 | 
						 */
 | 
				
			||||||
	if (ep_op_has_event(op) && (epds.events & EPOLLEXCLUSIVE)) {
 | 
						if (ep_op_has_event(op) && (epds->events & EPOLLEXCLUSIVE)) {
 | 
				
			||||||
		if (op == EPOLL_CTL_MOD)
 | 
							if (op == EPOLL_CTL_MOD)
 | 
				
			||||||
			goto error_tgt_fput;
 | 
								goto error_tgt_fput;
 | 
				
			||||||
		if (op == EPOLL_CTL_ADD && (is_file_epoll(tf.file) ||
 | 
							if (op == EPOLL_CTL_ADD && (is_file_epoll(tf.file) ||
 | 
				
			||||||
				(epds.events & ~EPOLLEXCLUSIVE_OK_BITS)))
 | 
									(epds->events & ~EPOLLEXCLUSIVE_OK_BITS)))
 | 
				
			||||||
			goto error_tgt_fput;
 | 
								goto error_tgt_fput;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2192,8 +2180,8 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
 | 
				
			||||||
	switch (op) {
 | 
						switch (op) {
 | 
				
			||||||
	case EPOLL_CTL_ADD:
 | 
						case EPOLL_CTL_ADD:
 | 
				
			||||||
		if (!epi) {
 | 
							if (!epi) {
 | 
				
			||||||
			epds.events |= EPOLLERR | EPOLLHUP;
 | 
								epds->events |= EPOLLERR | EPOLLHUP;
 | 
				
			||||||
			error = ep_insert(ep, &epds, tf.file, fd, full_check);
 | 
								error = ep_insert(ep, epds, tf.file, fd, full_check);
 | 
				
			||||||
		} else
 | 
							} else
 | 
				
			||||||
			error = -EEXIST;
 | 
								error = -EEXIST;
 | 
				
			||||||
		if (full_check)
 | 
							if (full_check)
 | 
				
			||||||
| 
						 | 
					@ -2208,8 +2196,8 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
 | 
				
			||||||
	case EPOLL_CTL_MOD:
 | 
						case EPOLL_CTL_MOD:
 | 
				
			||||||
		if (epi) {
 | 
							if (epi) {
 | 
				
			||||||
			if (!(epi->event.events & EPOLLEXCLUSIVE)) {
 | 
								if (!(epi->event.events & EPOLLEXCLUSIVE)) {
 | 
				
			||||||
				epds.events |= EPOLLERR | EPOLLHUP;
 | 
									epds->events |= EPOLLERR | EPOLLHUP;
 | 
				
			||||||
				error = ep_modify(ep, epi, &epds);
 | 
									error = ep_modify(ep, epi, epds);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		} else
 | 
							} else
 | 
				
			||||||
			error = -ENOENT;
 | 
								error = -ENOENT;
 | 
				
			||||||
| 
						 | 
					@ -2231,6 +2219,23 @@ SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
 | 
				
			||||||
	return error;
 | 
						return error;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					 * The following function implements the controller interface for
 | 
				
			||||||
 | 
					 * the eventpoll file that enables the insertion/removal/change of
 | 
				
			||||||
 | 
					 * file descriptors inside the interest set.
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					SYSCALL_DEFINE4(epoll_ctl, int, epfd, int, op, int, fd,
 | 
				
			||||||
 | 
							struct epoll_event __user *, event)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct epoll_event epds;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (ep_op_has_event(op) &&
 | 
				
			||||||
 | 
						    copy_from_user(&epds, event, sizeof(struct epoll_event)))
 | 
				
			||||||
 | 
							return -EFAULT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return do_epoll_ctl(epfd, op, fd, &epds);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Implement the event wait interface for the eventpoll file. It is the kernel
 | 
					 * Implement the event wait interface for the eventpoll file. It is the kernel
 | 
				
			||||||
 * part of the user space epoll_wait(2).
 | 
					 * part of the user space epoll_wait(2).
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue