Print this page
8634 epoll fails to wake on certain edge-triggered conditions
8635 epoll should not emit POLLNVAL
8636 recursive epoll should emit EPOLLRDNORM
Reviewed by: Jerry Jelinek <jerry.jelinek@joyent.com>
Reviewed by: Robert Mustacchi <rm@joyent.com>
Reviewed by: Toomas Soome <tsoome@me.com>
Reviewed by: Igor Kozhukhov <igor@dilos.org>

Split Close
Expand all
Collapse all
          --- old/usr/src/uts/common/fs/fs_subr.c
          +++ new/usr/src/uts/common/fs/fs_subr.c
↓ open down ↓ 17 lines elided ↑ open up ↑
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*      Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
  22   22  /*        All Rights Reserved   */
  23   23  
  24   24  
  25   25  /*
  26   26   * Copyright (c) 1989, 2010, Oracle and/or its affiliates. All rights reserved.
  27   27   * Copyright 2011 Nexenta Systems, Inc.  All rights reserved.
  28      - * Copyright 2015 Joyent, Inc.
       28 + * Copyright 2017 Joyent, Inc.
  29   29   */
  30   30  
  31   31  /*
  32   32   * Generic vnode operations.
  33   33   */
  34   34  #include <sys/types.h>
  35   35  #include <sys/param.h>
  36   36  #include <sys/systm.h>
  37   37  #include <sys/errno.h>
  38   38  #include <sys/fcntl.h>
↓ open down ↓ 370 lines elided ↑ open up ↑
 409  409   * Return the answer requested to poll() for non-device files.
 410  410   * Only POLLIN, POLLRDNORM, and POLLOUT are recognized.
 411  411   */
 412  412  struct pollhead fs_pollhd;
 413  413  
 414  414  /* ARGSUSED */
 415  415  int
 416  416  fs_poll(vnode_t *vp, short events, int anyyet, short *reventsp,
 417  417      struct pollhead **phpp, caller_context_t *ct)
 418  418  {
      419 +        /*
      420 +         * Reject all attempts for edge-triggered polling.  These should only
      421 +         * occur when regular files are added to a /dev/poll handle which is in
      422 +         * epoll mode.  The Linux epoll does not allow epoll-ing on regular
      423 +         * files at all, so rejecting EPOLLET requests is congruent with those
      424 +         * expectations.
      425 +         */
      426 +        if (events & POLLET) {
      427 +                return (EPERM);
      428 +        }
      429 +
 419  430          *reventsp = 0;
 420  431          if (events & POLLIN)
 421  432                  *reventsp |= POLLIN;
 422  433          if (events & POLLRDNORM)
 423  434                  *reventsp |= POLLRDNORM;
 424  435          if (events & POLLRDBAND)
 425  436                  *reventsp |= POLLRDBAND;
 426  437          if (events & POLLOUT)
 427  438                  *reventsp |= POLLOUT;
 428  439          if (events & POLLWRBAND)
 429  440                  *reventsp |= POLLWRBAND;
 430      -        *phpp = !anyyet && !*reventsp ? &fs_pollhd : (struct pollhead *)NULL;
      441 +        /*
      442 +         * Emitting a pollhead without the intention of issuing pollwakeup()
      443 +         * calls against it is a recipe for trouble.  It's only acceptable in
      444 +         * this case since the above logic matches practically all useful
      445 +         * events.
      446 +         */
      447 +        if (*reventsp == 0 && !anyyet) {
      448 +                *phpp = &fs_pollhd;
      449 +        }
 431  450          return (0);
 432  451  }
 433  452  
 434  453  /*
 435  454   * POSIX pathconf() support.
 436  455   */
 437  456  /* ARGSUSED */
 438  457  int
 439  458  fs_pathconf(vnode_t *vp, int cmd, ulong_t *valp, cred_t *cr,
 440  459      caller_context_t *ct)
↓ open down ↓ 568 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX