Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 30 Mar 2017 20:14:43 +0000 (UTC)
From:      Dmitry Chagin <dchagin@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-stable@freebsd.org, svn-src-stable-11@freebsd.org
Subject:   svn commit: r316302 - stable/11/sys/compat/linux
Message-ID:  <201703302014.v2UKEhbs050399@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: dchagin
Date: Thu Mar 30 20:14:43 2017
New Revision: 316302
URL: https://svnweb.freebsd.org/changeset/base/316302

Log:
  MFC r314404:
  
  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.

Modified:
  stable/11/sys/compat/linux/linux_event.c
Directory Properties:
  stable/11/   (props changed)

Modified: stable/11/sys/compat/linux/linux_event.c
==============================================================================
--- stable/11/sys/compat/linux/linux_event.c	Thu Mar 30 20:13:47 2017	(r316301)
+++ stable/11/sys/compat/linux/linux_event.c	Thu Mar 30 20:14:43 2017	(r316302)
@@ -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?201703302014.v2UKEhbs050399>