Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 15 Jul 2020 10:24:40 +0000 (UTC)
From:      Mateusz Guzik <mjg@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org
Subject:   svn commit: r363215 - head/sys/kern
Message-ID:  <202007151024.06FAOePk007944@repo.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: mjg
Date: Wed Jul 15 10:24:39 2020
New Revision: 363215
URL: https://svnweb.freebsd.org/changeset/base/363215

Log:
  poll: factor fd lookup out of scan and rescan

Modified:
  head/sys/kern/sys_generic.c

Modified: head/sys/kern/sys_generic.c
==============================================================================
--- head/sys/kern/sys_generic.c	Wed Jul 15 10:24:04 2020	(r363214)
+++ head/sys/kern/sys_generic.c	Wed Jul 15 10:24:39 2020	(r363215)
@@ -1476,7 +1476,50 @@ sys_ppoll(struct thread *td, struct ppoll_args *uap)
 	return (kern_poll(td, uap->fds, uap->nfds, tsp, ssp));
 }
 
+#ifdef CAPABILITIES
 static int
+poll_fget(struct filedesc *fdp, int fd, struct file **fpp)
+{
+	const struct filedescent *fde;
+	const struct fdescenttbl *fdt;
+	const cap_rights_t *haverights;
+	struct file *fp;
+	int error;
+
+	if (__predict_false(fd >= fdp->fd_nfiles))
+		return (EBADF);
+
+	fdt = fdp->fd_files;
+	fde = &fdt->fdt_ofiles[fd];
+	fp = fde->fde_file;
+	if (__predict_false(fp == NULL))
+		return (EBADF);
+	haverights = cap_rights_fde_inline(fde);
+	error = cap_check_inline(haverights, &cap_event_rights);
+	if (__predict_false(error != 0))
+		return (EBADF);
+	*fpp = fp;
+	return (0);
+}
+#else
+static int
+poll_fget(struct filedesc *fdp, int fd, struct file **fpp)
+{
+	struct file *fp;
+
+	if (__predict_false(fd >= fdp->fd_nfiles))
+		return (EBADF);
+
+	fp = fdp->fd_ofiles[fd].fde_file;
+	if (__predict_false(fp == NULL))
+		return (EBADF);
+
+	*fpp = fp;
+	return (0);
+}
+#endif
+
+static int
 pollrescan(struct thread *td)
 {
 	struct seltd *stp;
@@ -1499,19 +1542,11 @@ pollrescan(struct thread *td)
 		/* If the selinfo wasn't cleared the event didn't fire. */
 		if (si != NULL)
 			continue;
-		fp = fdp->fd_ofiles[fd->fd].fde_file;
-#ifdef CAPABILITIES
-		if (fp == NULL ||
-		    cap_check(cap_rights(fdp, fd->fd), &cap_event_rights) != 0)
-#else
-		if (fp == NULL)
-#endif
-		{
+		if (poll_fget(fdp, fd->fd, &fp) != 0) {
 			fd->revents = POLLNVAL;
 			n++;
 			continue;
 		}
-
 		/*
 		 * Note: backend also returns POLLHUP and
 		 * POLLERR if appropriate.
@@ -1550,47 +1585,39 @@ pollout(struct thread *td, struct pollfd *fds, struct 
 static int
 pollscan(struct thread *td, struct pollfd *fds, u_int nfd)
 {
-	struct filedesc *fdp = td->td_proc->p_fd;
+	struct filedesc *fdp;
 	struct file *fp;
-	int i, n = 0;
+	int i, n;
 
+	n = 0;
+	fdp = td->td_proc->p_fd;
 	FILEDESC_SLOCK(fdp);
 	for (i = 0; i < nfd; i++, fds++) {
-		if (fds->fd >= fdp->fd_nfiles) {
+		if (fds->fd < 0) {
+			fds->revents = 0;
+			continue;
+		}
+		if (poll_fget(fdp, fds->fd, &fp) != 0) {
 			fds->revents = POLLNVAL;
 			n++;
-		} else if (fds->fd < 0) {
-			fds->revents = 0;
-		} else {
-			fp = fdp->fd_ofiles[fds->fd].fde_file;
-#ifdef CAPABILITIES
-			if (fp == NULL ||
-			    cap_check(cap_rights(fdp, fds->fd), &cap_event_rights) != 0)
-#else
-			if (fp == NULL)
-#endif
-			{
-				fds->revents = POLLNVAL;
-				n++;
-			} else {
-				/*
-				 * Note: backend also returns POLLHUP and
-				 * POLLERR if appropriate.
-				 */
-				selfdalloc(td, fds);
-				fds->revents = fo_poll(fp, fds->events,
-				    td->td_ucred, td);
-				/*
-				 * POSIX requires POLLOUT to be never
-				 * set simultaneously with POLLHUP.
-				 */
-				if ((fds->revents & POLLHUP) != 0)
-					fds->revents &= ~POLLOUT;
-
-				if (fds->revents != 0)
-					n++;
-			}
+			continue;
 		}
+		/*
+		 * Note: backend also returns POLLHUP and
+		 * POLLERR if appropriate.
+		 */
+		selfdalloc(td, fds);
+		fds->revents = fo_poll(fp, fds->events,
+		    td->td_ucred, td);
+		/*
+		 * POSIX requires POLLOUT to be never
+		 * set simultaneously with POLLHUP.
+		 */
+		if ((fds->revents & POLLHUP) != 0)
+			fds->revents &= ~POLLOUT;
+
+		if (fds->revents != 0)
+			n++;
 	}
 	FILEDESC_SUNLOCK(fdp);
 	td->td_retval[0] = n;



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