Serialize printing during panic()
[akaros.git] / kern / src / fdtap.c
index 26a1397..540fc4d 100644 (file)
@@ -6,11 +6,11 @@
  * FD's underlying device file/qid. */
 
 #include <fdtap.h>
-#include <vfs.h>
 #include <event.h>
 #include <kmalloc.h>
+#include <syscall.h>
 #include <error.h>
-
+#include <umem.h>
 
 static void tap_min_release(struct kref *kref)
 {
@@ -43,14 +43,18 @@ int add_fd_tap(struct proc *p, struct fd_tap_req *tap_req)
                set_errno(EBADF);
                return -1;
        }
-       tap = kzmalloc(sizeof(struct fd_tap), KMALLOC_WAIT);
+       tap = kzmalloc(sizeof(struct fd_tap), MEM_WAIT);
        tap->proc = p;
        tap->fd = fd;
        tap->filter = tap_req->filter;
        tap->ev_q = tap_req->ev_q;
        tap->ev_id = tap_req->ev_id;
        tap->data = tap_req->data;
-
+       if (!is_user_rwaddr(tap->ev_q, sizeof(struct event_queue))) {
+               set_error(EINVAL, "Tap request with bad event_queue %p", tap->ev_q);
+               kfree(tap);
+               return -1;
+       }
        spin_lock(&fdt->lock);
        if (fd >= fdt->max_fdset) {
                set_errno(ENFILE);
@@ -61,19 +65,17 @@ int add_fd_tap(struct proc *p, struct fd_tap_req *tap_req)
                goto out_with_lock;
        }
        if (!fdt->fd[fd].fd_chan) {
-               set_errno(EINVAL);
-               set_errstr("Can't tap a VFS file");
+               set_error(EINVAL, "Can't tap a VFS file");
                goto out_with_lock;
        }
        chan = fdt->fd[fd].fd_chan;
        if (fdt->fd[fd].fd_tap) {
-               set_errno(EBUSY);
-               set_errstr("FD %d already has a tap", fd);
+               set_error(EBUSY, "FD %d already has a tap", fd);
                goto out_with_lock;
        }
        if (!devtab[chan->type].tapfd) {
-               set_errno(ENOSYS);
-               set_errstr("Device %c does not handle taps", devtab[chan->type].dc);
+               set_error(ENOSYS, "Device %s does not handle taps",
+                                 devtab[chan->type].name);
                goto out_with_lock;
        }
        /* need to keep chan alive for our call to the device.  someone else
@@ -134,8 +136,7 @@ int remove_fd_tap(struct proc *p, int fd)
                kref_put(&tap->kref);
                return 0;
        } else {
-               set_errno(EBADF);
-               set_errstr("FD %d was not tapped", fd);
+               set_error(EBADF, "FD %d was not tapped", fd);
                return -1;
        }
 }