Accept more types of FD Taps in #eventfd
authorBarret Rhoden <brho@cs.berkeley.edu>
Tue, 29 Sep 2015 19:09:33 +0000 (15:09 -0400)
committerBarret Rhoden <brho@cs.berkeley.edu>
Thu, 8 Oct 2015 14:29:57 +0000 (10:29 -0400)
The taps will never fire, but people can at least ask for them.  Asking
for ERROR is actually legitimate in Linux.

In general, being strict with what taps people ask for might be too
harsh, though in general if someone asks for something, they might
actually care if it happens or not.  For instance, we don't want to have
a device that can't do a READABLE tap and then have an app that thinks
it is waiting for READABLE to fire.  It never will, and the application
will hang.  So perhaps being strict on the more *important* taps is the
way to go.

Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
kern/drivers/dev/eventfd.c

index 92a7194..faa8aba 100644 (file)
@@ -279,16 +279,20 @@ static int efd_tapfd(struct chan *c, struct fd_tap *tap, int cmd)
        struct eventfd *efd = c->aux;
        int ret;
 
-       /* We don't actually support HANGUP, but epoll implies it */
+       /* HANGUP, ERROR, and PRIORITY will never fire, but people can ask for them.
+        * We don't actually support HANGUP, but epoll implies it.  Linux's eventfd
+        * cand have ERROR, so apps can ask for it.  Likewise, priority is
+        * meaningless for us, but sometimes people ask for it. */
        #define EFD_LEGAL_TAPS (FDTAP_FILT_READABLE | FDTAP_FILT_WRITABLE |        \
-                               FDTAP_FILT_HANGUP)
+                               FDTAP_FILT_HANGUP | FDTAP_FILT_PRIORITY |          \
+                               FDTAP_FILT_ERROR)
 
        switch (c->qid.path) {
                case Qefd:
                        if (tap->filter & ~EFD_LEGAL_TAPS) {
                                set_errno(ENOSYS);
-                               set_errstr("Unsupported #%s tap, must be %p", devname(),
-                                          EFD_LEGAL_TAPS);
+                               set_errstr("Unsupported #%s tap, must be %p, got %p", devname(),
+                                          EFD_LEGAL_TAPS, tap->filter);
                                return -1;
                        }
                        spin_lock(&efd->tap_lock);