Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 28 Feb 2017 19:55:16 +0000 (UTC)
From:      Dmitry Chagin <dchagin@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r314404 - head/sys/compat/linux
Message-ID:  <201702281955.v1SJtGeG011858@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dchagin
Date: Tue Feb 28 19:55:16 2017
New Revision: 314404
URL: https://svnweb.freebsd.org/changeset/base/314404

Log:
  Linux epoll return EEXIST on case when op is EPOLL_CTL_ADD, and the supplied
  file descriptor fd is already registered with this epoll instance.
  
  MFC after:	1 month

Modified:
  head/sys/compat/linux/linux_event.c

Modified: head/sys/compat/linux/linux_event.c
==============================================================================
--- head/sys/compat/linux/linux_event.c	Tue Feb 28 19:54:22 2017	(r314403)
+++ head/sys/compat/linux/linux_event.c	Tue Feb 28 19:55:16 2017	(r314404)
@@ -481,15 +481,34 @@ linux_epoll_ctl(struct thread *td, struc
 
 	ciargs.changelist = kev;
 
+	if (args->op != LINUX_EPOLL_CTL_DEL) {
+		kev_flags = EV_ADD | EV_ENABLE;
+		error = epoll_to_kevent(td, epfp, args->fd, &le,
+		    &kev_flags, kev, &nchanges);
+		if (error != 0)
+			goto leave0;
+	}
+
 	switch (args->op) {
 	case LINUX_EPOLL_CTL_MOD:
 		error = epoll_delete_all_events(td, epfp, args->fd);
 		if (error != 0)
 			goto leave0;
-		/* FALLTHROUGH */
+		break;
 
 	case LINUX_EPOLL_CTL_ADD:
-			kev_flags = EV_ADD | EV_ENABLE;
+		/*
+		 * kqueue_register() return ENOENT if event does not exists
+		 * and the EV_ADD flag is not set.
+		 */
+		kev[0].flags &= ~EV_ADD;
+		error = kqfd_register(args->epfd, &kev[0], td, 1);
+		if (error != ENOENT) {
+			error = EEXIST;
+			goto leave0;
+		}
+		error = 0;
+		kev[0].flags |= EV_ADD;
 		break;
 
 	case LINUX_EPOLL_CTL_DEL:
@@ -502,11 +521,6 @@ linux_epoll_ctl(struct thread *td, struc
 		goto leave0;
 	}
 
-	error = epoll_to_kevent(td, epfp, args->fd, &le, &kev_flags,
-	    kev, &nchanges);
-	if (error != 0)
-		goto leave0;
-
 	epoll_fd_install(td, args->fd, le.data);
 
 	error = kern_kevent_fp(td, epfp, nchanges, 0, &k_ops, NULL);



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201702281955.v1SJtGeG011858>