commit-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[hurd] 01/10: New upstream snapshot


From: Samuel Thibault
Subject: [hurd] 01/10: New upstream snapshot
Date: Tue, 27 May 2014 08:32:06 +0000

This is an automated email from the git hooks/post-receive script.

sthibault pushed a commit to branch master
in repository hurd.

commit 88c245dd42be5ee57d5507e24a078e06fa0dc52a
Author: Samuel Thibault <address@hidden>
Date:   Sun May 25 15:02:03 2014 +0000

    New upstream snapshot
---
 boot/Makefile                                    |   6 +-
 boot/boot.c                                      |   2 +-
 config.make.in                                   |   3 -
 configure.ac                                     |   4 -
 console-client/Makefile                          |   4 -
 console-client/trans.c                           |   1 +
 console/console.c                                |  40 ++--
 console/display.c                                |  39 ++--
 console/mutations.h                              |   9 +-
 devnode/Makefile                                 |   7 +-
 devnode/devnode.c                                |  36 ++--
 proc/mig-decls.h => devnode/mig-mutate.h         |  35 +--
 eth-filter/Makefile                              |   7 +-
 eth-filter/filter.c                              |  99 ++++-----
 {proc => eth-filter}/mig-decls.h                 |  35 +--
 proc/mig-decls.h => eth-filter/mig-mutate.h      |  42 ++--
 eth-multiplexer/Makefile                         |   8 +-
 eth-multiplexer/device_impl.c                    |  59 ++---
 {proc => eth-multiplexer}/mig-decls.h            |  35 +--
 proc/mig-decls.h => eth-multiplexer/mig-mutate.h |  42 ++--
 eth-multiplexer/multiplexer.c                    |  24 ++-
 eth-multiplexer/notify_impl.c                    |  14 +-
 exec/Makefile                                    |   1 +
 exec/exec.c                                      |  20 +-
 exec/execmutations.h                             |   8 +
 console/priv.h => exec/mig-decls.h               |  31 ++-
 exec/priv.h                                      |   2 +-
 ext2fs/ext2fs.h                                  |   8 +-
 ext2fs/hyper.c                                   |  19 +-
 ext2fs/ialloc.c                                  |   3 +-
 ext2fs/inode.c                                   |  11 +-
 ext2fs/pager.c                                   |  90 +++++---
 ext2fs/storeinfo.c                               |   1 +
 fatfs/inode.c                                    |  14 +-
 fatfs/main.c                                     |   3 +-
 fatfs/pager.c                                    |  90 +++++---
 hurd/exec_startup.defs                           |   6 +-
 hurd/hurd_types.defs                             |  24 +++
 hurd/hurd_types.h                                |   2 +
 hurd/interrupt.defs                              |   6 +-
 include/refcount.h                               | 263 +++++++++++++++++++++++
 isofs/inode.c                                    |   1 +
 libdiskfs/Makefile                               |   1 +
 libdiskfs/boot-start.c                           |  11 +-
 libdiskfs/dir-renamed.c                          |   7 +-
 libdiskfs/diskfs.h                               |  23 ++
 libdiskfs/file-chg.c                             |   2 +-
 libdiskfs/file-chmod.c                           |   1 +
 libdiskfs/file-get-fs-opts.c                     |   1 +
 libdiskfs/fsmutations.h                          |  15 +-
 libdiskfs/init-startup.c                         |   2 +
 libdiskfs/priv.h                                 |   3 +-
 libihash/ihash.c                                 | 151 +++----------
 libihash/ihash.h                                 |  54 +++--
 libmachdev/Makefile                              |   6 +-
 libmachdev/block.c                               |   1 +
 libmachdev/ds_routines.c                         | 244 +++++++--------------
 libmachdev/ds_routines.h                         |   2 +
 {proc => libmachdev}/mig-decls.h                 |  34 +--
 proc/mig-decls.h => libmachdev/mig-mutate.h      |  42 ++--
 libmachdev/net.c                                 |  18 +-
 libmachdev/trivfs_server.c                       |  34 +--
 libnetfs/file-get-children.c                     |   1 +
 libnetfs/file-getcontrol.c                       |   2 +-
 libnetfs/file-set-translator.c                   |   1 +
 libnetfs/fsstubs.c                               |   1 +
 libnetfs/mutations.h                             |   8 +-
 libpager/Makefile                                |   2 +-
 libpager/chg-compl.c                             |  10 +-
 libpager/data-request.c                          |  10 +-
 libpager/data-return.c                           |  13 +-
 libpager/data-unlock.c                           |   8 +-
 libpager/lock-completed.c                        |   8 +-
 {proc => libpager}/mig-decls.h                   |  32 +--
 proc/mig-decls.h => libpager/mig-mutate.h        |  37 ++--
 libpager/no-senders.c                            |  21 +-
 libpager/notify-stubs.c                          |  20 +-
 libpager/object-init.c                           |   9 +-
 libpager/object-terminate.c                      |   9 +-
 libpager/priv.h                                  |   1 +
 libpager/seqnos.c                                |  14 +-
 libpager/stubs.c                                 |  12 +-
 libports/Makefile                                |   1 +
 libports/bucket-iterate.c                        |  49 +++--
 libports/interrupt-operation.c                   |   4 +-
 libports/manage-one-thread.c                     |   9 +-
 {proc => libports}/mig-decls.h                   |  30 ++-
 proc/mig-decls.h => libports/mig-mutate.h        |  42 ++--
 libports/notify-dead-name.c                      |   5 +-
 libports/notify-msg-accepted.c                   |   3 +-
 libports/notify-no-senders.c                     |   5 +-
 libports/notify-port-deleted.c                   |   3 +-
 libports/notify-port-destroyed.c                 |   3 +-
 libports/notify-send-once.c                      |   2 +-
 libports/ports.h                                 |  25 ++-
 libtrivfs/file-access.c                          |   1 +
 libtrivfs/file-chauthor.c                        |   1 +
 libtrivfs/file-chflags.c                         |   1 +
 libtrivfs/file-chg.c                             |   1 +
 libtrivfs/file-chmod.c                           |   1 +
 libtrivfs/file-chown.c                           |   1 +
 libtrivfs/file-exec.c                            |   1 +
 libtrivfs/file-get-children.c                    |   1 +
 libtrivfs/file-get-fs-options.c                  |   1 +
 libtrivfs/file-get-source.c                      |   1 +
 libtrivfs/file-get-storage-info.c                |   1 +
 libtrivfs/file-get-trans.c                       |   1 +
 libtrivfs/file-get-transcntl.c                   |   1 +
 libtrivfs/file-getcontrol.c                      |   1 +
 libtrivfs/file-getfh.c                           |   1 +
 libtrivfs/file-getlinknode.c                     |   1 +
 libtrivfs/file-lock.c                            |   1 +
 libtrivfs/file-reparent.c                        |   2 +
 libtrivfs/file-set-size.c                        |   1 +
 libtrivfs/file-set-trans.c                       |   1 +
 libtrivfs/file-statfs.c                          |   1 +
 libtrivfs/file-sync.c                            |   1 +
 libtrivfs/file-syncfs.c                          |   1 +
 libtrivfs/file-utimes.c                          |   1 +
 libtrivfs/fsys-forward.c                         |   1 +
 libtrivfs/fsys-get-options.c                     |   1 +
 libtrivfs/fsys-getroot.c                         |   1 +
 libtrivfs/fsys-goaway.c                          |   1 +
 libtrivfs/fsys-set-options.c                     |   1 +
 libtrivfs/fsys-stubs.c                           |   1 +
 libtrivfs/fsys-syncfs.c                          |   1 +
 libtrivfs/io-async-icky.c                        |   1 +
 libtrivfs/io-async.c                             |   1 +
 libtrivfs/io-duplicate.c                         |   1 +
 libtrivfs/io-identity.c                          |   1 +
 libtrivfs/io-map.c                               |   1 +
 libtrivfs/io-modes-get.c                         |   1 +
 libtrivfs/io-modes-off.c                         |   1 +
 libtrivfs/io-modes-on.c                          |   1 +
 libtrivfs/io-modes-set.c                         |   1 +
 libtrivfs/io-owner-get.c                         |   1 +
 libtrivfs/io-owner-mod.c                         |   1 +
 libtrivfs/io-pathconf.c                          |   1 +
 libtrivfs/io-read.c                              |   1 +
 libtrivfs/io-readable.c                          |   1 +
 libtrivfs/io-reauthenticate.c                    |   1 +
 libtrivfs/io-restrict-auth.c                     |   1 +
 libtrivfs/io-revoke.c                            |   1 +
 libtrivfs/io-seek.c                              |   1 +
 libtrivfs/io-select.c                            |   1 +
 libtrivfs/io-stat.c                              |   1 +
 libtrivfs/io-stubs.c                             |   1 +
 libtrivfs/io-version.c                           |   1 +
 libtrivfs/io-write.c                             |   1 +
 libtrivfs/mig-mutate.h                           |   6 +-
 pfinet/tunnel.c                                  |   3 +
 proc/Makefile                                    |   4 +-
 proc/hash.c                                      |  11 -
 proc/mgt.c                                       |   1 -
 proc/mig-decls.h                                 |  18 ++
 proc/{mig-decls.h => mig-mutate.h}               |  39 ++--
 proc/notify.c                                    |  24 +--
 proc/proc.h                                      |   7 -
 random/Makefile                                  |   1 +
 {proc => random}/mig-decls.h                     |  37 ++--
 proc/mig-decls.h => random/mig-mutate.h          |  35 +--
 random/random.c                                  |   5 +-
 storeio/io.c                                     |   2 +
 storeio/storeio.c                                |   1 +
 term/devio.c                                     |   6 +-
 term/users.c                                     |   2 +
 tmpfs/node.c                                     |  10 +-
 trans/Makefile                                   |   4 +-
 trans/fakeroot.c                                 |  30 ++-
 trans/fifo.c                                     |   3 +
 trans/firmlink.c                                 |   2 +
 trans/hello-mt.c                                 |   2 +
 trans/hello.c                                    |   2 +
 trans/magic.c                                    |   2 +
 trans/mtab.c                                     |   1 +
 trans/new-fifo.c                                 |   4 +
 trans/null.c                                     |   3 +
 trans/proxy-defpager.c                           |   1 +
 trans/streamio.c                                 |   3 +
 utils/Makefile                                   |   8 +-
 utils/rpctrace.c                                 |   2 +
 181 files changed, 1412 insertions(+), 1128 deletions(-)

diff --git a/boot/Makefile b/boot/Makefile
index 0d883b0..2d52f3f 100644
--- a/boot/Makefile
+++ b/boot/Makefile
@@ -20,7 +20,7 @@ makemode := utility
 
 SRCS = mach-crt0.c boot.c ux.c sigvec.S syscall.S \
        boot_script.c userland-boot.c
-COMMON-OBJS = notifyServer.o ourdeviceServer.o \
+COMMON-OBJS = notifyServer.o deviceServer.o \
        ioServer.o io_replyUser.o device_replyUser.o \
        termServer.o bootstrapServer.o boot_script.o userland-boot.o
 OBJS = boot.o $(COMMON-OBJS)
@@ -39,10 +39,6 @@ include ../Makeconf
 
 all: boot # uxboot
 
-ourdevice.defs: device.defs
-       $(CPP) $(CPPFLAGS) -x c $< | sed -e '/out[      ]*device[       ]*:[    
]*device_t/s/device_t/mach_port_send_t/' > $@
-
-
 uxboot.o: boot.c
        $(COMPILE.c) -DUX $< -o $@
 
diff --git a/boot/boot.c b/boot/boot.c
index 0dbe1c2..ed29014 100644
--- a/boot/boot.c
+++ b/boot/boot.c
@@ -42,7 +42,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 #include <version.h>
 
 #include "notify_S.h"
-#include "ourdevice_S.h"
+#include "device_S.h"
 #include "io_S.h"
 #include "device_reply_U.h"
 #include "io_reply_U.h"
diff --git a/config.make.in b/config.make.in
index c5d4e68..0f1390a 100644
--- a/config.make.in
+++ b/config.make.in
@@ -65,9 +65,6 @@ gnu89-inline-CFLAGS = @libc_cv_gnu89_inline@
 # `yes' or `no' to indicate if ld --version-script is available.
 VERSIONING = @VERSIONING@
 
-# If a separate libcrypt is available, use it.
-LIBCRYPT = @LIBCRYPT@
-
 # How to link against Parted libraries, if at all.
 PARTED_LIBS = @PARTED_LIBS@
 
diff --git a/configure.ac b/configure.ac
index ecabfdf..873ced8 100644
--- a/configure.ac
+++ b/configure.ac
@@ -106,10 +106,6 @@ fi
 dnl Let these propagate from the environment.
 AC_SUBST(CFLAGS) AC_SUBST(CPPFLAGS) AC_SUBST(LDFLAGS)
 
-# See if there's a separate libcrypt (many systems put crypt there).
-AC_CHECK_LIB(crypt, crypt, LIBCRYPT=-lcrypt)
-AC_SUBST(LIBCRYPT)
-
 hurd_MIG_RETCODE
 
 # See if --version-script is available.
diff --git a/console-client/Makefile b/console-client/Makefile
index 65a04e0..f576cbe 100644
--- a/console-client/Makefile
+++ b/console-client/Makefile
@@ -49,10 +49,6 @@ XKB_DATA_FILES = keymap/hurd types/hurd symbols/hurd
 # In seeking, thou shalt find it!
 CPPFLAGS += -DQUAERENDO_INVENIETIS
 
-DIST_FILES = xkb/HACKING xkb/MISSING-FEATURES xkb/README xkb/TODO \
-             xkb/kstoucs_map.sh \
-             $(addprefix xkb/xkb-data/, $(XKB_DATA_FILES))
-
 include ../Makeconf
 
 driver-CPPFLAGS = -D'CONSOLE_DEFPATH="$(module-dir)\0"' \
diff --git a/console-client/trans.c b/console-client/trans.c
index d65161c..67cd149 100644
--- a/console-client/trans.c
+++ b/console-client/trans.c
@@ -31,6 +31,7 @@
 #include <stdio.h>
 
 #include "trans.h"
+#include "libnetfs/io_S.h"
 
 
 char *netfs_server_name = "console";
diff --git a/console/console.c b/console/console.c
index 0577ea0..57ae813 100644
--- a/console/console.c
+++ b/console/console.c
@@ -48,6 +48,9 @@
 #include "input.h"
 
 #include "fs_notify_U.h"
+#include "libnetfs/fs_S.h"
+#include "libnetfs/io_S.h"
+#include "tioctl_S.h"
 
 const char *argp_program_version = STANDARD_HURD_VERSION (console);
 
@@ -1815,98 +1818,101 @@ S_tioctl_tiocgpgrp (struct protid *cred, int *pgrp)
 }
 
 kern_return_t
-S_tioctl_tiocmodg (io_t port, int *state)
+S_tioctl_tiocmodg (struct protid *cred, int *state)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-S_tioctl_tiocmods (io_t port, int state)
+S_tioctl_tiocmods (struct protid *cred, int state)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-S_tioctl_tiocexcl (io_t port)
+S_tioctl_tiocexcl (struct protid *cred)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-S_tioctl_tiocnxcl (io_t port)
+S_tioctl_tiocnxcl (struct protid *cred)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-S_tioctl_tiocgeta (io_t port, tcflag_t *modes, cc_t *ccs, speed_t *speeds)
+S_tioctl_tiocgeta (struct protid *cred, tcflag_t *modes, cc_t *ccs,
+                  speed_t *speeds)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-S_tioctl_tiocseta (io_t port, tcflag_t *modes, cc_t *ccs, speed_t *speeds)
+S_tioctl_tiocseta (struct protid *cred, tcflag_t *modes, cc_t *ccs,
+                  speed_t *speeds)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-S_tioctl_tiocsetaw (io_t port, tcflag_t *modes, cc_t *ccs, speed_t *speeds)
+S_tioctl_tiocsetaw (struct protid *cred, tcflag_t *modes, cc_t *ccs,
+                   speed_t *speeds)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-S_tioctl_tiocsetaf (io_t port, tcflag_t *modes, cc_t *ccs,
-                                 speed_t *speeds)
+S_tioctl_tiocsetaf (struct protid *cred, tcflag_t *modes, cc_t *ccs,
+                   speed_t *speeds)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-S_tioctl_tiocgetd (io_t port, int *disc)
+S_tioctl_tiocgetd (struct protid *cred, int *disc)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-S_tioctl_tiocsetd (io_t port, int disc)
+S_tioctl_tiocsetd (struct protid *cred, int disc)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-S_tioctl_tiocdrain (io_t port)
+S_tioctl_tiocdrain (struct protid *cred)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-S_tioctl_tiocmget (io_t port, int *bits)
+S_tioctl_tiocmget (struct protid *cred, int *bits)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-S_tioctl_tiocmset (io_t port, int bits)
+S_tioctl_tiocmset (struct protid *cred, int bits)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-S_tioctl_tiocsig (io_t port, int sig)
+S_tioctl_tiocsig (struct protid *cred, int sig)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-S_tioctl_tiocext (io_t port, int mode)
+S_tioctl_tiocext (struct protid *cred, int mode)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-S_tioctl_tiocucntl (io_t port, int mode)
+S_tioctl_tiocucntl (struct protid *cred, int mode)
 
 {
   return EOPNOTSUPP;
diff --git a/console/display.c b/console/display.c
index 8d9e478..09add5c 100644
--- a/console/display.c
+++ b/console/display.c
@@ -42,6 +42,7 @@
 #include "display.h"
 #include "pager.h"
 
+#include "notify_S.h"
 
 struct changes
 {
@@ -318,7 +319,7 @@ free_modreqs (struct modreq *mr)
 /* A port deleted notification is generated when we deallocate the
    user's notify port before it is dead.  */
 error_t
-do_mach_notify_port_deleted (mach_port_t notify, mach_port_t name)
+do_mach_notify_port_deleted (struct port_info *pi, mach_port_t name)
 {
   /* As we cancel the dead-name notification before deallocating the
      port, this should not happen.  */
@@ -327,15 +328,16 @@ do_mach_notify_port_deleted (mach_port_t notify, 
mach_port_t name)
 
 /* We request dead name notifications for the user ports.  */
 error_t
-do_mach_notify_dead_name (mach_port_t notify, mach_port_t dead_name)
+do_mach_notify_dead_name (struct port_info *pi, mach_port_t dead_name)
 {
-  struct notify *notify_port = ports_lookup_port (notify_bucket,
-                                                 notify, notify_class);
+  struct notify *notify_port = (struct notify *) pi;
   struct display *display;
   struct modreq **preq;
   struct modreq *req;
 
-  if (!notify_port)
+  if (!notify_port
+      || notify_port->pi.bucket != notify_bucket
+      || notify_port->pi.class != notify_class)
     return EOPNOTSUPP;
 
   display = notify_port->display;
@@ -369,30 +371,35 @@ do_mach_notify_dead_name (mach_port_t notify, mach_port_t 
dead_name)
   return 0;
 }
 
-void do_mach_notify_port_destroyed (void) { assert (0); }
+error_t
+do_mach_notify_port_destroyed (struct port_info *pi, mach_port_t rights)
+{
+  assert (0);
+}
 
 error_t
-do_mach_notify_no_senders (mach_port_t port, mach_port_mscount_t count)
+do_mach_notify_no_senders (struct port_info *pi, mach_port_mscount_t count)
 {
-  return ports_do_mach_notify_no_senders (port, count);
+  return ports_do_mach_notify_no_senders (pi, count);
 }
 
 kern_return_t
-do_mach_notify_send_once (mach_port_t notify)
+do_mach_notify_send_once (struct port_info *pi)
 {
   return 0;
 }
 
 kern_return_t
-do_mach_notify_msg_accepted (mach_port_t notify, mach_port_t send)
+do_mach_notify_msg_accepted (struct port_info *pi, mach_port_t send)
 {
-  struct notify *notify_port = ports_lookup_port (notify_bucket,
-                                                 notify, notify_class);
+  struct notify *notify_port = (struct notify *) pi;
   struct display *display;
   struct modreq **preq;
   struct modreq *req;
 
-  if (!notify_port)
+  if (!notify_port
+      || notify_port->pi.bucket != notify_bucket
+      || notify_port->pi.class != notify_class)
     return EOPNOTSUPP;
 
   /* If we deallocated the send right in display_destroy before the
@@ -401,7 +408,6 @@ do_mach_notify_msg_accepted (mach_port_t notify, 
mach_port_t send)
   if (!send)
     {
       assert(0);
-      ports_port_deref (notify_port);
       return 0;
     }
 
@@ -418,7 +424,6 @@ do_mach_notify_msg_accepted (mach_port_t notify, 
mach_port_t send)
     {
       assert(0);
       pthread_mutex_unlock (&display->lock);
-      ports_port_deref (notify_port);
       return 0;
     }
   req = *preq;
@@ -430,7 +435,7 @@ do_mach_notify_msg_accepted (mach_port_t notify, 
mach_port_t send)
         and stay in pending queue.  */
       req->pending = 0;
       err = nowait_file_changed (req->port, 0, FILE_CHANGED_WRITE, -1, -1,
-                                notify);
+                                notify_port->pi.port_right);
       if (err && err != MACH_SEND_WILL_NOTIFY)
        {
          mach_port_t old;
@@ -446,7 +451,6 @@ do_mach_notify_msg_accepted (mach_port_t notify, 
mach_port_t send)
 
          mach_port_deallocate (mach_task_self (), req->port);
          free (req);
-         ports_port_deref (notify_port);
          return err;
        }
       if (err == MACH_SEND_WILL_NOTIFY)
@@ -462,7 +466,6 @@ do_mach_notify_msg_accepted (mach_port_t notify, 
mach_port_t send)
   req->next = display->filemod_reqs;
   display->filemod_reqs = req;
   pthread_mutex_unlock (&display->lock);
-  ports_port_deref (notify_port);
   return 0;
 }
 
diff --git a/console/mutations.h b/console/mutations.h
index 5f26672..4e1cc7e 100644
--- a/console/mutations.h
+++ b/console/mutations.h
@@ -23,4 +23,11 @@
 #define IO_INTRAN protid_t begin_using_protid_port (io_t)
 #define IO_DESTRUCTOR end_using_protid_port (protid_t)
 
-#define TIOCTL_IMPORTS import "priv.h";
+#define TIOCTL_IMPORTS import "libnetfs/priv.h";
+
+#define NOTIFY_INTRAN                                          \
+  port_info_t begin_using_port_info_port (mach_port_t)
+#define NOTIFY_DESTRUCTOR                                      \
+  end_using_port_info (port_info_t)
+#define NOTIFY_IMPORTS                                         \
+  import "libports/mig-decls.h";
diff --git a/devnode/Makefile b/devnode/Makefile
index f452256..d9a9c23 100644
--- a/devnode/Makefile
+++ b/devnode/Makefile
@@ -20,13 +20,10 @@ makemode := server
 
 SRCS = devnode.c
 LCLHDRS = util.h
-DIST_FILES = ourdevice.defs notify.defs
 HURDLIBS = ports trivfs fshelp shouldbeinlibc
 target = devnode
-MIGSTUBS = ourdeviceServer.o notifyServer.o
+MIGSTUBS = deviceServer.o notifyServer.o
+MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
 OBJS = $(SRCS:.c=.o) $(MIGSTUBS)
 
 include ../Makeconf
-
-ourdevice.defs: device.defs
-       $(CPP) $(CPPFLAGS) -x c $< | sed -e '/out[      ]*device[       ]*:[    
]*device_t/s/device_t/mach_port_send_t/' > $@
diff --git a/devnode/devnode.c b/devnode/devnode.c
index 947d31b..789bf51 100644
--- a/devnode/devnode.c
+++ b/devnode/devnode.c
@@ -35,8 +35,9 @@
 #include <device/device.h>
 #include <hurd/trivfs.h>
 #include <hurd/ports.h>
+#include <version.h>
 
-#include "ourdevice_S.h"
+#include "device_S.h"
 #include "notify_S.h"
 #include "util.h"
 
@@ -48,8 +49,8 @@ static char *master_file;
 /* The master device port for opening the interface. */
 static mach_port_t master_device;
 
-const char *argp_program_version = "devnode 0.1";
-const char *argp_program_bug_address = "<address@hidden>";
+const char *argp_program_version = STANDARD_HURD_VERSION (devnode);
+
 static const char args_doc[] = "device";
 static const char doc[] = "Hurd devnode translator.";
 static const struct argp_option options[] =
@@ -81,49 +82,56 @@ static int
 devnode_demuxer (mach_msg_header_t *inp,
                    mach_msg_header_t *outp)
 {
-  extern int device_server (mach_msg_header_t *, mach_msg_header_t *);
-  extern int notify_server (mach_msg_header_t *, mach_msg_header_t *);
-  return device_server (inp, outp) || notify_server (inp, outp)
-    || trivfs_demuxer (inp, outp);
+  mig_routine_t routine;
+  if ((routine = device_server_routine (inp)) ||
+      (routine = notify_server_routine (inp)) ||
+      (routine = NULL, trivfs_demuxer (inp, outp)))
+    {
+      if (routine)
+        (*routine) (inp, outp);
+      return TRUE;
+    }
+  else
+    return FALSE;
 }
 
 /* Implementation of notify interface */
 kern_return_t
-do_mach_notify_port_deleted (mach_port_t notify,
+do_mach_notify_port_deleted (struct port_info *pi,
                             mach_port_t name)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-do_mach_notify_msg_accepted (mach_port_t notify,
+do_mach_notify_msg_accepted (struct port_info *pi,
                             mach_port_t name)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-do_mach_notify_port_destroyed (mach_port_t notify,
+do_mach_notify_port_destroyed (struct port_info *pi,
                               mach_port_t port)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-do_mach_notify_no_senders (mach_port_t notify,
+do_mach_notify_no_senders (struct port_info *pi,
                           mach_port_mscount_t mscount)
 {
-  return ports_do_mach_notify_no_senders (notify, mscount);
+  return ports_do_mach_notify_no_senders (pi, mscount);
 }
 
 kern_return_t
-do_mach_notify_send_once (mach_port_t notify)
+do_mach_notify_send_once (struct port_info *pi)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-do_mach_notify_dead_name (mach_port_t notify,
+do_mach_notify_dead_name (struct port_info *pi,
                          mach_port_t name)
 {
   return EOPNOTSUPP;
diff --git a/proc/mig-decls.h b/devnode/mig-mutate.h
similarity index 56%
copy from proc/mig-decls.h
copy to devnode/mig-mutate.h
index 0d5bd4d..f692236 100644
--- a/proc/mig-decls.h
+++ b/devnode/mig-mutate.h
@@ -1,8 +1,6 @@
-/* Translation functions for mig.
-
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
+/*
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Justus Winter.
 
    This file is part of the GNU Hurd.
 
@@ -19,24 +17,9 @@
    You should have received a copy of the GNU General Public License
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#ifndef __MIG_DECLS_H__
-#define __MIG_DECLS_H__
-
-#include "proc.h"
-
-typedef struct exc* exc_t;
-
-static inline exc_t __attribute__ ((unused))
-begin_using_exc_port (mach_port_t port)
-{
-  return ports_lookup_port (NULL, port, exc_class);
-}
-
-static inline void __attribute__ ((unused))
-end_using_exc (exc_t exc)
-{
-  if (exc != NULL)
-    ports_port_deref (exc);
-}
-
-#endif
+#define NOTIFY_INTRAN                                          \
+  port_info_t begin_using_port_info_port (mach_port_t)
+#define NOTIFY_DESTRUCTOR                                      \
+  end_using_port_info (port_info_t)
+#define NOTIFY_IMPORTS                                         \
+  import "libports/mig-decls.h";
diff --git a/eth-filter/Makefile b/eth-filter/Makefile
index 16f5d73..ed3286c 100644
--- a/eth-filter/Makefile
+++ b/eth-filter/Makefile
@@ -20,16 +20,13 @@ makemode := server
 
 SRCS = bpf_impl.c filter.c queue.c pcap_filter.c
 LCLHDRS = bpf_impl.h queue.h util.h
-DIST_FILES = ourdevice.defs notify.defs
 HURDLIBS = ports trivfs fshelp ihash shouldbeinlibc
 target = eth-filter
-MIGSTUBS = ourdeviceServer.o notifyServer.o
+MIGSTUBS = deviceServer.o notifyServer.o
+MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
 OBJS = $(SRCS:.c=.o) $(MIGSTUBS)
 
 include ../Makeconf
 
 #CFLAGS += -I../pfinet/linux-src/include -I../pfinet/glue-include
 LDFLAGS += -lpcap
-
-ourdevice.defs: device.defs
-       $(CPP) $(CPPFLAGS) -x c $< | sed -e '/out[      ]*device[       ]*:[    
]*device_t/s/device_t/mach_port_send_t/' > $@
diff --git a/eth-filter/filter.c b/eth-filter/filter.c
index d2b1e39..482b080 100644
--- a/eth-filter/filter.c
+++ b/eth-filter/filter.c
@@ -39,8 +39,9 @@
 #include <hurd/ports.h>
 #include <hurd/ihash.h>
 #include <hurd/fshelp.h>
+#include <version.h>
 
-#include "ourdevice_S.h"
+#include "device_S.h"
 #include "notify_S.h"
 #include "bpf_impl.h"
 #include "util.h"
@@ -73,8 +74,8 @@ static struct hurd_ihash proxy_deliverport_ht
 
 /* The name of the network interface that the filter translator sits on. */
 static char *device_file;
-const char *argp_program_version = "eth-filter 0.1";
-const char *argp_program_bug_address = "<address@hidden>";
+const char *argp_program_version = STANDARD_HURD_VERSION (eth-filter);
+
 static const char doc[] = "Hurd filter translator.";
 static const struct argp_option options[] =
 {
@@ -193,17 +194,6 @@ clean_proxy_device (void *p)
     device->proxy->device = NULL;
 }
 
-static int
-filter_demuxer (mach_msg_header_t *inp,
-               mach_msg_header_t *outp)
-{
-  extern int device_server (mach_msg_header_t *, mach_msg_header_t *);
-  extern int notify_server (mach_msg_header_t *, mach_msg_header_t *);
-  extern int ethernet_demuxer (mach_msg_header_t *, mach_msg_header_t *);
-  return device_server (inp, outp) || notify_server (inp, outp)
-    || ethernet_demuxer (inp, outp) || trivfs_demuxer (inp, outp);
-}
-
 int
 ethernet_demuxer (mach_msg_header_t *inp,
                  mach_msg_header_t *outp)
@@ -232,44 +222,62 @@ ethernet_demuxer (mach_msg_header_t *inp,
   return 1;
 }
 
+static int
+filter_demuxer (mach_msg_header_t *inp,
+               mach_msg_header_t *outp)
+{
+  mig_routine_t routine;
+  if ((routine = NULL, ethernet_demuxer (inp, outp)) ||
+      (routine = device_server_routine (inp)) ||
+      (routine = notify_server_routine (inp)) ||
+      (routine = NULL, trivfs_demuxer (inp, outp)))
+    {
+      if (routine)
+        (*routine) (inp, outp);
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
 /* Implementation of notify interface */
 kern_return_t
-do_mach_notify_port_deleted (mach_port_t notify,
+do_mach_notify_port_deleted (struct port_info *pi,
                             mach_port_t name)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-do_mach_notify_msg_accepted (mach_port_t notify,
+do_mach_notify_msg_accepted (struct port_info *pi,
                             mach_port_t name)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-do_mach_notify_port_destroyed (mach_port_t notify,
+do_mach_notify_port_destroyed (struct port_info *pi,
                               mach_port_t port)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-do_mach_notify_no_senders (mach_port_t notify,
+do_mach_notify_no_senders (struct port_info *pi,
                           mach_port_mscount_t mscount)
 {
   debug ("do_mach_notify_no_senders is called\n");
-  return ports_do_mach_notify_no_senders (notify, mscount);
+  return ports_do_mach_notify_no_senders (pi, mscount);
 }
 
 kern_return_t
-do_mach_notify_send_once (mach_port_t notify)
+do_mach_notify_send_once (struct port_info *pi)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-do_mach_notify_dead_name (mach_port_t notify,
+do_mach_notify_dead_name (struct port_info *pi,
                          mach_port_t name)
 {
   struct proxy *proxy;
@@ -287,21 +295,21 @@ do_mach_notify_dead_name (mach_port_t notify,
 
 /* Implementation of device interface */
 kern_return_t 
-ds_xxx_device_set_status (device_t device, dev_flavor_t flavor,
+ds_xxx_device_set_status (struct proxy_user *device, dev_flavor_t flavor,
                          dev_status_t status, size_t statu_cnt)
 {
   return D_INVALID_OPERATION;
 }
 
 kern_return_t
-ds_xxx_device_get_status (device_t device, dev_flavor_t flavor,
+ds_xxx_device_get_status (struct proxy_user *device, dev_flavor_t flavor,
                          dev_status_t status, size_t *statuscnt)
 {
   return D_INVALID_OPERATION;
 }
 
 kern_return_t
-ds_xxx_device_set_filter (device_t device, mach_port_t rec,
+ds_xxx_device_set_filter (struct proxy_user *device, mach_port_t rec,
                          int pri, filter_array_t filt, size_t len)
 {
   return D_INVALID_OPERATION;
@@ -348,7 +356,6 @@ ds_device_open (mach_port_t master_port, mach_port_t 
reply_port,
   err = create_proxy_user (proxy, &user_port);
   if (err)
     {
-      mach_port_deallocate (mach_task_self (), master_device);
       free (proxy);
       return err;
     }
@@ -360,13 +367,13 @@ ds_device_open (mach_port_t master_port, mach_port_t 
reply_port,
 }
 
 kern_return_t
-ds_device_close (device_t device)
+ds_device_close (struct proxy_user *device)
 {
   return 0;
 }
 
 kern_return_t
-ds_device_write (device_t device, mach_port_t reply_port,
+ds_device_write (struct proxy_user *user, mach_port_t reply_port,
                 mach_msg_type_name_t reply_type, dev_mode_t mode,
                 recnum_t recnum, io_buf_ptr_t data, size_t datalen,
                 int *bytes_written)
@@ -375,17 +382,14 @@ ds_device_write (device_t device, mach_port_t reply_port,
   int has_filter = 0;
   net_hash_entry_t entp, *hash_headp;
   net_rcv_port_t infp, nextfp;
-  struct proxy_user *user;
   struct proxy *proxy;
 
-  user = ports_lookup_port (port_bucket, device, user_portclass);
   if (user == NULL)
     {
       vm_deallocate (mach_task_self (), (vm_address_t) data, datalen);
       return D_INVALID_OPERATION;
     }
   proxy = user->proxy;
-  ports_port_deref (user);
 
   /* The packet can be sent as long as it passes one filter,
    * even thought there is usually only one filter in the list. */
@@ -421,20 +425,17 @@ ds_device_write (device_t device, mach_port_t reply_port,
 }
 
 kern_return_t
-ds_device_write_inband (device_t device, mach_port_t reply_port,
+ds_device_write_inband (struct proxy_user *user, mach_port_t reply_port,
                        mach_msg_type_name_t reply_type, dev_mode_t mode,
                        recnum_t recnum, io_buf_ptr_inband_t data,
                        size_t datalen, int *bytes_written)
 {
   kern_return_t ret;
-  struct proxy_user *user;
   struct proxy *proxy;
 
-  user = ports_lookup_port (port_bucket, device, user_portclass);
   if (user == NULL)
     return D_INVALID_OPERATION;
   proxy = user->proxy;
-  ports_port_deref (user);
 
   ret = device_write_inband (proxy->device_port, mode, recnum, data,
                             datalen, bytes_written);
@@ -442,20 +443,17 @@ ds_device_write_inband (device_t device, mach_port_t 
reply_port,
 }
 
 kern_return_t
-ds_device_read (device_t device, mach_port_t reply_port,
+ds_device_read (struct proxy_user *user, mach_port_t reply_port,
                mach_msg_type_name_t reply_type, dev_mode_t mode,
                recnum_t recnum, int bytes_wanted,
                io_buf_ptr_t *data, size_t *datalen)
 {
   kern_return_t ret;
-  struct proxy_user *user;
   struct proxy *proxy;
 
-  user = ports_lookup_port (port_bucket, device, user_portclass);
   if (user == NULL)
     return D_INVALID_OPERATION;
   proxy = user->proxy;
-  ports_port_deref (user);
 
   ret = device_read (proxy->device_port, mode, recnum,
                     bytes_wanted, data, datalen);
@@ -463,20 +461,17 @@ ds_device_read (device_t device, mach_port_t reply_port,
 }
 
 kern_return_t
-ds_device_read_inband (device_t device, mach_port_t reply_port,
+ds_device_read_inband (struct proxy_user *user, mach_port_t reply_port,
                       mach_msg_type_name_t reply_type, dev_mode_t mode,
                       recnum_t recnum, int bytes_wanted,
                       io_buf_ptr_inband_t data, size_t *datalen)
 {
   kern_return_t ret;
-  struct proxy_user *user;
   struct proxy *proxy;
 
-  user = ports_lookup_port (port_bucket, device, user_portclass);
   if (user == NULL)
     return D_INVALID_OPERATION;
   proxy = user->proxy;
-  ports_port_deref (user);
 
   ret = device_read_inband (proxy->device_port, mode, recnum, 
                            bytes_wanted, data, datalen);
@@ -484,18 +479,15 @@ ds_device_read_inband (device_t device, mach_port_t 
reply_port,
 }
 
 kern_return_t
-ds_device_map (device_t device, vm_prot_t prot, vm_offset_t offset,
+ds_device_map (struct proxy_user *user, vm_prot_t prot, vm_offset_t offset,
               vm_size_t size, memory_object_t *pager, int unmap)
 {
   kern_return_t ret;
-  struct proxy_user *user;
   struct proxy *proxy;
 
-  user = ports_lookup_port (port_bucket, device, user_portclass);
   if (user == NULL)
     return D_INVALID_OPERATION;
   proxy = user->proxy;
-  ports_port_deref (user);
 
   ret = device_map (proxy->device_port, prot, offset,
                    size, pager, unmap);
@@ -503,18 +495,15 @@ ds_device_map (device_t device, vm_prot_t prot, 
vm_offset_t offset,
 }
 
 kern_return_t
-ds_device_set_status (device_t device, dev_flavor_t flavor,
+ds_device_set_status (struct proxy_user *user, dev_flavor_t flavor,
                      dev_status_t status, size_t statuslen)
 {
   kern_return_t ret;
-  struct proxy_user *user;
   struct proxy *proxy;
 
-  user = ports_lookup_port (port_bucket, device, user_portclass);
   if (user == NULL)
     return D_INVALID_OPERATION;
   proxy = user->proxy;
-  ports_port_deref (user);
 
   ret = device_set_status (proxy->device_port, flavor,
                           status, statuslen);
@@ -522,38 +511,32 @@ ds_device_set_status (device_t device, dev_flavor_t 
flavor,
 }
 
 kern_return_t
-ds_device_get_status (device_t device, dev_flavor_t flavor,
+ds_device_get_status (struct proxy_user *user, dev_flavor_t flavor,
                      dev_status_t status, size_t *statuslen)
 {
   kern_return_t ret;
-  struct proxy_user *user;
   struct proxy *proxy;
 
-  user = ports_lookup_port (port_bucket, device, user_portclass);
   if (user == NULL)
     return D_INVALID_OPERATION;
   proxy = user->proxy;
-  ports_port_deref (user);
 
   ret = device_get_status (proxy->device_port, flavor, status, statuslen);
   return ret;
 }
 
 kern_return_t
-ds_device_set_filter (device_t device, mach_port_t receive_port,
+ds_device_set_filter (struct proxy_user *user, mach_port_t receive_port,
                      int priority, filter_array_t filter, size_t filterlen)
 {
   mach_port_t tmp;
   kern_return_t err;
   mach_port_t device_receive_port;
-  struct proxy_user *user;
   struct proxy *proxy;
 
-  user = ports_lookup_port (port_bucket, device, user_portclass);
   if (user == NULL)
     return D_INVALID_OPERATION;
   proxy = user->proxy;
-  ports_port_deref (user);
 
   if (proxy->device == NULL)
     {
diff --git a/proc/mig-decls.h b/eth-filter/mig-decls.h
similarity index 53%
copy from proc/mig-decls.h
copy to eth-filter/mig-decls.h
index 0d5bd4d..0bb29a6 100644
--- a/proc/mig-decls.h
+++ b/eth-filter/mig-decls.h
@@ -1,8 +1,6 @@
-/* Translation functions for mig.
-
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
+/*
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Justus Winter.
 
    This file is part of the GNU Hurd.
 
@@ -19,24 +17,29 @@
    You should have received a copy of the GNU General Public License
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#ifndef __MIG_DECLS_H__
-#define __MIG_DECLS_H__
+#ifndef __ETH_FILTER_MIG_DECLS_H__
+#define __ETH_FILTER_MIG_DECLS_H__
+
+#include <hurd/ports.h>
+
+typedef struct proxy_user *proxy_user_t;
 
-#include "proc.h"
+extern struct port_bucket *port_bucket;
+extern struct port_class *user_portclass;
 
-typedef struct exc* exc_t;
+/* Called by server stub functions.  */
 
-static inline exc_t __attribute__ ((unused))
-begin_using_exc_port (mach_port_t port)
+static inline struct proxy_user * __attribute__ ((unused))
+begin_using_device_port (mach_port_t port)
 {
-  return ports_lookup_port (NULL, port, exc_class);
+  return ports_lookup_port (port_bucket, port, user_portclass);
 }
 
 static inline void __attribute__ ((unused))
-end_using_exc (exc_t exc)
+end_using_device (struct proxy_user *p)
 {
-  if (exc != NULL)
-    ports_port_deref (exc);
+  if (p)
+    ports_port_deref (p);
 }
 
-#endif
+#endif /* __ETH_FILTER_MIG_DECLS_H__ */
diff --git a/proc/mig-decls.h b/eth-filter/mig-mutate.h
similarity index 56%
copy from proc/mig-decls.h
copy to eth-filter/mig-mutate.h
index 0d5bd4d..388ce09 100644
--- a/proc/mig-decls.h
+++ b/eth-filter/mig-mutate.h
@@ -1,8 +1,6 @@
-/* Translation functions for mig.
-
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
+/*
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Justus Winter.
 
    This file is part of the GNU Hurd.
 
@@ -19,24 +17,16 @@
    You should have received a copy of the GNU General Public License
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#ifndef __MIG_DECLS_H__
-#define __MIG_DECLS_H__
-
-#include "proc.h"
-
-typedef struct exc* exc_t;
-
-static inline exc_t __attribute__ ((unused))
-begin_using_exc_port (mach_port_t port)
-{
-  return ports_lookup_port (NULL, port, exc_class);
-}
-
-static inline void __attribute__ ((unused))
-end_using_exc (exc_t exc)
-{
-  if (exc != NULL)
-    ports_port_deref (exc);
-}
-
-#endif
+#define NOTIFY_INTRAN                                          \
+  port_info_t begin_using_port_info_port (mach_port_t)
+#define NOTIFY_DESTRUCTOR                                      \
+  end_using_port_info (port_info_t)
+#define NOTIFY_IMPORTS                                         \
+  import "libports/mig-decls.h";
+
+#define DEVICE_INTRAN                                          \
+  proxy_user_t begin_using_device_port (mach_port_t)
+#define DEVICE_DESTRUCTOR                                      \
+  end_using_device (proxy_user_t)
+#define DEVICE_IMPORTS                                         \
+  import "eth-filter/mig-decls.h";
diff --git a/eth-multiplexer/Makefile b/eth-multiplexer/Makefile
index a96619c..fbee1ca 100644
--- a/eth-multiplexer/Makefile
+++ b/eth-multiplexer/Makefile
@@ -21,17 +21,13 @@ target = eth-multiplexer
 
 #CFLAGS += -DDEBUG
 SRCS = ethernet.c vdev.c multiplexer.c dev_stat.c netfs_impl.c notify_impl.c 
device_impl.c demuxer.c
-MIGSTUBS = ourdeviceServer.o notifyServer.o
+MIGSTUBS = deviceServer.o notifyServer.o
+MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
 OBJS = $(SRCS:.c=.o) $(MIGSTUBS)
 LCLHDRS = ethernet.h util.h vdev.h netfs_impl.h
-DIST_FILES = ourdevice.defs notify.defs
 HURDLIBS=ports fshelp shouldbeinlibc netfs bpf
 OTHERLIBS = -lpthread
 
 CFLAGS += -I$(top_srcdir)/libbpf
 
 include ../Makeconf
-
-ourdevice.defs: device.defs
-       $(CPP) $(CPPFLAGS) -x c $< | sed -e '/out[      ]*device[       ]*:[    
]*device_t/s/device_t/mach_port_send_t/' > $@
-
diff --git a/eth-multiplexer/device_impl.c b/eth-multiplexer/device_impl.c
index 459d9c4..35a4da4 100644
--- a/eth-multiplexer/device_impl.c
+++ b/eth-multiplexer/device_impl.c
@@ -27,7 +27,7 @@
 
 #include "ethernet.h"
 #include "vdev.h"
-#include "ourdevice_S.h"
+#include "device_S.h"
 #include "notify_S.h"
 #include "bpf_impl.h"
 #include "netfs_impl.h"
@@ -40,38 +40,29 @@ extern struct port_info *notify_pi;
 
 /* Implementation of device interface */
 kern_return_t
-ds_xxx_device_set_status (device_t device, dev_flavor_t flavor,
+ds_xxx_device_set_status (struct vether_device *vdev, dev_flavor_t flavor,
                          dev_status_t status, size_t statu_cnt)
 {
-  struct vether_device *vdev = ports_lookup_port (port_bucket, device,
-                                                 vdev_portclass);
   if (vdev == NULL)
     return D_NO_SUCH_DEVICE;
-  ports_port_deref (vdev);
   return D_INVALID_OPERATION;
 }
 
 kern_return_t
-ds_xxx_device_get_status (device_t device, dev_flavor_t flavor,
+ds_xxx_device_get_status (struct vether_device *vdev, dev_flavor_t flavor,
                          dev_status_t status, size_t *statuscnt)
 {
-  struct vether_device *vdev = ports_lookup_port (port_bucket, device,
-                                                 vdev_portclass);
   if (vdev == NULL)
     return D_NO_SUCH_DEVICE;
-  ports_port_deref (vdev);
   return D_INVALID_OPERATION;
 }
 
 kern_return_t
-ds_xxx_device_set_filter (device_t device, mach_port_t rec,
+ds_xxx_device_set_filter (struct vether_device *vdev, mach_port_t rec,
                          int pri, filter_array_t filt, size_t len)
 {
-  struct vether_device *vdev = ports_lookup_port (port_bucket, device,
-                                                 vdev_portclass);
   if (vdev == NULL)
     return D_NO_SUCH_DEVICE;
-  ports_port_deref (vdev);
   return D_INVALID_OPERATION;
 }
 
@@ -140,20 +131,18 @@ ds_device_open (mach_port_t master_port, mach_port_t 
reply_port,
 }
 
 kern_return_t
-ds_device_close (device_t device)
+ds_device_close (struct vether_device *device)
 {
   return 0;
 }
 
 kern_return_t
-ds_device_write (device_t device, mach_port_t reply_port,
+ds_device_write (struct vether_device *vdev, mach_port_t reply_port,
                 mach_msg_type_name_t reply_type, dev_mode_t mode,
                 recnum_t recnum, io_buf_ptr_t data, size_t datalen,
                 int *bytes_written)
 {
   kern_return_t ret = 0;
-  struct vether_device *vdev = ports_lookup_port (port_bucket, device,
-                                                 vdev_portclass);
   if (vdev == NULL)
     {
       vm_deallocate (mach_task_self (), (vm_address_t) data, datalen);
@@ -169,103 +158,82 @@ ds_device_write (device_t device, mach_port_t reply_port,
   /* The data in device_write() is transmifered out of line,
    * so the server-side function has to deallocate it. */
   vm_deallocate (mach_task_self (), (vm_address_t) data, datalen);
-  ports_port_deref (vdev);
   return ret;
 }
 
 kern_return_t
-ds_device_write_inband (device_t device, mach_port_t reply_port,
+ds_device_write_inband (struct vether_device *vdev, mach_port_t reply_port,
                        mach_msg_type_name_t reply_type, dev_mode_t mode,
                        recnum_t recnum, io_buf_ptr_inband_t data,
                        size_t datalen, int *bytes_written)
 {
-  struct vether_device *vdev = ports_lookup_port (port_bucket, device,
-                                                 vdev_portclass);
   if (vdev == NULL)
     return D_NO_SUCH_DEVICE;
-  ports_port_deref (vdev);
   return D_INVALID_OPERATION;
 }
 
 kern_return_t
-ds_device_read (device_t device, mach_port_t reply_port,
+ds_device_read (struct vether_device *vdev, mach_port_t reply_port,
                mach_msg_type_name_t reply_type, dev_mode_t mode,
                recnum_t recnum, int bytes_wanted,
                io_buf_ptr_t *data, size_t *datalen)
 {
-  struct vether_device *vdev = ports_lookup_port (port_bucket, device,
-                                                 vdev_portclass);
   if (vdev == NULL)
     return D_NO_SUCH_DEVICE;
-  ports_port_deref (vdev);
   return D_INVALID_OPERATION;
 }
 
 kern_return_t
-ds_device_read_inband (device_t device, mach_port_t reply_port,
+ds_device_read_inband (struct vether_device *vdev, mach_port_t reply_port,
                       mach_msg_type_name_t reply_type, dev_mode_t mode,
                       recnum_t recnum, int bytes_wanted,
                       io_buf_ptr_inband_t data, size_t *datalen)
 {
-  struct vether_device *vdev = ports_lookup_port (port_bucket, device,
-                                                 vdev_portclass);
   if (vdev == NULL)
     return D_NO_SUCH_DEVICE;
-  ports_port_deref (vdev);
   return D_INVALID_OPERATION;
 }
 
 kern_return_t
-ds_device_map (device_t device, vm_prot_t prot, vm_offset_t offset,
+ds_device_map (struct vether_device *vdev, vm_prot_t prot, vm_offset_t offset,
               vm_size_t size, memory_object_t *pager, int unmap)
 {
-  struct vether_device *vdev = ports_lookup_port (port_bucket, device,
-                                                 vdev_portclass);
   if (vdev == NULL)
     return D_NO_SUCH_DEVICE;
-  ports_port_deref (vdev);
   return D_INVALID_OPERATION;
 }
 
 kern_return_t
-ds_device_set_status (device_t device, dev_flavor_t flavor,
+ds_device_set_status (struct vether_device *vdev, dev_flavor_t flavor,
                      dev_status_t status, size_t statuslen)
 {
-  struct vether_device *vdev = ports_lookup_port (port_bucket, device,
-                                                 vdev_portclass);
   if (vdev == NULL)
     return D_NO_SUCH_DEVICE;
-  ports_port_deref (vdev);
   return D_INVALID_OPERATION;
 }
 
 kern_return_t
-ds_device_get_status (device_t device, dev_flavor_t flavor,
+ds_device_get_status (struct vether_device *vdev, dev_flavor_t flavor,
                      dev_status_t status, size_t *statuslen)
 {
   extern io_return_t dev_getstat (struct vether_device *, dev_flavor_t,
                                  dev_status_t, natural_t *);
   kern_return_t ret = 0;
-  struct vether_device *vdev = ports_lookup_port (port_bucket, device,
-                                                 vdev_portclass);
   if (vdev == NULL)
     return D_NO_SUCH_DEVICE;
   if(ether_port != MACH_PORT_NULL)
     ret = device_get_status (ether_port, flavor, status, statuslen);
   else 
     ret = dev_getstat (vdev, flavor, status, statuslen);
-  ports_port_deref (vdev);
   return ret;
 }
 
 kern_return_t
-ds_device_set_filter (device_t device, mach_port_t receive_port,
+ds_device_set_filter (struct vether_device *vdev, mach_port_t receive_port,
                      int priority, filter_array_t filter, size_t filterlen)
 {
   mach_port_t tmp;
   kern_return_t err;
-  struct vether_device *vdev = ports_lookup_port (port_bucket, device,
-                                                 vdev_portclass);
   if (vdev == NULL)
     return D_NO_SUCH_DEVICE;
   err = mach_port_request_notification (mach_task_self (), receive_port, 
@@ -279,6 +247,5 @@ ds_device_set_filter (device_t device, mach_port_t 
receive_port,
   err = net_set_filter (&vdev->port_list, receive_port,
                        priority, filter, filterlen);
 out:
-  ports_port_deref (vdev);
   return err;
 }
diff --git a/proc/mig-decls.h b/eth-multiplexer/mig-decls.h
similarity index 52%
copy from proc/mig-decls.h
copy to eth-multiplexer/mig-decls.h
index 0d5bd4d..a68e2ec 100644
--- a/proc/mig-decls.h
+++ b/eth-multiplexer/mig-decls.h
@@ -1,8 +1,6 @@
-/* Translation functions for mig.
-
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
+/*
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Justus Winter.
 
    This file is part of the GNU Hurd.
 
@@ -19,24 +17,29 @@
    You should have received a copy of the GNU General Public License
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#ifndef __MIG_DECLS_H__
-#define __MIG_DECLS_H__
+#ifndef __ETH_MULTIPLEXER_MIG_DECLS_H__
+#define __ETH_MULTIPLEXER_MIG_DECLS_H__
+
+#include <hurd/ports.h>
+
+typedef struct vether_device *vether_device_t;
 
-#include "proc.h"
+extern struct port_bucket *port_bucket;
+extern struct port_class *vdev_portclass;
 
-typedef struct exc* exc_t;
+/* Called by server stub functions.  */
 
-static inline exc_t __attribute__ ((unused))
-begin_using_exc_port (mach_port_t port)
+static inline struct vether_device * __attribute__ ((unused))
+begin_using_device_port (mach_port_t port)
 {
-  return ports_lookup_port (NULL, port, exc_class);
+  return ports_lookup_port (port_bucket, port, vdev_portclass);
 }
 
 static inline void __attribute__ ((unused))
-end_using_exc (exc_t exc)
+end_using_device (struct vether_device *p)
 {
-  if (exc != NULL)
-    ports_port_deref (exc);
+  if (p)
+    ports_port_deref (p);
 }
 
-#endif
+#endif /* __ETH_MULTIPLEXER_MIG_DECLS_H__ */
diff --git a/proc/mig-decls.h b/eth-multiplexer/mig-mutate.h
similarity index 56%
copy from proc/mig-decls.h
copy to eth-multiplexer/mig-mutate.h
index 0d5bd4d..2403c29 100644
--- a/proc/mig-decls.h
+++ b/eth-multiplexer/mig-mutate.h
@@ -1,8 +1,6 @@
-/* Translation functions for mig.
-
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
+/*
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Justus Winter.
 
    This file is part of the GNU Hurd.
 
@@ -19,24 +17,16 @@
    You should have received a copy of the GNU General Public License
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#ifndef __MIG_DECLS_H__
-#define __MIG_DECLS_H__
-
-#include "proc.h"
-
-typedef struct exc* exc_t;
-
-static inline exc_t __attribute__ ((unused))
-begin_using_exc_port (mach_port_t port)
-{
-  return ports_lookup_port (NULL, port, exc_class);
-}
-
-static inline void __attribute__ ((unused))
-end_using_exc (exc_t exc)
-{
-  if (exc != NULL)
-    ports_port_deref (exc);
-}
-
-#endif
+#define NOTIFY_INTRAN                                          \
+  port_info_t begin_using_port_info_port (mach_port_t)
+#define NOTIFY_DESTRUCTOR                                      \
+  end_using_port_info (port_info_t)
+#define NOTIFY_IMPORTS                                         \
+  import "libports/mig-decls.h";
+
+#define DEVICE_INTRAN                                          \
+  vether_device_t begin_using_device_port (mach_port_t)
+#define DEVICE_DESTRUCTOR                                      \
+  end_using_device (vether_device_t)
+#define DEVICE_IMPORTS                                         \
+  import "eth-multiplexer/mig-decls.h";
diff --git a/eth-multiplexer/multiplexer.c b/eth-multiplexer/multiplexer.c
index 87578ec..cc0024e 100644
--- a/eth-multiplexer/multiplexer.c
+++ b/eth-multiplexer/multiplexer.c
@@ -39,10 +39,11 @@
 #include <device/device.h>
 #include <hurd/ports.h>
 #include <hurd/netfs.h>
+#include <version.h>
 
 #include "ethernet.h"
 #include "vdev.h"
-#include "ourdevice_S.h"
+#include "device_S.h"
 #include "notify_S.h"
 #include "bpf_impl.h"
 #include "netfs_impl.h"
@@ -51,8 +52,8 @@
 /* The device which the multiplexer connects to */
 static char *device_file;
 
-const char *argp_program_version = "eth-multiplexer 0.1";
-const char *argp_program_bug_address = "<address@hidden>";
+const char *argp_program_version = STANDARD_HURD_VERSION (eth-multiplexer);
+
 static const char doc[] = "Hurd multiplexer server.";
 static const struct argp_option options[] =
 {
@@ -78,12 +79,17 @@ static int
 multiplexer_demuxer (mach_msg_header_t *inp,
                  mach_msg_header_t *outp)
 {
-  int device_server (mach_msg_header_t *, mach_msg_header_t *);
-  int notify_server (mach_msg_header_t *, mach_msg_header_t *);
-
-  return (device_server (inp, outp)
-          || notify_server (inp, outp)
-          || ethernet_demuxer (inp, outp));
+  mig_routine_t routine;
+  if ((routine = NULL, ethernet_demuxer (inp, outp)) ||
+      (routine = device_server_routine (inp)) ||
+      (routine = notify_server_routine (inp)))
+    {
+      if (routine)
+        (*routine) (inp, outp);
+      return TRUE;
+    }
+  else
+    return FALSE;
 }
 
 static void *
diff --git a/eth-multiplexer/notify_impl.c b/eth-multiplexer/notify_impl.c
index 33725bb..947069f 100644
--- a/eth-multiplexer/notify_impl.c
+++ b/eth-multiplexer/notify_impl.c
@@ -25,41 +25,41 @@
 
 /* Implementation of notify interface */
 kern_return_t
-do_mach_notify_port_deleted (mach_port_t notify,
+do_mach_notify_port_deleted (struct port_info *pi,
                             mach_port_t name)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-do_mach_notify_msg_accepted (mach_port_t notify,
+do_mach_notify_msg_accepted (struct port_info *pi,
                             mach_port_t name)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-do_mach_notify_port_destroyed (mach_port_t notify,
+do_mach_notify_port_destroyed (struct port_info *pi,
                               mach_port_t port)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-do_mach_notify_no_senders (mach_port_t notify,
+do_mach_notify_no_senders (struct port_info *pi,
                           mach_port_mscount_t mscount)
 {
-  return ports_do_mach_notify_no_senders (notify, mscount);
+  return ports_do_mach_notify_no_senders (pi, mscount);
 }
 
 kern_return_t
-do_mach_notify_send_once (mach_port_t notify)
+do_mach_notify_send_once (struct port_info *pi)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-do_mach_notify_dead_name (mach_port_t notify,
+do_mach_notify_dead_name (struct port_info *pi,
                          mach_port_t name)
 {
   debug ("do_mach_notify_dead_name is called\n");
diff --git a/exec/Makefile b/exec/Makefile
index 3ef742d..d332f36 100644
--- a/exec/Makefile
+++ b/exec/Makefile
@@ -30,6 +30,7 @@ HURDLIBS = trivfs fshelp iohelp ports ihash shouldbeinlibc
 OTHERLIBS = -lpthread
 
 exec-MIGSFLAGS = -imacros $(srcdir)/execmutations.h
+exec_startup-MIGSFLAGS = -imacros $(srcdir)/execmutations.h
 
 include ../Makeconf
 
diff --git a/exec/exec.c b/exec/exec.c
index e693f63..b068f5e 100644
--- a/exec/exec.c
+++ b/exec/exec.c
@@ -1168,9 +1168,20 @@ do_exec (file_t file,
        goto out;
 
       char *name;
-      if (asprintf (&name, "%s(%d)", argv, pid) > 0)
+      int size = asprintf (&name, "%s(%d)", argv, pid);
+      if (size > 0)
        {
-         task_set_name (newtask, name);
+/* This is an internal implementational detail of the gnumach kernel.  */
+#define TASK_NAME_SIZE 32
+         if (size < TASK_NAME_SIZE)
+           task_set_name (newtask, name);
+         else
+           {
+             char *abbr = name + size - TASK_NAME_SIZE + 1;
+             abbr[0] = abbr[1] = abbr[2] = '.';
+             task_set_name (newtask, abbr);
+           }
+#undef TASK_NAME_SIZE
          free (name);
        }
     }
@@ -1457,7 +1468,7 @@ S_exec_setexecdata (struct trivfs_protid *protid,
 /* RPC sent on the bootstrap port.  */
 
 kern_return_t
-S_exec_startup_get_info (mach_port_t port,
+S_exec_startup_get_info (struct bootinfo *boot,
                         vm_address_t *user_entry,
                         vm_address_t *phdr_data, vm_size_t *phdr_size,
                         vm_address_t *stack_base, vm_size_t *stack_size,
@@ -1472,11 +1483,8 @@ S_exec_startup_get_info (mach_port_t port,
                         mach_msg_type_number_t *nports,
                         int **intarray, mach_msg_type_number_t *nints)
 {
-  struct bootinfo *boot = ports_lookup_port (port_bucket, port,
-                                            execboot_portclass);
   if (! boot)
     return EOPNOTSUPP;
-  ports_port_deref (boot);
 
   /* Pass back all the information we are storing.  */
 
diff --git a/exec/execmutations.h b/exec/execmutations.h
index ffcba9c..2acca7a 100644
--- a/exec/execmutations.h
+++ b/exec/execmutations.h
@@ -7,4 +7,12 @@
   import "priv.h";                                     \
   import "../libtrivfs/mig-decls.h";                   \
 
+#define EXEC_STARTUP_INTRAN                             \
+  bootinfo_t begin_using_bootinfo_port (exec_startup_t)
+#define EXEC_STARTUP_DESTRUCTOR                         \
+  end_using_bootinfo (bootinfo_t)
+#define EXEC_STARTUP_IMPORTS                            \
+  import "priv.h";                                      \
+  import "mig-decls.h";
+
 #define SERVERCOPY 1
diff --git a/console/priv.h b/exec/mig-decls.h
similarity index 51%
rename from console/priv.h
rename to exec/mig-decls.h
index fdb96e7..0437414 100644
--- a/console/priv.h
+++ b/exec/mig-decls.h
@@ -1,7 +1,6 @@
 /*
-   Copyright (C) 1995, 1996, 2001, 2007 Free Software Foundation, Inc.
-
-   Written by Michael I. Bushnell, p/BSG.
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Justus Winter.
 
    This file is part of the GNU Hurd.
 
@@ -16,26 +15,26 @@
    General Public License for more details.
 
    You should have received a copy of the GNU General Public License
-   along with this program; if not, write to the Free Software
-   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
+   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#ifndef _CONSOLE_PRIV_H
-#define _CONSOLE_PRIV_H
+#ifndef __EXEC_MIG_DECLS_H__
+#define __EXEC_MIG_DECLS_H__
 
-#include <hurd/hurd_types.h>
+#include "priv.h"
 
-#include <hurd/netfs.h>
+/* Called by server stub functions.  */
 
-static inline struct protid * __attribute__ ((unused))
-begin_using_protid_port (file_t port)
+static inline struct bootinfo * __attribute__ ((unused))
+begin_using_bootinfo_port (mach_port_t port)
 {
-  return ports_lookup_port (netfs_port_bucket, port, netfs_protid_class);
+    return ports_lookup_port (port_bucket, port, execboot_portclass);
 }
 
 static inline void __attribute__ ((unused))
-end_using_protid_port (struct protid *cred)
+end_using_bootinfo (struct bootinfo *b)
 {
-  if (cred)
-    ports_port_deref (cred);
+  if (b)
+    ports_port_deref (b);
 }
-#endif
+
+#endif /* __EXEC_MIG_DECLS_H__ */
diff --git a/exec/priv.h b/exec/priv.h
index 85e03ae..733f35c 100644
--- a/exec/priv.h
+++ b/exec/priv.h
@@ -52,6 +52,7 @@ struct bootinfo
     vm_address_t phdr_addr, user_entry;
     vm_size_t phdr_size;
   };
+typedef struct bootinfo *bootinfo_t;
 
 
 /* Where to put the service ports. */
@@ -151,5 +152,4 @@ extern int *std_ints;
 extern size_t std_nports, std_nints;
 extern pthread_rwlock_t std_lock;
 
-
 #endif /* exec_priv_h */
diff --git a/ext2fs/ext2fs.h b/ext2fs/ext2fs.h
index e01d1a5..3422af2 100644
--- a/ext2fs/ext2fs.h
+++ b/ext2fs/ext2fs.h
@@ -297,10 +297,14 @@ unsigned log2_stat_blocks_per_fs_block;
 /* A handy page of page-aligned zeros.  */
 vm_address_t zeroblock;
 
-/* Get the superblock from the disk, & setup various global info from it.  */
+/* Get the superblock from the disk, point `sblock' to it, and setup
+   various global info from it.  */
 void get_hypermetadata ();
 
-/* Map `sblock' and `group_desc_image' pointers to disk cache.  */
+/* Map `group_desc_image' pointers to disk cache.  Also, establish a
+   non-exported mapping to the superblock that will be used by
+   diskfs_set_hypermetadata to update the superblock from the cache
+   `sblock' points to.  */
 void map_hypermetadata ();
 
 /* ---------------------------------------------------------------- */
diff --git a/ext2fs/hyper.c b/ext2fs/hyper.c
index 5bcc2ab..5f288bf 100644
--- a/ext2fs/hyper.c
+++ b/ext2fs/hyper.c
@@ -61,7 +61,9 @@ get_hypermetadata (void)
   error_t err;
   size_t read = 0;
 
-  assert (! sblock);
+  if (sblock != NULL)
+    munmap (sblock, SBLOCK_SIZE);
+
   err = store_read (store, SBLOCK_OFFS >> store->log2_block_size,
                    SBLOCK_SIZE, (void **)&sblock, &read);
   if (err || read != SBLOCK_SIZE)
@@ -161,19 +163,19 @@ get_hypermetadata (void)
       zeroblock = (vm_address_t) mmap (0, block_size, PROT_READ, MAP_ANON, 0, 
0);
       assert (zeroblock != (vm_address_t) MAP_FAILED);
     }
-
-  munmap (sblock, SBLOCK_SIZE);
-  sblock = NULL;
 }
 
+static struct ext2_super_block *mapped_sblock;
+
 void
 map_hypermetadata (void)
 {
-  sblock = (struct ext2_super_block *) boffs_ptr (SBLOCK_OFFS);
+  mapped_sblock = (struct ext2_super_block *) boffs_ptr (SBLOCK_OFFS);
 
   /* Cache a convenient pointer to the block group descriptors for allocation.
      These are stored in the filesystem blocks following the superblock.  */
-  group_desc_image = (struct ext2_group_desc *) bptr (bptr_block (sblock) + 1);
+  group_desc_image =
+    (struct ext2_group_desc *) bptr (bptr_block (mapped_sblock) + 1);
 }
 
 error_t
@@ -196,8 +198,9 @@ diskfs_set_hypermetadata (int wait, int clean)
  if (sblock_dirty)
    {
      sblock_dirty = 0;
-     disk_cache_block_ref_ptr (sblock);
-     record_global_poke (sblock);
+     memcpy (mapped_sblock, sblock, SBLOCK_SIZE);
+     disk_cache_block_ref_ptr (mapped_sblock);
+     record_global_poke (mapped_sblock);
    }
 
   sync_global (wait);
diff --git a/ext2fs/ialloc.c b/ext2fs/ialloc.c
index 2d8e51e..52212d5 100644
--- a/ext2fs/ialloc.c
+++ b/ext2fs/ialloc.c
@@ -115,7 +115,8 @@ ino_t
 ext2_alloc_inode (ino_t dir_inum, mode_t mode)
 {
   char *bh = NULL;
-  int i, j, inum, avefreei;
+  int i, j, avefreei;
+  ino_t inum;
   struct ext2_group_desc *gdp;
   struct ext2_group_desc *tmp;
 
diff --git a/ext2fs/inode.c b/ext2fs/inode.c
index e75c63f..ed78265 100644
--- a/ext2fs/inode.c
+++ b/ext2fs/inode.c
@@ -47,6 +47,7 @@
 #endif
 
 static struct node *nodehash[INOHSZ];
+static size_t nodehash_nr_items;
 
 static error_t read_node (struct node *np);
 
@@ -106,6 +107,7 @@ diskfs_cached_lookup (ino_t inum, struct node **npp)
     dn->hnext->dn->hprevp = &dn->hnext;
   dn->hprevp = &nodehash[INOHASH(inum)];
   nodehash[INOHASH(inum)] = np;
+  nodehash_nr_items += 1;
 
   pthread_spin_unlock (&diskfs_node_refcnt_lock);
 
@@ -159,6 +161,7 @@ diskfs_node_norefs (struct node *np)
   *np->dn->hprevp = np->dn->hnext;
   if (np->dn->hnext)
     np->dn->hnext->dn->hprevp = np->dn->hprevp;
+  nodehash_nr_items -= 1;
 
   if (np->dn->dirents)
     free (np->dn->dirents);
@@ -549,7 +552,8 @@ error_t
 diskfs_node_iterate (error_t (*fun)(struct node *))
 {
   error_t err = 0;
-  int n, num_nodes = 0;
+  int n;
+  size_t num_nodes;
   struct node *node, **node_list, **p;
 
   pthread_spin_lock (&diskfs_node_refcnt_lock);
@@ -559,10 +563,7 @@ diskfs_node_iterate (error_t (*fun)(struct node *))
      during processing (normally we delegate access to hash-table with
      diskfs_node_refcnt_lock, but we can't hold this while locking the
      individual node locks).  */
-
-  for (n = 0; n < INOHSZ; n++)
-    for (node = nodehash[n]; node; node = node->dn->hnext)
-      num_nodes++;
+  num_nodes = nodehash_nr_items;
 
   /* TODO This method doesn't scale beyond a few dozen nodes and should be
      replaced.  */
diff --git a/ext2fs/pager.c b/ext2fs/pager.c
index 6e99c83..017efcc 100644
--- a/ext2fs/pager.c
+++ b/ext2fs/pager.c
@@ -21,14 +21,18 @@
 #include <unistd.h>
 #include <string.h>
 #include <errno.h>
+#include <error.h>
 #include <hurd/store.h>
 #include "ext2fs.h"
 
 /* XXX */
 #include "../libpager/priv.h"
 
-/* A ports bucket to hold pager ports.  */
-struct port_bucket *pager_bucket;
+/* A ports bucket to hold disk pager ports.  */
+struct port_bucket *disk_pager_bucket;
+
+/* A ports bucket to hold file pager ports.  */
+struct port_bucket *file_pager_bucket;
 
 pthread_spinlock_t node_to_page_lock = PTHREAD_SPINLOCK_INITIALIZER;
 
@@ -1188,21 +1192,56 @@ disk_cache_block_is_ref (block_t block)
   return ref;
 }
 
-/* Create the DISK pager.  */
+/* A top-level function for the paging thread that just services paging
+   requests.  */
+static void *
+service_paging_requests (void *arg)
+{
+  struct port_bucket *pager_bucket = arg;
+  ports_manage_port_operations_multithread (pager_bucket,
+                                           pager_demuxer,
+                                           1000,
+                                           0,
+                                           NULL);
+  /* Not reached.  */
+  return NULL;
+}
+
+/* Create the disk pager, and the file pager.  */
 void
 create_disk_pager (void)
 {
+  pthread_t thread;
+  pthread_attr_t attr;
+  error_t err;
+
+  /* The disk pager.  */
   struct user_pager_info *upi = malloc (sizeof (struct user_pager_info));
   if (!upi)
     ext2_panic ("can't create disk pager: %s", strerror (errno));
   upi->type = DISK;
-  pager_bucket = ports_create_bucket ();
+  disk_pager_bucket = ports_create_bucket ();
   get_hypermetadata ();
   disk_cache_blocks = DISK_CACHE_BLOCKS;
   disk_cache_size = disk_cache_blocks << log2_block_size;
-  diskfs_start_disk_pager (upi, pager_bucket, MAY_CACHE, 1,
+  diskfs_start_disk_pager (upi, disk_pager_bucket, MAY_CACHE, 1,
                           disk_cache_size, &disk_cache);
   disk_cache_init ();
+
+  /* The file pager.  */
+  file_pager_bucket = ports_create_bucket ();
+
+#define STACK_SIZE (64 * 1024)
+  pthread_attr_init (&attr);
+  pthread_attr_setstacksize (&attr, STACK_SIZE);
+#undef STACK_SIZE
+
+  /* Make a thread to service file paging requests.  */
+  err = pthread_create (&thread, &attr,
+                       service_paging_requests, file_pager_bucket);
+  if (err)
+    error (2, err, "pthread_create");
+  pthread_detach (thread);
 }
 
 /* Call this to create a FILE_DATA pager and return a send right.
@@ -1241,7 +1280,7 @@ diskfs_get_filemap (struct node *node, vm_prot_t prot)
          upi->max_prot = prot;
          diskfs_nref_light (node);
          node->dn->pager =
-           pager_create (upi, pager_bucket, MAY_CACHE,
+           pager_create (upi, file_pager_bucket, MAY_CACHE,
                          MEMORY_OBJECT_COPY_DELAY, 0);
          if (node->dn->pager == 0)
            {
@@ -1324,14 +1363,13 @@ diskfs_shutdown_pager ()
   error_t shutdown_one (void *v_p)
     {
       struct pager *p = v_p;
-      if (p != diskfs_disk_pager)
-       pager_shutdown (p);
+      pager_shutdown (p);
       return 0;
     }
 
   write_all_disknodes ();
 
-  ports_bucket_iterate (pager_bucket, shutdown_one);
+  ports_bucket_iterate (file_pager_bucket, shutdown_one);
 
   /* Sync everything on the the disk pager.  */
   sync_global (1);
@@ -1347,13 +1385,12 @@ diskfs_sync_everything (int wait)
   error_t sync_one (void *v_p)
     {
       struct pager *p = v_p;
-      if (p != diskfs_disk_pager)
-       pager_sync (p, wait);
+      pager_sync (p, wait);
       return 0;
     }
 
   write_all_disknodes ();
-  ports_bucket_iterate (pager_bucket, sync_one);
+  ports_bucket_iterate (file_pager_bucket, sync_one);
 
   /* Do things on the the disk pager.  */
   sync_global (wait);
@@ -1372,7 +1409,8 @@ disable_caching ()
 
   /* Loop through the pagers and turn off caching one by one,
      synchronously.  That should cause termination of each pager. */
-  ports_bucket_iterate (pager_bucket, block_cache);
+  ports_bucket_iterate (disk_pager_bucket, block_cache);
+  ports_bucket_iterate (file_pager_bucket, block_cache);
 }
 
 static void
@@ -1400,7 +1438,8 @@ enable_caching ()
       return 0;
     }
 
-  ports_bucket_iterate (pager_bucket, enable_cache);
+  ports_bucket_iterate (disk_pager_bucket, enable_cache);
+  ports_bucket_iterate (file_pager_bucket, enable_cache);
 }
 
 /* Tell diskfs if there are pagers exported, and if none, then
@@ -1408,7 +1447,7 @@ enable_caching ()
 int
 diskfs_pager_users ()
 {
-  int npagers = ports_count_bucket (pager_bucket);
+  int npagers = ports_count_bucket (file_pager_bucket);
 
   if (npagers <= 1)
     return 0;
@@ -1421,8 +1460,8 @@ diskfs_pager_users ()
         immediately.  XXX */
       sleep (1);
 
-      npagers = ports_count_bucket (pager_bucket);
-      if (npagers <= 1)
+      npagers = ports_count_bucket (file_pager_bucket);
+      if (npagers == 0)
        return 0;
 
       /* Darn, there are actual honest users.  Turn caching back on,
@@ -1430,7 +1469,7 @@ diskfs_pager_users ()
       enable_caching ();
     }
 
-  ports_enable_bucket (pager_bucket);
+  ports_enable_bucket (file_pager_bucket);
 
   return 1;
 }
@@ -1441,20 +1480,17 @@ vm_prot_t
 diskfs_max_user_pager_prot ()
 {
   vm_prot_t max_prot = 0;
-  int npagers = ports_count_bucket (pager_bucket);
+  int npagers = ports_count_bucket (file_pager_bucket);
 
-  if (npagers > 1)
-    /* More than just the disk pager.  */
+  if (npagers > 0)
     {
       error_t add_pager_max_prot (void *v_p)
        {
          struct pager *p = v_p;
          struct user_pager_info *upi = pager_get_upi (p);
-         if (upi->type == FILE_DATA)
-           max_prot |= upi->max_prot;
+         max_prot |= upi->max_prot;
          /* Stop iterating if MAX_PROT is as filled as it's going to get. */
-         return
-           (max_prot == (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE)) ? 1 : 0;
+         return max_prot == (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
        }
 
       disable_caching ();              /* Make any silly pagers go away. */
@@ -1463,12 +1499,12 @@ diskfs_max_user_pager_prot ()
         immediately.  XXX */
       sleep (1);
 
-      ports_bucket_iterate (pager_bucket, add_pager_max_prot);
+      ports_bucket_iterate (file_pager_bucket, add_pager_max_prot);
 
       enable_caching ();
     }
 
-  ports_enable_bucket (pager_bucket);
+  ports_enable_bucket (file_pager_bucket);
 
   return max_prot;
 }
diff --git a/ext2fs/storeinfo.c b/ext2fs/storeinfo.c
index 5d21b05..d9a2be8 100644
--- a/ext2fs/storeinfo.c
+++ b/ext2fs/storeinfo.c
@@ -22,6 +22,7 @@
 #include <hurd/store.h>
 
 #include "ext2fs.h"
+#include "libdiskfs/fs_S.h"
 
 error_t
 diskfs_S_file_get_storage_info (struct protid *cred,
diff --git a/fatfs/inode.c b/fatfs/inode.c
index e3ca09d..ed6f3f0 100644
--- a/fatfs/inode.c
+++ b/fatfs/inode.c
@@ -23,6 +23,7 @@
 
 #include <string.h>
 #include "fatfs.h"
+#include "libdiskfs/fs_S.h"
 
 /* These flags aren't actually defined by a header file yet, so
    temporarily disable them if necessary.  */
@@ -44,6 +45,7 @@
 #endif
 
 static struct node *nodehash[INOHSZ];
+static size_t nodehash_nr_items;
 
 static error_t read_node (struct node *np, vm_address_t buf);
 
@@ -105,6 +107,7 @@ diskfs_cached_lookup (ino64_t inum, struct node **npp)
     dn->hnext->dn->hprevp = &dn->hnext;
   dn->hprevp = &nodehash[INOHASH(inum)];
   nodehash[INOHASH(inum)] = np;
+  nodehash_nr_items += 1;
 
   pthread_spin_unlock (&diskfs_node_refcnt_lock);
   
@@ -170,6 +173,7 @@ diskfs_cached_lookup_in_dirbuf (int inum, struct node 
**npp, vm_address_t buf)
     dn->hnext->dn->hprevp = &dn->hnext;
   dn->hprevp = &nodehash[INOHASH(inum)];
   nodehash[INOHASH(inum)] = np;
+  nodehash_nr_items += 1;
 
   pthread_spin_unlock (&diskfs_node_refcnt_lock);
   
@@ -215,7 +219,8 @@ diskfs_node_norefs (struct node *np)
   *np->dn->hprevp = np->dn->hnext;
   if (np->dn->hnext)
     np->dn->hnext->dn->hprevp = np->dn->hprevp;
-  
+  nodehash_nr_items -= 1;
+
   while (last)
     {
       struct cluster_chain *next = last->next;
@@ -545,7 +550,8 @@ error_t
 diskfs_node_iterate (error_t (*fun)(struct node *))
 {
   error_t err = 0;
-  int n, num_nodes = 0;
+  int n;
+  size_t num_nodes;
   struct node *node, **node_list, **p;
 
   pthread_spin_lock (&diskfs_node_refcnt_lock);
@@ -556,9 +562,7 @@ diskfs_node_iterate (error_t (*fun)(struct node *))
      diskfs_node_refcnt_lock, but we can't hold this while locking the
      individual node locks).  */
 
-  for (n = 0; n < INOHSZ; n++)
-    for (node = nodehash[n]; node; node = node->dn->hnext)
-      num_nodes++;
+  num_nodes = nodehash_nr_items;
 
   node_list = alloca (num_nodes * sizeof (struct node *));
   p = node_list;
diff --git a/fatfs/main.c b/fatfs/main.c
index b34f8da..2bbcdfa 100644
--- a/fatfs/main.c
+++ b/fatfs/main.c
@@ -29,6 +29,7 @@
 
 #include <version.h>
 #include "fatfs.h"
+#include "libdiskfs/fsys_S.h"
 
 struct node *diskfs_root_node;
 
@@ -270,7 +271,7 @@ diskfs_readonly_changed (int readonly)
 /* FIXME: libdiskfs doesn't lock the parent dir when looking up a node
    for fsys_getfile, so we disable NFS.  */
 error_t
-diskfs_S_fsys_getfile (mach_port_t fsys,
+diskfs_S_fsys_getfile (struct diskfs_control *pt,
                       mach_port_t reply, mach_msg_type_name_t reply_type,
                       uid_t *uids, mach_msg_type_number_t nuids,
                       gid_t *gids, mach_msg_type_number_t ngids,
diff --git a/fatfs/pager.c b/fatfs/pager.c
index 8146e64..f855ecf 100644
--- a/fatfs/pager.c
+++ b/fatfs/pager.c
@@ -18,12 +18,16 @@
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
+#include <error.h>
 #include <string.h>
 #include <hurd/store.h>
 #include "fatfs.h"
 
-/* A ports bucket to hold pager ports.  */
-struct port_bucket *pager_bucket;
+/* A ports bucket to hold disk pager ports.  */
+struct port_bucket *disk_pager_bucket;
+
+/* A ports bucket to hold file pager ports.  */
+struct port_bucket *file_pager_bucket;
 
 /* Mapped image of the FAT.  */
 void *fat_image;
@@ -752,16 +756,51 @@ pager_dropweak (struct user_pager_info *p __attribute__ 
((unused)))
 {
 }
 
+/* A top-level function for the paging thread that just services paging
+   requests.  */
+static void *
+service_paging_requests (void *arg)
+{
+  struct port_bucket *pager_bucket = arg;
+  ports_manage_port_operations_multithread (pager_bucket,
+                                           pager_demuxer,
+                                           1000,
+                                           0,
+                                           NULL);
+  /* Not reached.  */
+  return NULL;
+}
+
 /* Create the disk pager.  */
 void
 create_fat_pager (void)
 {
+  pthread_t thread;
+  pthread_attr_t attr;
+  error_t err;
+
+  /* The disk pager.  */
   struct user_pager_info *upi = malloc (sizeof (struct user_pager_info));
   upi->type = FAT;
-  pager_bucket = ports_create_bucket ();
-  diskfs_start_disk_pager (upi, pager_bucket, MAY_CACHE, 0,
+  disk_pager_bucket = ports_create_bucket ();
+  diskfs_start_disk_pager (upi, disk_pager_bucket, MAY_CACHE, 0,
                           bytes_per_sector * sectors_per_fat,
                           &fat_image);
+
+  /* The file pager.  */
+  file_pager_bucket = ports_create_bucket ();
+
+#define STACK_SIZE (64 * 1024)
+  pthread_attr_init (&attr);
+  pthread_attr_setstacksize (&attr, STACK_SIZE);
+#undef STACK_SIZE
+
+  /* Make a thread to service file paging requests.  */
+  err = pthread_create (&thread, &attr,
+                       service_paging_requests, file_pager_bucket);
+  if (err)
+    error (2, err, "pthread_create");
+  pthread_detach (thread);
 }
 
 /* Call this to create a FILE_DATA pager and return a send right.
@@ -800,7 +839,7 @@ diskfs_get_filemap (struct node *node, vm_prot_t prot)
           upi->max_prot = prot;
           diskfs_nref_light (node);
           node->dn->pager =
-            pager_create (upi, pager_bucket, MAY_CACHE,
+            pager_create (upi, file_pager_bucket, MAY_CACHE,
                           MEMORY_OBJECT_COPY_DELAY, 0);
           if (node->dn->pager == 0)
             {
@@ -881,14 +920,13 @@ diskfs_shutdown_pager ()
   error_t shutdown_one (void *v_p)
     {
       struct pager *p = v_p;
-      if (p != diskfs_disk_pager)
-        pager_shutdown (p);
+      pager_shutdown (p);
       return 0;
     }
 
   write_all_disknodes ();
 
-  ports_bucket_iterate (pager_bucket, shutdown_one);
+  ports_bucket_iterate (file_pager_bucket, shutdown_one);
 
   pager_sync (diskfs_disk_pager, 1);
 
@@ -903,13 +941,12 @@ diskfs_sync_everything (int wait)
   error_t sync_one (void *v_p)
     {
       struct pager *p = v_p;
-      if (p != diskfs_disk_pager)
-        pager_sync (p, wait);
+      pager_sync (p, wait);
       return 0;
     }
 
   write_all_disknodes ();
-  ports_bucket_iterate (pager_bucket, sync_one);
+  ports_bucket_iterate (file_pager_bucket, sync_one);
   pager_sync (diskfs_disk_pager, wait);
 }
 
@@ -926,7 +963,8 @@ disable_caching ()
 
   /* Loop through the pagers and turn off caching one by one,
      synchronously.  That should cause termination of each pager.  */
-  ports_bucket_iterate (pager_bucket, block_cache);
+  ports_bucket_iterate (disk_pager_bucket, block_cache);
+  ports_bucket_iterate (file_pager_bucket, block_cache);
 }
          
 static void
@@ -954,7 +992,8 @@ enable_caching ()
       return 0;
     }
 
-  ports_bucket_iterate (pager_bucket, enable_cache);
+  ports_bucket_iterate (disk_pager_bucket, enable_cache);
+  ports_bucket_iterate (file_pager_bucket, enable_cache);
 }
            
 /* Tell diskfs if there are pagers exported, and if none, then
@@ -962,9 +1001,9 @@ enable_caching ()
 int
 diskfs_pager_users ()
 {
-  int npagers = ports_count_bucket (pager_bucket);
+  int npagers = ports_count_bucket (file_pager_bucket);
 
-  if (npagers <= 1)
+  if (npagers == 0)
     return 0;
 
   if (MAY_CACHE)
@@ -975,8 +1014,8 @@ diskfs_pager_users ()
         immediately.  XXX */
       sleep (1);
       
-      npagers = ports_count_bucket (pager_bucket);
-      if (npagers <= 1)
+      npagers = ports_count_bucket (file_pager_bucket);
+      if (npagers == 0)
        return 0;
 
       /* Darn, there are actual honest users.  Turn caching back on,
@@ -984,7 +1023,7 @@ diskfs_pager_users ()
       enable_caching ();
     }
   
-  ports_enable_bucket (pager_bucket);
+  ports_enable_bucket (file_pager_bucket);
 
   return 1;
 }
@@ -995,21 +1034,18 @@ vm_prot_t
 diskfs_max_user_pager_prot ()
 {
   vm_prot_t max_prot = 0;
-  int npagers = ports_count_bucket (pager_bucket);
+  int npagers = ports_count_bucket (file_pager_bucket);
 
-  if (npagers > 1)
-    /* More than just the disk pager.  */
+  if (npagers > 0)
     {
       error_t add_pager_max_prot (void *v_p)
         {
           struct pager *p = v_p;
           struct user_pager_info *upi = pager_get_upi (p);
-          if (upi->type == FILE_DATA)
-            max_prot |= upi->max_prot;
+          max_prot |= upi->max_prot;
           /* Stop iterating if MAX_PROT is as filled as it is going to
             get.  */
-          return (max_prot
-                 == (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE)) ? 1 : 0;
+          return max_prot == (VM_PROT_READ|VM_PROT_WRITE|VM_PROT_EXECUTE);
         }
 
       disable_caching ();               /* Make any silly pagers go away.  */
@@ -1018,12 +1054,12 @@ diskfs_max_user_pager_prot ()
          immediately.  XXX */
       sleep (1);
 
-      ports_bucket_iterate (pager_bucket, add_pager_max_prot);
+      ports_bucket_iterate (file_pager_bucket, add_pager_max_prot);
 
       enable_caching ();
     }
 
-  ports_enable_bucket (pager_bucket);
+  ports_enable_bucket (file_pager_bucket);
 
   return max_prot;
 }
diff --git a/hurd/exec_startup.defs b/hurd/exec_startup.defs
index 9dfb79a..697f6b2 100644
--- a/hurd/exec_startup.defs
+++ b/hurd/exec_startup.defs
@@ -23,11 +23,15 @@ subsystem exec_startup 30500;
 
 #include <hurd/hurd_types.defs>
 
+#ifdef EXEC_STARTUP_IMPORTS
+EXEC_STARTUP_IMPORTS
+#endif
+
 /* This call is made by a new task to its bootstrap port to get its
    startup ports and information.  */
 
 routine exec_startup_get_info (
-       bootstrap: mach_port_t;
+       bootstrap: exec_startup_t;
        /* These describe the entry point and program header data
           of the user program loaded into the task.  */
        out user_entry: vm_address_t;
diff --git a/hurd/hurd_types.defs b/hurd/hurd_types.defs
index 4b32504..129a68c 100644
--- a/hurd/hurd_types.defs
+++ b/hurd/hurd_types.defs
@@ -156,6 +156,30 @@ destructor: FS_NOTIFY_DESTRUCTOR
 #endif
 ;
 
+type exec_startup_t = mach_port_copy_send_t
+#ifdef EXEC_STARTUP_INTRAN
+intran: EXEC_STARTUP_INTRAN
+#endif
+#ifdef EXEC_STARTUP_OUTTRAN
+outtran: EXEC_STARTUP_OUTTRAN
+#endif
+#ifdef EXEC_STARTUP_DESTRUCTOR
+destructor: EXEC_STARTUP_DESTRUCTOR
+#endif
+;
+
+type interrupt_t = mach_port_copy_send_t
+#ifdef INTERRUPT_INTRAN
+intran: INTERRUPT_INTRAN
+#endif
+#ifdef INTERRUPT_OUTTRAN
+outtran: INTERRUPT_OUTTRAN
+#endif
+#ifdef INTERRUPT_DESTRUCTOR
+destructor: INTERRUPT_DESTRUCTOR
+#endif
+;
+
 
 type proccoll_t = mach_port_copy_send_t;
 
diff --git a/hurd/hurd_types.h b/hurd/hurd_types.h
index 7d1bb73..8eac206 100644
--- a/hurd/hurd_types.h
+++ b/hurd/hurd_types.h
@@ -46,6 +46,8 @@ typedef mach_port_t pf_t;     /* Protocol family */
 typedef mach_port_t addr_port_t;
 typedef mach_port_t startup_t;
 typedef mach_port_t fs_notify_t;
+typedef mach_port_t exec_startup_t;
+typedef mach_port_t interrupt_t;
 typedef mach_port_t proccoll_t;
 
 #include <errno.h>             /* Defines `error_t'.  */
diff --git a/hurd/interrupt.defs b/hurd/interrupt.defs
index cc3ad1e..9981aed 100644
--- a/hurd/interrupt.defs
+++ b/hurd/interrupt.defs
@@ -23,10 +23,14 @@ subsystem interrupt 33000;
 
 #include <hurd/hurd_types.defs>
 
+#ifdef INTERRUPT_IMPORTS
+INTERRUPT_IMPORTS
+#endif
+
 /* Cause a pending request on this object to immediately return.  The
    exact semantics are dependent on the specific object.  */
 
 routine
-interrupt_operation (object: mach_port_t;
+interrupt_operation (object: interrupt_t;
                     waittime timeout: natural_t;
                     msgseqno seqno: mach_port_seqno_t);
diff --git a/include/refcount.h b/include/refcount.h
new file mode 100644
index 0000000..5c3302d
--- /dev/null
+++ b/include/refcount.h
@@ -0,0 +1,263 @@
+/* Lock-less reference counting primitives
+
+   Copyright (C) 2014 Free Software Foundation, Inc.
+
+   Written by Justus Winter <address@hidden>
+
+   This file is part of the GNU Hurd.
+
+   The GNU Hurd is free software; you can redistribute it and/or
+   modify it under the terms of the GNU General Public License as
+   published by the Free Software Foundation; either version 2, or (at
+   your option) any later version.
+
+   The GNU Hurd is distributed in the hope that it will be useful, but
+   WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#ifndef _HURD_REFCOUNT_H_
+#define _HURD_REFCOUNT_H_
+
+#include <assert.h>
+#include <limits.h>
+#include <stdint.h>
+
+/* Simple reference counting.  */
+
+/* An opaque type.  You must not access these values directly.  */
+typedef unsigned int refcount_t;
+
+/* Initialize REF with REFERENCES.  */
+static inline void
+refcount_init (refcount_t *ref, unsigned int references)
+{
+  *ref = references;
+}
+
+/* Increment REF.  Return the result of the operation.  This function
+   uses atomic operations.  It is not required to serialize calls to
+   this function.  */
+static inline unsigned int
+refcount_ref (refcount_t *ref)
+{
+  unsigned int r;
+  r = __atomic_add_fetch (ref, 1, __ATOMIC_RELAXED);
+  assert (r != UINT_MAX || !"refcount overflowed!");
+  return r;
+}
+
+/* Decrement REF.  Return the result of the operation.  This function
+   uses atomic operations.  It is not required to serialize calls to
+   this function.  */
+static inline unsigned int
+refcount_deref (refcount_t *ref)
+{
+  unsigned int r;
+  r = __atomic_sub_fetch (ref, 1, __ATOMIC_RELAXED);
+  assert (r != UINT_MAX || !"refcount underflowed!");
+  return r;
+}
+
+/* Return REF.  This function uses atomic operations.  It is not
+   required to serialize calls to this function.  */
+static inline unsigned int
+refcount_references (refcount_t *ref)
+{
+  return __atomic_load_n (ref, __ATOMIC_RELAXED);
+}
+
+/* Reference counting with weak references.  */
+
+/* An opaque type.  You must not access these values directly.  */
+typedef union _references refcounts_t;
+
+/* Instead, the functions manipulating refcounts_t values write the
+   results into this kind of objects.  */
+struct references {
+  /* We chose the layout of this struct so that when it is used in the
+     union _references, the hard reference counts occupy the least
+     significant bits.  We rely on this layout for atomic promotion
+     and demotion of references.  See refcounts_promote and
+     refcounts_demote for details.  */
+#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+  uint32_t hard;
+  uint32_t weak;
+#else
+  uint32_t weak;
+  uint32_t hard;
+#endif
+};
+
+/* We use a union to convert struct reference values to uint64_t which
+   we can manipulate atomically.  While this behavior is not
+   guaranteed by the C standard, it is supported by all major
+   compilers.  */
+union _references {
+  struct references references;
+  uint64_t value;
+};
+
+/* Initialize REF with HARD and WEAK references.  */
+static inline void
+refcounts_init (refcounts_t *ref, uint32_t hard, uint32_t weak)
+{
+  ref->references = (struct references) { .hard = hard, .weak = weak };
+}
+
+/* Increment the hard reference count of REF.  If RESULT is not NULL,
+   the result of the operation is written there.  This function uses
+   atomic operations.  It is not required to serialize calls to this
+   function.  */
+static inline void
+refcounts_ref (refcounts_t *ref, struct references *result)
+{
+  const union _references op = { .references = { .hard = 1 } };
+  union _references r;
+  r.value = __atomic_add_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
+  assert (r.references.hard != UINT32_MAX || !"refcount overflowed!");
+  if (result)
+    *result = r.references;
+}
+
+/* Decrement the hard reference count of REF.  If RESULT is not NULL,
+   the result of the operation is written there.  This function uses
+   atomic operations.  It is not required to serialize calls to this
+   function.  */
+static inline void
+refcounts_deref (refcounts_t *ref, struct references *result)
+{
+  const union _references op = { .references = { .hard = 1 } };
+  union _references r;
+  r.value = __atomic_sub_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
+  assert (r.references.hard != UINT32_MAX || !"refcount underflowed!");
+  if (result)
+    *result = r.references;
+}
+
+/* Promote a weak reference to a hard reference.  If RESULT is not
+   NULL, the result of the operation is written there.  This function
+   uses atomic operations.  It is not required to serialize calls to
+   this function.  */
+static inline void
+refcounts_promote (refcounts_t *ref, struct references *result)
+{
+  /* To promote a weak reference, we need to atomically subtract 1
+     from the weak reference count, and add 1 to the hard reference
+     count.
+
+     We can subtract by 1 by adding the two's complement of 1 = ~0 to
+     a fixed-width value, discarding the overflow.
+
+     We do the same in our uint64_t value, but we have chosen the
+     layout of struct references so that when it is used in the union
+     _references, the weak reference counts occupy the most
+     significant bits.  When we add ~0 to the weak references, the
+     overflow will be discarded as unsigned arithmetic is modulo 2^n.
+     So we just add a hard reference.  In combination, this is the
+     desired operation.  */
+  const union _references op =
+    { .references = { .weak = ~0, .hard = 1} };
+  union _references r;
+  r.value = __atomic_add_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
+  assert (r.references.hard != UINT32_MAX || !"refcount overflowed!");
+  assert (r.references.weak != UINT32_MAX || !"refcount underflowed!");
+  if (result)
+    *result = r.references;
+}
+
+/* Demote a hard reference to a weak reference.  If RESULT is not
+   NULL, the result of the operation is written there.  This function
+   uses atomic operations.  It is not required to serialize calls to
+   this function.  */
+static inline void
+refcounts_demote (refcounts_t *ref, struct references *result)
+{
+  /* To demote a hard reference, we need to atomically subtract 1 from
+     the hard reference count, and add 1 to the weak reference count.
+
+     We can subtract by 1 by adding the two's complement of 1 = ~0 to
+     a fixed-width value, discarding the overflow.
+
+     We do the same in our uint64_t value, but we have chosen the
+     layout of struct references so that when it is used in the union
+     _references, the hard reference counts occupy the least
+     significant bits.  When we add ~0 to the hard references, it will
+     overflow into the weak references.  This is the desired
+     operation.  */
+  const union _references op = { .references = { .hard = ~0 } };
+  union _references r;
+  r.value = __atomic_add_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
+  assert (r.references.hard != UINT32_MAX || !"refcount underflowed!");
+  assert (r.references.weak != UINT32_MAX || !"refcount overflowed!");
+  if (result)
+    *result = r.references;
+}
+
+/* Increment the weak reference count of REF.  If RESULT is not NULL,
+   the result of the operation is written there.  This function uses
+   atomic operations.  It is not required to serialize calls to this
+   function.  */
+static inline void
+refcounts_ref_weak (refcounts_t *ref, struct references *result)
+{
+  const union _references op = { .references = { .weak = 1 } };
+  union _references r;
+  r.value = __atomic_add_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
+  assert (r.references.weak != UINT32_MAX || !"refcount overflowed!");
+  if (result)
+    *result = r.references;
+}
+
+/* Decrement the weak reference count of REF.  If RESULT is not NULL,
+   the result of the operation is written there.  This function uses
+   atomic operations.  It is not required to serialize calls to this
+   function.  */
+static inline void
+refcounts_deref_weak (refcounts_t *ref, struct references *result)
+{
+  const union _references op = { .references = { .weak = 1 } };
+  union _references r;
+  r.value = __atomic_sub_fetch (&ref->value, op.value, __ATOMIC_RELAXED);
+  assert (r.references.weak != UINT32_MAX || !"refcount underflowed!");
+  if (result)
+    *result = r.references;
+}
+
+/* Store the current reference counts of REF in RESULT.  This function
+   uses atomic operations.  It is not required to serialize calls to
+   this function.  */
+static inline void
+refcounts_references (refcounts_t *ref, struct references *result)
+{
+  union _references r;
+  r.value =__atomic_load_n (&ref->value, __ATOMIC_RELAXED);
+  *result = r.references;
+}
+
+/* Return the hard reference count of REF.  This function uses atomic
+   operations.  It is not required to serialize calls to this
+   function.  */
+static inline uint32_t
+refcounts_hard_references (refcounts_t *ref)
+{
+  struct references result;
+  refcounts_references (ref, &result);
+  return result.hard;
+}
+
+/* Return the weak reference count of REF.  This function uses atomic
+   operations.  It is not required to serialize calls to this
+   function.  */
+static inline uint32_t
+refcounts_weak_references (refcounts_t *ref)
+{
+  struct references result;
+  refcounts_references (ref, &result);
+  return result.weak;
+}
+
+#endif /* _HURD_REFCOUNT_H_ */
diff --git a/isofs/inode.c b/isofs/inode.c
index f542d18..cdc05ae 100644
--- a/isofs/inode.c
+++ b/isofs/inode.c
@@ -22,6 +22,7 @@
 #include <stdio.h>
 #include <time.h>
 #include "isofs.h"
+#include "libdiskfs/fs_S.h"
 
 
 /* There is no such thing as an inode in this format, all such
diff --git a/libdiskfs/Makefile b/libdiskfs/Makefile
index aeebe4e..996e86a 100644
--- a/libdiskfs/Makefile
+++ b/libdiskfs/Makefile
@@ -68,6 +68,7 @@ fsys-MIGSFLAGS = -imacros $(srcdir)/fsmutations.h 
-DREPLY_PORTS
 fs-MIGSFLAGS = -imacros $(srcdir)/fsmutations.h
 io-MIGSFLAGS = -imacros $(srcdir)/fsmutations.h
 ifsock-MIGSFLAGS = -imacros $(srcdir)/fsmutations.h
+exec_startup-MIGSFLAGS = -imacros $(srcdir)/fsmutations.h
 MIGCOMSFLAGS = -prefix diskfs_
 
 include ../Makeconf
diff --git a/libdiskfs/boot-start.c b/libdiskfs/boot-start.c
index 7b8a84f..a60a1d0 100644
--- a/libdiskfs/boot-start.c
+++ b/libdiskfs/boot-start.c
@@ -34,6 +34,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 #include <argz.h>
 #include <error.h>
 #include <pids.h>
+#include "exec_S.h"
+#include "exec_startup_S.h"
 #include "fsys_S.h"
 #include "fsys_reply_U.h"
 
@@ -299,7 +301,7 @@ diskfs_start_bootstrap ()
    call (as does any task) to get its state.  We can't give it all of
    its ports (we'll provide those with a later call to exec_init).  */
 kern_return_t
-diskfs_S_exec_startup_get_info (mach_port_t port,
+diskfs_S_exec_startup_get_info (struct bootinfo *upt,
                                vm_address_t *user_entry,
                                vm_address_t *phdr_data,
                                vm_size_t *phdr_size,
@@ -322,12 +324,10 @@ diskfs_S_exec_startup_get_info (mach_port_t port,
   error_t err;
   mach_port_t *portarray, *dtable;
   mach_port_t rootport;
-  struct ufsport *upt;
   struct protid *rootpi;
   struct peropen *rootpo;
 
-  if (!(upt = ports_lookup_port (diskfs_port_bucket, port,
-                                diskfs_execboot_class)))
+  if (! upt)
     return EOPNOTSUPP;
 
   *user_entry = 0;
@@ -368,13 +368,12 @@ diskfs_S_exec_startup_get_info (mach_port_t port,
   portarray[INIT_PORT_AUTH] = MACH_PORT_NULL;
   portarray[INIT_PORT_PROC] = MACH_PORT_NULL;
   portarray[INIT_PORT_CTTYID] = MACH_PORT_NULL;
-  portarray[INIT_PORT_BOOTSTRAP] = port; /* use the same port */
+  portarray[INIT_PORT_BOOTSTRAP] = upt->pi.port_right; /* use the same port */
 
   *portarraypoly = MACH_MSG_TYPE_MAKE_SEND;
 
   *dtablepoly = MACH_MSG_TYPE_COPY_SEND;
 
-  ports_port_deref (upt);
   return 0;
 }
 
diff --git a/libdiskfs/dir-renamed.c b/libdiskfs/dir-renamed.c
index 9b7ec3a..9e37e23 100644
--- a/libdiskfs/dir-renamed.c
+++ b/libdiskfs/dir-renamed.c
@@ -209,7 +209,12 @@ diskfs_rename_dir (struct node *fdp, struct node *fnp, 
const char *fromname,
   if (tmpnp)
     diskfs_nrele (tmpnp);
   if (err)
-    goto out;
+    {
+      assert (!tmpnp);
+      /* diskfs_lookup has not locked fnp then, do not unlock it. */
+      fnp = NULL;
+      goto out;
+    }
 
   diskfs_dirremove (fdp, fnp, fromname, ds);
   ds = 0;
diff --git a/libdiskfs/diskfs.h b/libdiskfs/diskfs.h
index 359b11b..8151ddc 100644
--- a/libdiskfs/diskfs.h
+++ b/libdiskfs/diskfs.h
@@ -126,6 +126,11 @@ struct diskfs_control
   struct port_info pi;
 };
 
+struct bootinfo
+{
+  struct port_info pi;
+};
+
 /* Possibly lookup types for diskfs_lookup call */
 enum lookup_type
 {
@@ -801,9 +806,11 @@ void diskfs_finish_protid (struct protid *cred, struct 
iouser *user);
 
 extern struct protid * diskfs_begin_using_protid_port (file_t port);
 extern struct diskfs_control * diskfs_begin_using_control_port (fsys_t port);
+extern struct bootinfo *diskfs_begin_using_bootinfo_port (exec_startup_t port);
 
 extern void diskfs_end_using_protid_port (struct protid *cred);
 extern void diskfs_end_using_control_port (struct diskfs_control *cred);
+extern void diskfs_end_using_bootinfo (struct bootinfo *upt);
 
 #if defined(__USE_EXTERN_INLINES) || defined(DISKFS_DEFINE_EXTERN_INLINE)
 
@@ -823,6 +830,14 @@ diskfs_begin_using_control_port (fsys_t port)
   return ports_lookup_port (diskfs_port_bucket, port, NULL);
 }
 
+/* And for the exec_startup interface. */
+DISKFS_EXTERN_INLINE struct bootinfo *
+diskfs_begin_using_bootinfo_port (exec_startup_t port)
+{
+  return ports_lookup_port (diskfs_port_bucket, port, diskfs_execboot_class);
+}
+
+
 /* Called by MiG after server routines have been run; this
    balances begin_using_protid_port, and is arranged for the io
    and fs interfaces by fsmutations.h. */
@@ -841,6 +856,14 @@ diskfs_end_using_control_port (struct diskfs_control *cred)
     ports_port_deref (cred);
 }
 
+/* And for the exec_startup interface. */
+DISKFS_EXTERN_INLINE void
+diskfs_end_using_bootinfo (struct bootinfo *b)
+{
+  if (b)
+    ports_port_deref (b);
+}
+
 #endif /* Use extern inlines.  */
 
 /* Called when a protid CRED has no more references.  (Because references\
diff --git a/libdiskfs/file-chg.c b/libdiskfs/file-chg.c
index 2674398..9da43e7 100644
--- a/libdiskfs/file-chg.c
+++ b/libdiskfs/file-chg.c
@@ -16,7 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
-#include "fs_S.h"
+#include "fs_notify_S.h"
 #include "fs_notify_U.h"
 
 kern_return_t
diff --git a/libdiskfs/file-chmod.c b/libdiskfs/file-chmod.c
index 5dad2c7..df262ea 100644
--- a/libdiskfs/file-chmod.c
+++ b/libdiskfs/file-chmod.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "fs_S.h"
 
 /* Implement file_chmod as described in <hurd/fs.defs>. */
 error_t
diff --git a/libdiskfs/file-get-fs-opts.c b/libdiskfs/file-get-fs-opts.c
index 1e70da2..d759311 100644
--- a/libdiskfs/file-get-fs-opts.c
+++ b/libdiskfs/file-get-fs-opts.c
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <argz.h>
 #include "priv.h"
+#include "fs_S.h"
 
 error_t
 diskfs_S_file_get_fs_options (struct protid *cred,
diff --git a/libdiskfs/fsmutations.h b/libdiskfs/fsmutations.h
index 68b6ae3..3f9362b 100644
--- a/libdiskfs/fsmutations.h
+++ b/libdiskfs/fsmutations.h
@@ -26,7 +26,14 @@
 #define FSYS_INTRAN control_t diskfs_begin_using_control_port (fsys_t)
 #define FSYS_DESTRUCTOR diskfs_end_using_control_port (control_t)
 
-#define FILE_IMPORTS import "priv.h";
-#define IO_IMPORTS import "priv.h";
-#define FSYS_IMPORTS import "priv.h";
-#define IFSOCK_IMPORTS import "priv.h";
+#define FILE_IMPORTS import "libdiskfs/priv.h";
+#define IO_IMPORTS import "libdiskfs/priv.h";
+#define FSYS_IMPORTS import "libdiskfs/priv.h";
+#define IFSOCK_IMPORTS import "libdiskfs/priv.h";
+
+#define EXEC_STARTUP_INTRAN                             \
+  bootinfo_t diskfs_begin_using_bootinfo_port (exec_startup_t)
+#define EXEC_STARTUP_DESTRUCTOR                         \
+  diskfs_end_using_bootinfo (bootinfo_t)
+#define EXEC_STARTUP_IMPORTS                            \
+  import "libdiskfs/priv.h";
diff --git a/libdiskfs/init-startup.c b/libdiskfs/init-startup.c
index bf955d2..d10c964 100644
--- a/libdiskfs/init-startup.c
+++ b/libdiskfs/init-startup.c
@@ -28,6 +28,8 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 #include <hurd/startup.h>
 #include <pids.h>
 
+#include "startup_S.h"
+
 char *_diskfs_chroot_directory;
 
 mach_port_t
diff --git a/libdiskfs/priv.h b/libdiskfs/priv.h
index b41fa43..2ac3c9e 100644
--- a/libdiskfs/priv.h
+++ b/libdiskfs/priv.h
@@ -63,7 +63,7 @@ extern const struct argp_option diskfs_common_options[];
 #define OPT_INHERIT_DIR_GROUP          604     /* --inherit-dir-group */
 
 /* Common value for diskfs_common_options and diskfs_default_sync_interval. */
-#define DEFAULT_SYNC_INTERVAL 5
+#define DEFAULT_SYNC_INTERVAL 30
 #define DEFAULT_SYNC_INTERVAL_STRING STRINGIFY(DEFAULT_SYNC_INTERVAL)
 #define STRINGIFY(x) STRINGIFY_1(x)
 #define STRINGIFY_1(x) #x
@@ -74,6 +74,7 @@ extern int _diskfs_diskdirty;
 /* Needed for MiG. */
 typedef struct protid *protid_t;
 typedef struct diskfs_control *control_t;
+typedef struct bootinfo *bootinfo_t;
 
 /* Actually read or write a file.  The file size must already permit
    the requested access.  NP is the file to read/write.  DATA is a buffer
diff --git a/libihash/ihash.c b/libihash/ihash.c
index d670fee..4d9cc18 100644
--- a/libihash/ihash.c
+++ b/libihash/ihash.c
@@ -31,55 +31,19 @@
 #include <assert.h>
 
 #include "ihash.h"
-
 
-/* The prime numbers of the form 4 * i + 3 for some i, all greater
-   than twice the previous one and smaller than 2^40 (for now).  */
-static const uint64_t ihash_sizes[] =
+/* This is the integer finalizer from MurmurHash3.  */
+static inline uint32_t
+murmur3_mix32 (uint32_t h, unsigned int bits)
 {
-  3,
-  7,
-  19,
-  43,
-  103,
-  211,
-  431,
-  863,
-  1747,
-  3499,
-  7019,
-  14051,
-  28111,
-  56239,
-  112507,
-  225023,
-  450067,
-  900139,
-  1800311,
-  3600659,
-  7201351,
-  14402743,
-  28805519,
-  57611039,
-  115222091,
-  230444239,
-  460888499,
-  921777067,
-  1843554151,
-  UINT64_C (3687108307),
-  UINT64_C (7374216631),
-  UINT64_C (14748433279),
-  UINT64_C (29496866579),
-  UINT64_C (58993733159),
-  UINT64_C (117987466379),
-  UINT64_C (235974932759),
-  UINT64_C (471949865531),
-  UINT64_C (943899731087)
-};
-
-static const unsigned int ihash_nsizes = (sizeof ihash_sizes
-                                         / sizeof ihash_sizes[0]);
+  h ^= h >> 16;
+  h *= 0x85ebca6b;
+  h ^= h >> 13;
+  h *= 0xc2b2ae35;
+  h ^= h >> 16;
 
+  return h >> (32 - bits);
+}
 
 /* Return 1 if the slot with the index IDX in the hash table HT is
    empty, and 0 otherwise.  */
@@ -107,40 +71,24 @@ static inline int
 find_index (hurd_ihash_t ht, hurd_ihash_key_t key)
 {
   unsigned int idx;
-  unsigned int i;
   unsigned int up_idx;
-  unsigned int down_idx;
+  unsigned int mask = ht->size - 1;
 
-  idx = key % ht->size;
+  idx = murmur3_mix32 (key, __builtin_ctzl (ht->size));
 
   if (ht->items[idx].value == _HURD_IHASH_EMPTY || ht->items[idx].key == key)
     return idx;
 
-  /* Instead of calculating idx + 1, idx + 4, idx + 9, ..., idx + i^2,
-     we add 1, 3, 5, 7, etc to the previous index.  We do this in both
-     directions separately.  */
-  i = 1;
   up_idx = idx;
-  down_idx = idx;
 
   do
     {
-      up_idx = (up_idx + i) % ht->size;
+      up_idx = (up_idx + 1) & mask;
       if (ht->items[up_idx].value == _HURD_IHASH_EMPTY
          || ht->items[up_idx].key == key)
        return up_idx;
-
-      if (down_idx < i)
-       down_idx += ht->size;
-      down_idx = (down_idx - i) % ht->size;
-      if (ht->items[down_idx].value == _HURD_IHASH_EMPTY
-         || ht->items[down_idx].key == key)
-       return down_idx;
-
-      /* After (ht->size - 1) / 2 iterations, this will be 0.  */
-      i = (i + 2) % ht->size;
     }
-  while (i);
+  while (up_idx != idx);
 
   /* If we end up here, the item could not be found.  Return any
      invalid index.  */
@@ -232,14 +180,15 @@ hurd_ihash_set_cleanup (hurd_ihash_t ht, 
hurd_ihash_cleanup_t cleanup,
 }
 
 
-/* Set the maximum load factor in percent to MAX_LOAD, which should be
-   between 1 and 100.  The default is HURD_IHASH_MAX_LOAD_DEFAULT.
-   New elements are only added to the hash table while the number of
-   hashed elements is that much percent of the total size of the hash
-   table.  If more elements are added, the hash table is first
-   expanded and reorganized.  A MAX_LOAD of 100 will always fill the
-   whole table before enlarging it, but note that this will increase
-   the cost of operations significantly when the table is almost full.
+/* Set the maximum load factor in binary percent to MAX_LOAD, which
+   should be between 64 and 128.  The default is
+   HURD_IHASH_MAX_LOAD_DEFAULT.  New elements are only added to the
+   hash table while the number of hashed elements is that much binary
+   percent of the total size of the hash table.  If more elements are
+   added, the hash table is first expanded and reorganized.  A
+   MAX_LOAD of 128 will always fill the whole table before enlarging
+   it, but note that this will increase the cost of operations
+   significantly when the table is almost full.
 
    If the value is set to a smaller value than the current load
    factor, the next reorganization will happen when a new item is
@@ -264,52 +213,25 @@ add_one (hurd_ihash_t ht, hurd_ihash_key_t key, 
hurd_ihash_value_t value)
   unsigned int idx;
   unsigned int first_free;
 
-  idx = key % ht->size;
+  idx = murmur3_mix32 (key, __builtin_ctzl (ht->size));
   first_free = idx;
 
   if (ht->items[idx].value != _HURD_IHASH_EMPTY && ht->items[idx].key != key)
     {
-      /* Instead of calculating idx + 1, idx + 4, idx + 9, ..., idx +
-         i^2, we add 1, 3, 5, 7, ... 2 * i - 1 to the previous index.
-         We do this in both directions separately.  */
-      unsigned int i = 1;
+      unsigned int mask = ht->size - 1;
       unsigned int up_idx = idx;
-      unsigned int down_idx = idx;
- 
+
       do
        {
-         up_idx = (up_idx + i) % ht->size;
+        up_idx = (up_idx + 1) & mask;
          if (ht->items[up_idx].value == _HURD_IHASH_EMPTY
              || ht->items[up_idx].key == key)
            {
              idx = up_idx;
              break;
            }
-         if (first_free == idx
-             && ht->items[up_idx].value == _HURD_IHASH_DELETED)
-           first_free = up_idx;
-
-         if (down_idx < i)
-           down_idx += ht->size;
-         down_idx = (down_idx - i) % ht->size;
-         if (down_idx < 0)
-           down_idx += ht->size;
-         else
-           down_idx %= ht->size;
-         if (ht->items[down_idx].value == _HURD_IHASH_EMPTY
-             || ht->items[down_idx].key == key)
-           {
-             idx = down_idx;
-             break;
-           }
-         if (first_free == idx
-             && ht->items[down_idx].value == _HURD_IHASH_DELETED)
-           first_free = down_idx;
-
-         /* After (ht->size - 1) / 2 iterations, this will be 0.  */
-         i = (i + 2) % ht->size;
        }
-      while (i);
+      while (up_idx != idx);
     }
 
   /* Remove the old entry for this key if necessary.  */
@@ -352,22 +274,19 @@ hurd_ihash_add (hurd_ihash_t ht, hurd_ihash_key_t key, 
hurd_ihash_value_t item)
   if (ht->size)
     {
       /* Only fill the hash table up to its maximum load factor.  */
-      if (ht->nr_items * 100 / ht->size <= ht->max_load)
+      if (hurd_ihash_get_load (ht) <= ht->max_load)
        if (add_one (ht, key, item))
          return 0;
     }
 
   /* The hash table is too small, and we have to increase it.  */
-  for (i = 0; i < ihash_nsizes; i++)
-    if (ihash_sizes[i] > old_ht.size)
-      break;
-  if (i == ihash_nsizes
-      || ihash_sizes[i] > SIZE_MAX / sizeof (struct _hurd_ihash_item))
-    return ENOMEM;             /* Surely will be true momentarily.  */
-
   ht->nr_items = 0;
-  ht->size = ihash_sizes[i];
-  /* calloc() will initialize all values to _HURD_IHASH_EMPTY implicitely.  */
+  if (ht->size == 0)
+      ht->size = HURD_IHASH_MIN_SIZE;
+  else
+      ht->size <<= 1;
+
+  /* calloc() will initialize all values to _HURD_IHASH_EMPTY implicitly.  */
   ht->items = calloc (ht->size, sizeof (struct _hurd_ihash_item));
 
   if (ht->items == NULL)
diff --git a/libihash/ihash.h b/libihash/ihash.h
index 3ca5ec3..345630d 100644
--- a/libihash/ihash.h
+++ b/libihash/ihash.h
@@ -79,8 +79,8 @@ struct hurd_ihash
   /* The offset of the location pointer from the hash value.  */
   intptr_t locp_offset;
 
-  /* The maximum load factor in percent.  */
-  int max_load;
+  /* The maximum load factor in binary percent.  */
+  unsigned int max_load;
 
   /* When freeing or overwriting an element, this function is called
      with the value as the first argument, and CLEANUP_DATA as the
@@ -93,8 +93,13 @@ typedef struct hurd_ihash *hurd_ihash_t;
 
 /* Construction and destruction of hash tables.  */
 
-/* The default value for the maximum load factor in percent.  */
-#define HURD_IHASH_MAX_LOAD_DEFAULT 80
+/* The size of the initial allocation in number of items.  This must
+   be a power of two.  */
+#define HURD_IHASH_MIN_SIZE    32
+
+/* The default value for the maximum load factor in binary percent.
+   96b% is equivalent to 75%, 128b% to 100%.  */
+#define HURD_IHASH_MAX_LOAD_DEFAULT 96
 
 /* The LOCP_OFFS to use if no location pointer is available.  */
 #define HURD_IHASH_NO_LOCP     INTPTR_MIN
@@ -139,14 +144,15 @@ void hurd_ihash_free (hurd_ihash_t ht);
 void hurd_ihash_set_cleanup (hurd_ihash_t ht, hurd_ihash_cleanup_t cleanup,
                             void *cleanup_data);
 
-/* Set the maximum load factor in percent to MAX_LOAD, which should be
-   between 50 and 100.  The default is HURD_IHASH_MAX_LOAD_DEFAULT.
-   New elements are only added to the hash table while the number of
-   hashed elements is that much percent of the total size of the hash
-   table.  If more elements are added, the hash table is first
-   expanded and reorganized.  A MAX_LOAD of 100 will always fill the
-   whole table before enlarging it, but note that this will increase
-   the cost of operations significantly when the table is almost full.
+/* Set the maximum load factor in binary percent to MAX_LOAD, which
+   should be between 64 and 128.  The default is
+   HURD_IHASH_MAX_LOAD_DEFAULT.  New elements are only added to the
+   hash table while the number of hashed elements is that much binary
+   percent of the total size of the hash table.  If more elements are
+   added, the hash table is first expanded and reorganized.  A
+   MAX_LOAD of 128 will always fill the whole table before enlarging
+   it, but note that this will increase the cost of operations
+   significantly when the table is almost full.
 
    If the value is set to a smaller value than the current load
    factor, the next reorganization will happen when a new item is
@@ -154,6 +160,30 @@ void hurd_ihash_set_cleanup (hurd_ihash_t ht, 
hurd_ihash_cleanup_t cleanup,
 void hurd_ihash_set_max_load (hurd_ihash_t ht, unsigned int max_load);
 
 
+/* Get the current load factor of HT in binary percent, where 128b%
+   corresponds to 100%.  The reason we do this is that it is so
+   efficient to compute:
+
+   As the size is always a power of two, and 128 is also, the quotient
+   of both is also a power of two.  Therefore, we can use bit shifts
+   to scale the number of items.
+
+   load = nr_items * 128 / size
+        = nr_items * 2^{log2 (128) - log2 (size)}
+        = nr_items >> (log2 (size) - log2 (128))
+                                -- if size >= 128
+        = nr_items << (log2 (128) - log2 (size))
+                                -- otherwise
+
+   If you want to convert this to percent, just divide by 1.28.  */
+static inline unsigned int
+hurd_ihash_get_load (hurd_ihash_t ht)
+{
+  int d = __builtin_ctzl (ht->size) - 7;
+  return d >= 0 ? ht->nr_items >> d : ht->nr_items << -d;
+}
+
+
 /* Add ITEM to the hash table HT under the key KEY.  If there already
    is an item under this key, call the cleanup function (if any) for
    it before overriding the value.  If a memory allocation error
diff --git a/libmachdev/Makefile b/libmachdev/Makefile
index 728fe82..a47bf32 100644
--- a/libmachdev/Makefile
+++ b/libmachdev/Makefile
@@ -20,7 +20,7 @@ makemode := library
 libname = libmachdev
 
 SRCS = deviceUser.c machUser.c net.c ds_routines.c queue.c trivfs_server.c \
-       device_replyUser.c ourdeviceServer.c notifyServer.c misc.c block.c
+       device_replyUser.c deviceServer.c notifyServer.c misc.c block.c
 LCLHDRS = dev_hdr.h device_emul.h ds_routines.h vm_param.h \
          util.h queue.h io_req.h if_ether.h machdev.h linux-errno.h \
          errno-base.h
@@ -28,11 +28,9 @@ installhdrs = machdev.h
 HURDLIBS = ports trivfs ddekit bpf
 OTHERLIBS = -lpthread
 OBJS = $(SRCS:.c=.o) $(MIGSTUBS)
+MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
 
 include ../Makeconf
 
-ourdevice.defs: device.defs
-       $(CPP) $(CPPFLAGS) -x c $< | sed -e '/out[      ]*device[       ]*:[    
]*device_t/s/device_t/mach_port_send_t/' > $@
-
 $(libname).so.$(hurd-version):
        echo "INPUT ( $(libname).a )" > $@
diff --git a/libmachdev/block.c b/libmachdev/block.c
index 756a07b..cd868d2 100644
--- a/libmachdev/block.c
+++ b/libmachdev/block.c
@@ -35,6 +35,7 @@
 
 #include <ddekit/printf.h>
 
+#include "ds_routines.h"
 #include "vm_param.h"
 #include "device_reply_U.h"
 #include "dev_hdr.h"
diff --git a/libmachdev/ds_routines.c b/libmachdev/ds_routines.c
index d22fb2f..6bd5a12 100644
--- a/libmachdev/ds_routines.c
+++ b/libmachdev/ds_routines.c
@@ -63,15 +63,16 @@
 #include <ddekit/thread.h>
 
 #include "vm_param.h"
-#include "device_reply_U.h"
+#include "device_S.h"
+#include "notify_S.h"
 #include "io_req.h"
 #include "dev_hdr.h"
 #include "util.h"
 #include "queue.h"
 #include "mach_glue.h"
 
-static struct port_bucket *port_bucket;
-static struct port_class *dev_class;
+struct port_bucket *device_bucket;
+struct port_class *dev_class;
 
 #define NUM_EMULATION num_emul
 #define MAX_NUM_EMULATION 32
@@ -82,34 +83,6 @@ static int num_emul;
 
 boolean_t is_master_device (mach_port_t port);
 
-static inline void
-mach_device_deallocate (void *device)
-{
-  ports_port_deref (device);
-}
-
-static inline void
-mach_device_reference (mach_device_t device)
-{
-  ports_port_ref (device);
-}
-
-static inline emul_device_t
-mach_convert_port_to_device (device_t device)
-{
-  mach_device_t dev = ports_lookup_port (port_bucket, device, dev_class);
-  if (dev == NULL)
-    return NULL;
-
-  return &dev->dev;
-}
-
-static inline void *
-device_to_pi (emul_device_t device)
-{
-  return ((void *) device) - (int) &((mach_device_t) 0)->dev;
-}
-
 /*
  * What follows is the interface for the native Mach devices.
  */
@@ -126,21 +99,21 @@ mach_convert_device_to_port (mach_device_t device)
 
 /* Implementation of device interface */
 kern_return_t 
-ds_xxx_device_set_status (device_t device, dev_flavor_t flavor,
+ds_xxx_device_set_status (struct mach_device *device, dev_flavor_t flavor,
                          dev_status_t status, size_t statu_cnt)
 {
   return D_INVALID_OPERATION;
 }
 
 kern_return_t
-ds_xxx_device_get_status (device_t device, dev_flavor_t flavor,
+ds_xxx_device_get_status (struct mach_device *device, dev_flavor_t flavor,
                          dev_status_t status, size_t *statuscnt)
 {
   return D_INVALID_OPERATION;
 }
 
 kern_return_t
-ds_xxx_device_set_filter (device_t device, mach_port_t rec,
+ds_xxx_device_set_filter (struct mach_device *device, mach_port_t rec,
                          int pri, filter_array_t filt, size_t len)
 {
   return D_INVALID_OPERATION;
@@ -148,7 +121,7 @@ ds_xxx_device_set_filter (device_t device, mach_port_t rec,
 
 io_return_t
 ds_device_intr_register (mach_port_t master_port, int irq,
-                      int id, mach_port_t receive_port)
+                        int flags, int id, mach_port_t receive_port)
 {
   return D_INVALID_OPERATION;
 }
@@ -192,249 +165,176 @@ ds_device_open (mach_port_t open_port, mach_port_t 
reply_port,
 }
 
 io_return_t
-ds_device_close (device_t dev)
+ds_device_close (struct mach_device *device)
 {
-  emul_device_t device;
   io_return_t ret;
 
-  /* Refuse if device is dead or not completely open.  */
-  if (dev == MACH_PORT_NULL)
+  if (device == NULL)
     return D_NO_SUCH_DEVICE;
 
-  device = mach_convert_port_to_device (dev);
-  ret = (device->emul_ops->close
-        ? (*device->emul_ops->close) (device->emul_data)
+  ret = (device->dev.emul_ops->close
+        ? (*device->dev.emul_ops->close) (device->dev.emul_data)
         : D_SUCCESS);
-  mach_device_deallocate (device_to_pi (device));
-
-  ports_port_deref (device_to_pi (device));
   return ret;
 }
 
 io_return_t
-ds_device_write (device_t dev, mach_port_t reply_port,
+ds_device_write (struct mach_device *device, mach_port_t reply_port,
                 mach_msg_type_name_t reply_port_type, dev_mode_t mode,
                 recnum_t recnum, io_buf_ptr_t data, unsigned int count,
                 int *bytes_written)
 {
-  emul_device_t device;
   io_return_t ret;
 
-  /* Refuse if device is dead or not completely open.  */
-  if (dev == MACH_PORT_NULL)
-    return D_NO_SUCH_DEVICE;
-
   if (data == 0)
     return D_INVALID_SIZE;
 
-  device = mach_convert_port_to_device (dev);
   if (device == NULL)
-    return D_INVALID_OPERATION;
-
-  if (! device->emul_ops->write)
-    {
-      ports_port_deref (device_to_pi (device));
-      return D_INVALID_OPERATION;
-    }
+    return D_NO_SUCH_DEVICE;
 
-  ret = (*device->emul_ops->write) (device->emul_data, reply_port,
-                                   reply_port_type, mode, recnum,
-                                   data, count, bytes_written);
-  ports_port_deref (device_to_pi (device));
+  if (! device->dev.emul_ops->write)
+    return D_INVALID_OPERATION;
 
+  ret = (*device->dev.emul_ops->write) (device->dev.emul_data, reply_port,
+                                       reply_port_type, mode, recnum,
+                                       data, count, bytes_written);
   return ret;
 }
 
 io_return_t
-ds_device_write_inband (device_t dev, mach_port_t reply_port,
+ds_device_write_inband (struct mach_device *device, mach_port_t reply_port,
                        mach_msg_type_name_t reply_port_type,
                        dev_mode_t mode, recnum_t recnum,
                        io_buf_ptr_inband_t data, unsigned count,
                        int *bytes_written)
 {
-  emul_device_t device;
   io_return_t ret;
 
-  /* Refuse if device is dead or not completely open.  */
-  if (dev == MACH_PORT_NULL)
-    return D_NO_SUCH_DEVICE;
-
   if (data == 0)
     return D_INVALID_SIZE;
 
-  device = mach_convert_port_to_device (dev);
   if (device == NULL)
-    return D_INVALID_OPERATION;
-
-  if (! device->emul_ops->write_inband)
-    {
-      ports_port_deref (device_to_pi (device));
-      return D_INVALID_OPERATION;
-    }
+    return D_NO_SUCH_DEVICE;
 
-  ret = (*device->emul_ops->write_inband) (device->emul_data, reply_port,
-                                          reply_port_type, mode, recnum,
-                                          data, count, bytes_written);
-  ports_port_deref (device_to_pi (device));
+  if (! device->dev.emul_ops->write_inband)
+    return D_INVALID_OPERATION;
 
+  ret = (*device->dev.emul_ops->write_inband) (device->dev.emul_data,
+                                              reply_port, reply_port_type,
+                                              mode, recnum,
+                                              data, count, bytes_written);
   return ret;
 }
 
 io_return_t
-ds_device_read (device_t dev, mach_port_t reply_port,
+ds_device_read (struct mach_device *device, mach_port_t reply_port,
                mach_msg_type_name_t reply_port_type, dev_mode_t mode,
                recnum_t recnum, int count, io_buf_ptr_t *data,
                unsigned *bytes_read)
 {
-  emul_device_t device;
   io_return_t ret;
 
-  /* Refuse if device is dead or not completely open.  */
-  if (dev == MACH_PORT_NULL)
+  if (device == NULL)
     return D_NO_SUCH_DEVICE;
 
-  device = mach_convert_port_to_device (dev);
-  if (device == NULL)
+  if (! device->dev.emul_ops->read)
     return D_INVALID_OPERATION;
 
-  if (! device->emul_ops->read)
-    {
-      ports_port_deref (device_to_pi (device));
-      return D_INVALID_OPERATION;
-    }
-
-  ret = (*device->emul_ops->read) (device->emul_data, reply_port,
-                                  reply_port_type, mode, recnum,
-                                  count, data, bytes_read);
-  ports_port_deref (device_to_pi (device));
+  ret = (*device->dev.emul_ops->read) (device->dev.emul_data, reply_port,
+                                      reply_port_type, mode, recnum,
+                                      count, data, bytes_read);
   return ret;
 }
 
 io_return_t
-ds_device_read_inband (device_t dev, mach_port_t reply_port,
+ds_device_read_inband (struct mach_device *device, mach_port_t reply_port,
                       mach_msg_type_name_t reply_port_type, dev_mode_t mode,
                       recnum_t recnum, int count, char *data,
                       unsigned *bytes_read)
 {
-  emul_device_t device;
   io_return_t ret;
 
-  /* Refuse if device is dead or not completely open.  */
-  if (dev == MACH_PORT_NULL)
+  if (device == NULL)
     return D_NO_SUCH_DEVICE;
 
-  device = mach_convert_port_to_device (dev);
-  if (device == NULL)
+  if (! device->dev.emul_ops->read_inband)
     return D_INVALID_OPERATION;
 
-  if (! device->emul_ops->read_inband)
-    {
-      ports_port_deref (device_to_pi (device));
-      return D_INVALID_OPERATION;
-    }
-
-  ret = (*device->emul_ops->read_inband) (device->emul_data, reply_port,
-                                         reply_port_type, mode, recnum,
-                                         count, data, bytes_read);
-  ports_port_deref (device_to_pi (device));
+  ret = (*device->dev.emul_ops->read_inband) (device->dev.emul_data,
+                                             reply_port,
+                                             reply_port_type, mode, recnum,
+                                             count, data, bytes_read);
   return ret;
 }
 
 io_return_t
-ds_device_set_status (device_t dev, dev_flavor_t flavor,
+ds_device_set_status (struct mach_device *device, dev_flavor_t flavor,
                      dev_status_t status, mach_msg_type_number_t status_count)
 {
-  emul_device_t device;
   io_return_t ret;
 
-  /* Refuse if device is dead or not completely open.  */
-  if (dev == MACH_PORT_NULL)
+  if (device == NULL)
     return D_NO_SUCH_DEVICE;
 
-  device = mach_convert_port_to_device (dev);
-  if (device == NULL)
+  if (! device->dev.emul_ops->set_status)
     return D_INVALID_OPERATION;
 
-  if (! device->emul_ops->set_status)
-    {
-      ports_port_deref (device_to_pi (device));
-      return D_INVALID_OPERATION;
-    }
-
-  ret = (*device->emul_ops->set_status) (device->emul_data, flavor,
-                                        status, status_count);
-  ports_port_deref (device_to_pi (device));
+  ret = (*device->dev.emul_ops->set_status) (device->dev.emul_data, flavor,
+                                            status, status_count);
   return ret;
 }
 
 io_return_t
-ds_device_get_status (device_t dev, dev_flavor_t flavor, dev_status_t status,
+ds_device_get_status (struct mach_device *device, dev_flavor_t flavor,
+                      dev_status_t status,
                      mach_msg_type_number_t *status_count)
 {
-  emul_device_t device;
   io_return_t ret;
 
-  /* Refuse if device is dead or not completely open.  */
-  if (dev == MACH_PORT_NULL)
+  if (device == NULL)
     return D_NO_SUCH_DEVICE;
 
-  device = mach_convert_port_to_device (dev);
-  if (device == NULL)
+  if (! device->dev.emul_ops->get_status)
     return D_INVALID_OPERATION;
 
-  if (! device->emul_ops->get_status)
-    {
-      ports_port_deref (device_to_pi (device));
-      return D_INVALID_OPERATION;
-    }
-
-  ret = (*device->emul_ops->get_status) (device->emul_data, flavor,
-                                        status, status_count);
-  ports_port_deref (device_to_pi (device));
+  ret = (*device->dev.emul_ops->get_status) (device->dev.emul_data, flavor,
+                                            status, status_count);
   return ret;
 }
 
 io_return_t
-ds_device_set_filter (device_t dev, mach_port_t receive_port, int priority,
-                     filter_t *filter, unsigned filter_count)
+ds_device_set_filter (struct mach_device *device, mach_port_t receive_port,
+                      int priority, filter_t *filter, unsigned filter_count)
 {
-  emul_device_t device;
   io_return_t ret;
 
-  /* Refuse if device is dead or not completely open.  */
-  if (dev == MACH_PORT_NULL)
+  if (device == NULL)
     return D_NO_SUCH_DEVICE;
 
-  device = mach_convert_port_to_device (dev);
-  if (device == NULL)
+  if (! device->dev.emul_ops->set_filter)
     return D_INVALID_OPERATION;
 
-  if (! device->emul_ops->set_filter)
-    {
-      ports_port_deref (device_to_pi (device));
-      return D_INVALID_OPERATION;
-    }
-
-  ret = (*device->emul_ops->set_filter) (device->emul_data, receive_port,
-                                        priority, filter, filter_count);
-  ports_port_deref (device_to_pi (device));
+  ret = (*device->dev.emul_ops->set_filter) (device->dev.emul_data,
+                                            receive_port,
+                                            priority, filter, filter_count);
   return ret;
 }
 
 io_return_t
-ds_device_map (device_t dev, vm_prot_t prot, vm_offset_t offset,
+ds_device_map (struct mach_device *device, vm_prot_t prot, vm_offset_t offset,
               vm_size_t size, mach_port_t *pager, boolean_t unmap)
 {
   /* Refuse if device is dead or not completely open.  */
-  if (dev == MACH_PORT_NULL)
+  if (device == NULL)
     return D_NO_SUCH_DEVICE;
 
   return D_INVALID_OPERATION;
 }
 
-int create_device_port (int size, void *result)
+error_t
+create_device_port (size_t size, void *result)
 {
-  return ports_create_port (dev_class, port_bucket,
+  return ports_create_port (dev_class, device_bucket,
                            size, result);
 }
 
@@ -442,7 +342,7 @@ void mach_device_init()
 {
        int i;
 
-       port_bucket = ports_create_bucket ();
+       device_bucket = ports_create_bucket ();
        dev_class = ports_create_class (0, 0);
 
        for (i = 0; i < NUM_EMULATION; i++) {
@@ -454,11 +354,15 @@ void mach_device_init()
 static int
 demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
 {
-  int ret;
-  extern int device_server (mach_msg_header_t *, mach_msg_header_t *);
-  extern int notify_server (mach_msg_header_t *, mach_msg_header_t *);
-  ret = device_server (inp, outp) || notify_server (inp, outp);
-  return ret;
+  mig_routine_t routine;
+  if ((routine = device_server_routine (inp)) ||
+      (routine = notify_server_routine (inp)))
+    {
+      (*routine) (inp, outp);
+      return TRUE;
+    }
+  else
+    return FALSE;
 }
 
 void reg_dev_emul (struct device_emulation_ops *ops)
@@ -475,7 +379,7 @@ void * ds_server(void *arg)
   /* Launch.  */
   do
     {
-      ports_manage_port_operations_one_thread (port_bucket, demuxer, 0);
+      ports_manage_port_operations_one_thread (device_bucket, demuxer, 0);
     } while (1);
 
   return NULL;
diff --git a/libmachdev/ds_routines.h b/libmachdev/ds_routines.h
index e314e80..3706aa5 100644
--- a/libmachdev/ds_routines.h
+++ b/libmachdev/ds_routines.h
@@ -52,4 +52,6 @@ boolean_t     ds_write_done(io_req_t);
 
 void           iowait (io_req_t ior);
 
+error_t                create_device_port (size_t size, void *result);
+
 #endif /* DS_ROUTINES_H */
diff --git a/proc/mig-decls.h b/libmachdev/mig-decls.h
similarity index 54%
copy from proc/mig-decls.h
copy to libmachdev/mig-decls.h
index 0d5bd4d..b3dc43d 100644
--- a/proc/mig-decls.h
+++ b/libmachdev/mig-decls.h
@@ -1,8 +1,6 @@
-/* Translation functions for mig.
-
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
+/*
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Justus Winter.
 
    This file is part of the GNU Hurd.
 
@@ -19,24 +17,28 @@
    You should have received a copy of the GNU General Public License
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#ifndef __MIG_DECLS_H__
-#define __MIG_DECLS_H__
+#ifndef __LIBMACHDEV_MIG_DECLS_H__
+#define __LIBMACHDEV_MIG_DECLS_H__
+
+#include <hurd/ports.h>
+#include "dev_hdr.h"
 
-#include "proc.h"
+extern struct port_bucket *device_bucket;
+extern struct port_class *dev_class;
 
-typedef struct exc* exc_t;
+/* Called by server stub functions.  */
 
-static inline exc_t __attribute__ ((unused))
-begin_using_exc_port (mach_port_t port)
+static inline struct mach_device * __attribute__ ((unused))
+begin_using_device_port (mach_port_t port)
 {
-  return ports_lookup_port (NULL, port, exc_class);
+  return ports_lookup_port (device_bucket, port, dev_class);
 }
 
 static inline void __attribute__ ((unused))
-end_using_exc (exc_t exc)
+end_using_device (struct mach_device *p)
 {
-  if (exc != NULL)
-    ports_port_deref (exc);
+  if (p)
+    ports_port_deref (p);
 }
 
-#endif
+#endif /* __LIBMACHDEV_MIG_DECLS_H__ */
diff --git a/proc/mig-decls.h b/libmachdev/mig-mutate.h
similarity index 56%
copy from proc/mig-decls.h
copy to libmachdev/mig-mutate.h
index 0d5bd4d..56c6965 100644
--- a/proc/mig-decls.h
+++ b/libmachdev/mig-mutate.h
@@ -1,8 +1,6 @@
-/* Translation functions for mig.
-
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
+/*
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Justus Winter.
 
    This file is part of the GNU Hurd.
 
@@ -19,24 +17,16 @@
    You should have received a copy of the GNU General Public License
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#ifndef __MIG_DECLS_H__
-#define __MIG_DECLS_H__
-
-#include "proc.h"
-
-typedef struct exc* exc_t;
-
-static inline exc_t __attribute__ ((unused))
-begin_using_exc_port (mach_port_t port)
-{
-  return ports_lookup_port (NULL, port, exc_class);
-}
-
-static inline void __attribute__ ((unused))
-end_using_exc (exc_t exc)
-{
-  if (exc != NULL)
-    ports_port_deref (exc);
-}
-
-#endif
+#define NOTIFY_INTRAN                                          \
+  port_info_t begin_using_port_info_port (mach_port_t)
+#define NOTIFY_DESTRUCTOR                                      \
+  end_using_port_info (port_info_t)
+#define NOTIFY_IMPORTS                                         \
+  import "libports/mig-decls.h";
+
+#define DEVICE_INTRAN                                          \
+  mach_device_t begin_using_device_port (mach_port_t)
+#define DEVICE_DESTRUCTOR                                      \
+  end_using_device (mach_device_t)
+#define DEVICE_IMPORTS                                         \
+  import "libmachdev/mig-decls.h";
diff --git a/libmachdev/net.c b/libmachdev/net.c
index 501c9bb..07bb74a 100644
--- a/libmachdev/net.c
+++ b/libmachdev/net.c
@@ -70,6 +70,7 @@
 
 #define MACH_INCLUDE
 
+#include "ds_routines.h"
 #include "vm_param.h"
 #include "device_reply_U.h"
 #include "dev_hdr.h"
@@ -80,10 +81,6 @@
 
 #define ether_header ethhdr
 
-extern int linux_intr_pri;
-extern struct port_bucket *port_bucket;
-extern struct port_class *dev_class;
-
 /* One of these is associated with each instance of a device.  */
 struct net_data
 {
@@ -368,15 +365,14 @@ device_open (mach_port_t reply_port, mach_msg_type_name_t 
reply_port_type,
            dev->set_multicast_list (dev);
 #endif
        }
-      if (MACH_PORT_VALID (reply_port))
-       ds_device_open_reply (reply_port, reply_port_type,
-                             err, dev_to_port (nd));
-      return MIG_NO_REPLY;
     }
 
-  *devp = ports_get_right (nd);
-  *devicePoly = MACH_MSG_TYPE_COPY_SEND;
-  return D_SUCCESS;
+  if (nd)
+    {
+      *devp = ports_get_right (nd);
+      *devicePoly = MACH_MSG_TYPE_MAKE_SEND;
+    }
+  return err;
 }
 
 static io_return_t
diff --git a/libmachdev/trivfs_server.c b/libmachdev/trivfs_server.c
index 4565c3d..7d69a2a 100644
--- a/libmachdev/trivfs_server.c
+++ b/libmachdev/trivfs_server.c
@@ -6,6 +6,9 @@
 #include <hurd/trivfs.h>
 #include <hurd.h>
 
+#include "device_S.h"
+#include "notify_S.h"
+
 static struct port_bucket *port_bucket;
 
 /* Trivfs hooks.  */
@@ -23,41 +26,41 @@ int trivfs_cntl_nportclasses = 1;
 
 /* Implementation of notify interface */
 kern_return_t
-do_mach_notify_port_deleted (mach_port_t notify,
+do_mach_notify_port_deleted (struct port_info *pi,
                             mach_port_t name)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-do_mach_notify_msg_accepted (mach_port_t notify,
+do_mach_notify_msg_accepted (struct port_info *pi,
                             mach_port_t name)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-do_mach_notify_port_destroyed (mach_port_t notify,
+do_mach_notify_port_destroyed (struct port_info *pi,
                               mach_port_t port)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-do_mach_notify_no_senders (mach_port_t notify,
+do_mach_notify_no_senders (struct port_info *pi,
                           mach_port_mscount_t mscount)
 {
-  return ports_do_mach_notify_no_senders (notify, mscount);
+  return ports_do_mach_notify_no_senders (pi, mscount);
 }
 
 kern_return_t
-do_mach_notify_send_once (mach_port_t notify)
+do_mach_notify_send_once (struct port_info *pi)
 {
   return EOPNOTSUPP;
 }
 
 kern_return_t
-do_mach_notify_dead_name (mach_port_t notify,
+do_mach_notify_dead_name (struct port_info *pi,
                          mach_port_t name)
 {
   return EOPNOTSUPP;
@@ -125,12 +128,17 @@ trivfs_goaway (struct trivfs_control *fsys, int flags)
 static int
 demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp)
 {
-  int ret;
-  extern int device_server (mach_msg_header_t *, mach_msg_header_t *);
-  extern int notify_server (mach_msg_header_t *, mach_msg_header_t *);
-  ret = device_server (inp, outp) || notify_server (inp, outp)
-    || trivfs_demuxer (inp, outp);
-  return ret;
+  mig_routine_t routine;
+  if ((routine = device_server_routine (inp)) ||
+      (routine = notify_server_routine (inp)) ||
+      (routine = NULL, trivfs_demuxer (inp, outp)))
+    {
+      if (routine)
+        (*routine) (inp, outp);
+      return TRUE;
+    }
+  else
+    return FALSE;
 }
 
 void
diff --git a/libnetfs/file-get-children.c b/libnetfs/file-get-children.c
index 80a727f..bd7e8fc 100644
--- a/libnetfs/file-get-children.c
+++ b/libnetfs/file-get-children.c
@@ -20,6 +20,7 @@
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "priv.h"
+#include "fs_S.h"
 
 #include <argz.h>
 
diff --git a/libnetfs/file-getcontrol.c b/libnetfs/file-getcontrol.c
index 50401f8..0e29ccf 100644
--- a/libnetfs/file-getcontrol.c
+++ b/libnetfs/file-getcontrol.c
@@ -20,7 +20,7 @@
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
 #include "netfs.h"
-#include "fsys_S.h"
+#include "fs_S.h"
 #include <hurd/fshelp.h>
 
 error_t
diff --git a/libnetfs/file-set-translator.c b/libnetfs/file-set-translator.c
index b46eb02..02c5583 100644
--- a/libnetfs/file-set-translator.c
+++ b/libnetfs/file-set-translator.c
@@ -20,6 +20,7 @@
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
 #include "netfs.h"
+#include "fs_S.h"
 #include <hurd/paths.h>
 #include <hurd/fsys.h>
 
diff --git a/libnetfs/fsstubs.c b/libnetfs/fsstubs.c
index f1b9bf7..75bd790 100644
--- a/libnetfs/fsstubs.c
+++ b/libnetfs/fsstubs.c
@@ -21,6 +21,7 @@
 
 #include "netfs.h"
 #include "fs_S.h"
+#include "ifsock_S.h"
 
 error_t
 netfs_S_file_notice_changes (struct protid *user,
diff --git a/libnetfs/mutations.h b/libnetfs/mutations.h
index 51ca871..e60a220 100644
--- a/libnetfs/mutations.h
+++ b/libnetfs/mutations.h
@@ -31,7 +31,7 @@
 #define FSYS_INTRAN control_t begin_using_control_port (fsys_t)
 #define FSYS_DESTRUCTOR end_using_control_port (control_t)
 
-#define FILE_IMPORTS import "netfs.h"; import "priv.h";
-#define IO_IMPORTS import "netfs.h"; import "priv.h";
-#define FSYS_IMPORTS import "netfs.h"; import "priv.h";
-#define IFSOCK_IMPORTS import "netfs.h"; import "priv.h";
+#define FILE_IMPORTS import "libnetfs/netfs.h"; import "libnetfs/priv.h";
+#define IO_IMPORTS import "libnetfs/netfs.h"; import "libnetfs/priv.h";
+#define FSYS_IMPORTS import "libnetfs/netfs.h"; import "libnetfs/priv.h";
+#define IFSOCK_IMPORTS import "libnetfs/netfs.h"; import "libnetfs/priv.h";
diff --git a/libpager/Makefile b/libpager/Makefile
index 7c4da38..b622295 100644
--- a/libpager/Makefile
+++ b/libpager/Makefile
@@ -31,7 +31,7 @@ HURDLIBS= ports
 LDLIBS += -lpthread
 OBJS = $(SRCS:.c=.o) memory_objectServer.o notifyServer.o
 
-MIGSFLAGS = -DSEQNOS
+MIGSFLAGS = -DSEQNOS -imacros $(srcdir)/mig-mutate.h
 MIGCOMSFLAGS = -prefix _pager_
 
 include ../Makeconf
diff --git a/libpager/chg-compl.c b/libpager/chg-compl.c
index 0b0c99c..d77c46c 100644
--- a/libpager/chg-compl.c
+++ b/libpager/chg-compl.c
@@ -22,16 +22,15 @@
    when a memory_object_change_attributes call has completed.  Read this
    in combination with pager-attr.c.  */
 kern_return_t
-_pager_seqnos_memory_object_change_completed (mach_port_t obj,
+_pager_seqnos_memory_object_change_completed (struct pager *p,
                                       mach_port_seqno_t seq,
                                       boolean_t maycache,
                                       memory_object_copy_strategy_t strat)
 {
-  struct pager *p;
   struct attribute_request *ar;
-  
-  p = ports_lookup_port (0, obj, _pager_class);
-  if (!p)
+
+  if (!p
+      || p->port.class != _pager_class)
     {
       printf ("Bad change completed\n");
       return EOPNOTSUPP;
@@ -50,6 +49,5 @@ _pager_seqnos_memory_object_change_completed (mach_port_t obj,
   
   _pager_release_seqno (p, seq);
   pthread_mutex_unlock (&p->interlock);
-  ports_port_deref (p);
   return 0;
 }
diff --git a/libpager/data-request.c b/libpager/data-request.c
index 34b8b43..82ce904 100644
--- a/libpager/data-request.c
+++ b/libpager/data-request.c
@@ -22,22 +22,21 @@
 
 /* Implement pagein callback as described in <mach/memory_object.defs>. */
 kern_return_t
-_pager_seqnos_memory_object_data_request (mach_port_t object,
+_pager_seqnos_memory_object_data_request (struct pager *p,
                                          mach_port_seqno_t seqno,
                                          mach_port_t control,
                                          vm_offset_t offset,
                                          vm_size_t length,
                                          vm_prot_t access)
 {
-  struct pager *p;
   short *pm_entry;
   int doread, doerror;
   error_t err;
   vm_address_t page;
   int write_lock;
 
-  p = ports_lookup_port (0, object, _pager_class);
-  if (!p)
+  if (!p
+      || p->port.class != _pager_class)
     return EOPNOTSUPP;
 
   /* Acquire the right to meddle with the pagemap */
@@ -126,7 +125,6 @@ _pager_seqnos_memory_object_data_request (mach_port_t 
object,
   _pager_mark_object_error (p, offset, length, 0);
   _pager_allow_termination (p);
   pthread_mutex_unlock (&p->interlock);
-  ports_port_deref (p);
   return 0;
 
  error_read:
@@ -136,7 +134,6 @@ _pager_seqnos_memory_object_data_request (mach_port_t 
object,
   pthread_mutex_lock (&p->interlock);
   _pager_allow_termination (p);
   pthread_mutex_unlock (&p->interlock);
-  ports_port_deref (p);
   return 0;
 
  allow_release_out:
@@ -144,6 +141,5 @@ _pager_seqnos_memory_object_data_request (mach_port_t 
object,
  release_out:
   _pager_release_seqno (p, seqno);
   pthread_mutex_unlock (&p->interlock);
-  ports_port_deref (p);
   return 0;
 }
diff --git a/libpager/data-return.c b/libpager/data-return.c
index 6a3b903..ee6c6e8 100644
--- a/libpager/data-return.c
+++ b/libpager/data-return.c
@@ -26,7 +26,7 @@
    as for _pager_seqnos_memory_object_data_return; the additional
    INITIALIZING arg identifies which function is calling us. */
 kern_return_t
-_pager_do_write_request (mach_port_t object,
+_pager_do_write_request (struct pager *p,
                         mach_port_seqno_t seqno,
                         mach_port_t control,
                         vm_offset_t offset,
@@ -36,7 +36,6 @@ _pager_do_write_request (mach_port_t object,
                         int kcopy,
                         int initializing)
 {
-  struct pager *p;
   short *pm_entries;
   int npages, i;
   char *notified;
@@ -47,8 +46,8 @@ _pager_do_write_request (mach_port_t object,
   int wakeup;
   int omitdata = 0;
 
-  p = ports_lookup_port (0, object, _pager_class);
-  if (!p)
+  if (!p
+      || p->port.class != _pager_class)
     return EOPNOTSUPP;
 
   /* Acquire the right to meddle with the pagemap */
@@ -249,19 +248,17 @@ _pager_do_write_request (mach_port_t object,
        }
     }
 
-  ports_port_deref (p);
   return 0;
 
  release_out:
   _pager_release_seqno (p, seqno);
   pthread_mutex_unlock (&p->interlock);
-  ports_port_deref (p);
   return 0;
 }
 
 /* Implement pageout call back as described by <mach/memory_object.defs>. */
 kern_return_t
-_pager_seqnos_memory_object_data_return (mach_port_t object,
+_pager_seqnos_memory_object_data_return (struct pager *p,
                                         mach_port_seqno_t seqno,
                                         mach_port_t control,
                                         vm_offset_t offset,
@@ -270,6 +267,6 @@ _pager_seqnos_memory_object_data_return (mach_port_t object,
                                         int dirty,
                                         int kcopy)
 {
-  return _pager_do_write_request (object, seqno, control, offset, data,
+  return _pager_do_write_request (p, seqno, control, offset, data,
                                  length, dirty, kcopy, 0);
 }
diff --git a/libpager/data-unlock.c b/libpager/data-unlock.c
index 02339ab..599237c 100644
--- a/libpager/data-unlock.c
+++ b/libpager/data-unlock.c
@@ -22,18 +22,17 @@
 /* Implement kernel requests for access as described in
    <mach/memory_object.defs>. */
 kern_return_t
-_pager_seqnos_memory_object_data_unlock (mach_port_t object,
+_pager_seqnos_memory_object_data_unlock (struct pager *p,
                                         mach_port_seqno_t seqno,
                                         mach_port_t control,
                                         vm_offset_t offset,
                                         vm_size_t length,
                                         vm_prot_t access)
 {
-  struct pager *p;
   volatile int err;
 
-  p = ports_lookup_port (0, object, _pager_class);
-  if (!p)
+  if (!p
+      || p->port.class != _pager_class)
     return EOPNOTSUPP;
 
   pthread_mutex_lock (&p->interlock);
@@ -84,6 +83,5 @@ _pager_seqnos_memory_object_data_unlock (mach_port_t object,
       _pager_mark_next_request_error (p, offset, length, err);
     }
  out:
-  ports_port_deref (p);
   return 0;
 }
diff --git a/libpager/lock-completed.c b/libpager/lock-completed.c
index 9ab640f..a3f3f16 100644
--- a/libpager/lock-completed.c
+++ b/libpager/lock-completed.c
@@ -23,18 +23,17 @@
    when a memory_object_lock_request call has completed.  Read this
    in combination with lock-object.c.  */
 kern_return_t
-_pager_seqnos_memory_object_lock_completed (mach_port_t object,
+_pager_seqnos_memory_object_lock_completed (struct pager *p,
                                            mach_port_seqno_t seqno,
                                            mach_port_t control,
                                            vm_offset_t offset,
                                            vm_size_t length)
 {
   error_t err = 0;
-  struct pager *p;
   struct lock_request *lr;
 
-  p = ports_lookup_port (0, object, _pager_class);
-  if (!p)
+  if (!p
+      || p->port.class != _pager_class)
     return EOPNOTSUPP;
 
   pthread_mutex_lock (&p->interlock);
@@ -62,7 +61,6 @@ _pager_seqnos_memory_object_lock_completed (mach_port_t 
object,
  out:
   _pager_release_seqno (p, seqno);
   pthread_mutex_unlock (&p->interlock);
-  ports_port_deref (p);
 
   return err;
 }
diff --git a/proc/mig-decls.h b/libpager/mig-decls.h
similarity index 59%
copy from proc/mig-decls.h
copy to libpager/mig-decls.h
index 0d5bd4d..0c7b402 100644
--- a/proc/mig-decls.h
+++ b/libpager/mig-decls.h
@@ -1,8 +1,6 @@
-/* Translation functions for mig.
-
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
+/*
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Justus Winter.
 
    This file is part of the GNU Hurd.
 
@@ -19,24 +17,26 @@
    You should have received a copy of the GNU General Public License
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#ifndef __MIG_DECLS_H__
-#define __MIG_DECLS_H__
+#ifndef __LIBPAGER_MIG_DECLS_H__
+#define __LIBPAGER_MIG_DECLS_H__
+
+#include "priv.h"
 
-#include "proc.h"
+typedef struct pager *pager_t;
 
-typedef struct exc* exc_t;
+/* Called by server stub functions.  */
 
-static inline exc_t __attribute__ ((unused))
-begin_using_exc_port (mach_port_t port)
+static inline struct pager * __attribute__ ((unused))
+begin_using_pager (mach_port_t port)
 {
-  return ports_lookup_port (NULL, port, exc_class);
+  return ports_lookup_port (0, port, _pager_class);
 }
 
 static inline void __attribute__ ((unused))
-end_using_exc (exc_t exc)
+end_using_pager (struct pager *p)
 {
-  if (exc != NULL)
-    ports_port_deref (exc);
+  if (p)
+    ports_port_deref (p);
 }
 
-#endif
+#endif /* __LIBPAGER_MIG_DECLS_H__ */
diff --git a/proc/mig-decls.h b/libpager/mig-mutate.h
similarity index 56%
copy from proc/mig-decls.h
copy to libpager/mig-mutate.h
index 0d5bd4d..9e9065f 100644
--- a/proc/mig-decls.h
+++ b/libpager/mig-mutate.h
@@ -1,8 +1,6 @@
-/* Translation functions for mig.
-
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
+/*
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Justus Winter.
 
    This file is part of the GNU Hurd.
 
@@ -19,24 +17,13 @@
    You should have received a copy of the GNU General Public License
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#ifndef __MIG_DECLS_H__
-#define __MIG_DECLS_H__
-
-#include "proc.h"
-
-typedef struct exc* exc_t;
-
-static inline exc_t __attribute__ ((unused))
-begin_using_exc_port (mach_port_t port)
-{
-  return ports_lookup_port (NULL, port, exc_class);
-}
-
-static inline void __attribute__ ((unused))
-end_using_exc (exc_t exc)
-{
-  if (exc != NULL)
-    ports_port_deref (exc);
-}
+#define MEMORY_OBJECT_INTRAN pager_t begin_using_pager (memory_object_t)
+#define MEMORY_OBJECT_DESTRUCTOR end_using_pager (pager_t)
+#define MEMORY_OBJECT_IMPORTS import "mig-decls.h";
 
-#endif
+#define NOTIFY_INTRAN                                          \
+  port_info_t begin_using_port_info_port (mach_port_t)
+#define NOTIFY_DESTRUCTOR                                      \
+  end_using_port_info (port_info_t)
+#define NOTIFY_IMPORTS                                         \
+  import "libports/mig-decls.h";
diff --git a/libpager/no-senders.c b/libpager/no-senders.c
index 83a2c88..c21dfc2 100644
--- a/libpager/no-senders.c
+++ b/libpager/no-senders.c
@@ -18,24 +18,19 @@
 
 #include "priv.h"
 #include <mach/notify.h>
+#include "notify_S.h"
 
 error_t
-_pager_do_seqnos_mach_notify_no_senders (mach_port_t notify,
+_pager_do_seqnos_mach_notify_no_senders (struct port_info *pi,
                                         mach_port_seqno_t seqno,
                                         mach_port_mscount_t mscount)
 {
-  struct pager *p = ports_lookup_port (0, notify, _pager_class);
-  
-  if (!p)
+  if (!pi ||
+      pi->class != _pager_class)
     return EOPNOTSUPP;
-  
-  pthread_mutex_lock (&p->interlock);
-  _pager_wait_for_seqno (p, seqno);
-  _pager_release_seqno (p, seqno);
-  pthread_mutex_unlock (&p->interlock);
-  
-  ports_no_senders (p, mscount);
-
-  ports_port_deref (p);
+
+  _pager_update_seqno_p ((struct pager *) pi, seqno);
+  ports_no_senders (pi, mscount);
+
   return 0;
 }
diff --git a/libpager/notify-stubs.c b/libpager/notify-stubs.c
index 2d791aa..ba13882 100644
--- a/libpager/notify-stubs.c
+++ b/libpager/notify-stubs.c
@@ -23,54 +23,54 @@
 #include <errno.h>
 
 error_t
-_pager_do_seqnos_mach_notify_port_deleted (mach_port_t notify,
+_pager_do_seqnos_mach_notify_port_deleted (struct port_info *pi,
                                           mach_port_seqno_t seqno,
                                           mach_port_t name
                                           __attribute__ ((unused)))
 {
-  _pager_update_seqno (notify, seqno);
+  _pager_update_seqno_p ((struct pager *) pi, seqno);
 
   return 0;
 }
 
 error_t
-_pager_do_seqnos_mach_notify_msg_accepted (mach_port_t notify,
+_pager_do_seqnos_mach_notify_msg_accepted (struct port_info *pi,
                                           mach_port_seqno_t seqno,
                                           mach_port_t name
                                             __attribute__ ((unused)))
 {
-  _pager_update_seqno (notify, seqno);
+  _pager_update_seqno_p ((struct pager *) pi, seqno);
 
   return 0;
 }
 
 error_t
-_pager_do_seqnos_mach_notify_port_destroyed (mach_port_t notify,
+_pager_do_seqnos_mach_notify_port_destroyed (struct port_info *pi,
                                             mach_port_seqno_t seqno,
                                             mach_port_t name
                                               __attribute__ ((unused)))
 {
-  _pager_update_seqno (notify, seqno);
+  _pager_update_seqno_p ((struct pager *) pi, seqno);
 
   return 0;
 }
 
 error_t
-_pager_do_seqnos_mach_notify_send_once (mach_port_t notify,
+_pager_do_seqnos_mach_notify_send_once (struct port_info *pi,
                                        mach_port_seqno_t seqno)
 {
-  _pager_update_seqno (notify, seqno);
+  _pager_update_seqno_p ((struct pager *) pi, seqno);
 
   return 0;
 }
 
 error_t
-_pager_do_seqnos_mach_notify_dead_name (mach_port_t notify,
+_pager_do_seqnos_mach_notify_dead_name (struct port_info *pi,
                                        mach_port_seqno_t seqno,
                                        mach_port_t name
                                          __attribute__ ((unused)))
 {
-  _pager_update_seqno (notify, seqno);
+  _pager_update_seqno_p ((struct pager *) pi, seqno);
 
   return 0;
 }
diff --git a/libpager/object-init.c b/libpager/object-init.c
index 90ffc01..6683e24 100644
--- a/libpager/object-init.c
+++ b/libpager/object-init.c
@@ -22,16 +22,14 @@
 /* Implement the object initialiation call as described in
    <mach/memory_object.defs>.  */
 kern_return_t
-_pager_seqnos_memory_object_init (mach_port_t object, 
+_pager_seqnos_memory_object_init (struct pager *p,
                                  mach_port_seqno_t seqno,
                                  mach_port_t control,
                                  mach_port_t name,
                                  vm_size_t pagesize)
 {
-  struct pager *p;
-
-  p = ports_lookup_port (0, object, _pager_class);
-  if (!p)
+  if (!p
+      || p->port.class != _pager_class)
     return EOPNOTSUPP;
 
   pthread_mutex_lock (&p->interlock);
@@ -73,7 +71,6 @@ _pager_seqnos_memory_object_init (mach_port_t object,
  out:
   _pager_release_seqno (p, seqno);
   pthread_mutex_unlock (&p->interlock);
-  ports_port_deref (p);
 
   return 0;
 }
diff --git a/libpager/object-terminate.c b/libpager/object-terminate.c
index 896e2c2..365ba27 100644
--- a/libpager/object-terminate.c
+++ b/libpager/object-terminate.c
@@ -22,15 +22,13 @@
 /* Implement the object termination call from the kernel as described
    in <mach/memory_object.defs>. */
 kern_return_t
-_pager_seqnos_memory_object_terminate (mach_port_t object, 
+_pager_seqnos_memory_object_terminate (struct pager *p,
                                       mach_port_seqno_t seqno,
                                       mach_port_t control,
                                       mach_port_t name)
 {
-  struct pager *p;
-  
-  p = ports_lookup_port (0, object, _pager_class);
-  if (!p)
+  if (!p
+      || p->port.class != _pager_class)
     return EOPNOTSUPP;
 
   pthread_mutex_lock (&p->interlock);
@@ -79,7 +77,6 @@ _pager_seqnos_memory_object_terminate (mach_port_t object,
  out:
   _pager_release_seqno (p, seqno);
   pthread_mutex_unlock (&p->interlock);
-  ports_port_deref (p);
 
   return 0;
 }
diff --git a/libpager/priv.h b/libpager/priv.h
index 7aa0fb4..d49cbb9 100644
--- a/libpager/priv.h
+++ b/libpager/priv.h
@@ -139,6 +139,7 @@ struct port_class *_pager_class;
 void _pager_wait_for_seqno (struct pager *, mach_port_seqno_t);
 void _pager_release_seqno (struct pager *, mach_port_seqno_t);
 void _pager_update_seqno (mach_port_t, mach_port_seqno_t);
+void _pager_update_seqno_p (struct pager *, mach_port_seqno_t);
 void _pager_block_termination (struct pager *);
 void _pager_allow_termination (struct pager *);
 error_t _pager_pagemap_resize (struct pager *, vm_address_t);
diff --git a/libpager/seqnos.c b/libpager/seqnos.c
index 77bfbf2..cab2f33 100644
--- a/libpager/seqnos.c
+++ b/libpager/seqnos.c
@@ -57,13 +57,23 @@ _pager_update_seqno (mach_port_t object,
   struct pager *p;
 
   p = ports_lookup_port (0, object, _pager_class);
+  _pager_update_seqno_p (p, seqno);
   if (p)
+    ports_port_deref (p);
+}
+
+
+/* Just update the seqno, pointer version.  */
+void
+_pager_update_seqno_p (struct pager *p,
+                       mach_port_seqno_t seqno)
+{
+  if (p
+      && p->port.class == _pager_class)
     {
       pthread_mutex_lock (&p->interlock);
       _pager_wait_for_seqno (p, seqno);
       _pager_release_seqno (p, seqno);
       pthread_mutex_unlock (&p->interlock);
-
-      ports_port_deref (p);
     }
 }
diff --git a/libpager/stubs.c b/libpager/stubs.c
index 8478212..411f483 100644
--- a/libpager/stubs.c
+++ b/libpager/stubs.c
@@ -21,7 +21,7 @@
 #include <stdio.h>
 
 kern_return_t
-_pager_seqnos_memory_object_copy (mach_port_t obj,
+_pager_seqnos_memory_object_copy (struct pager *p,
                           mach_port_seqno_t seq,
                           memory_object_control_t obj_ctl,
                           vm_offset_t off,
@@ -30,13 +30,13 @@ _pager_seqnos_memory_object_copy (mach_port_t obj,
 {
   printf ("m_o_copy called\n");
 
-  _pager_update_seqno (obj, seq);
+  _pager_update_seqno_p (p, seq);
 
   return EOPNOTSUPP;
 }
 
 kern_return_t
-_pager_seqnos_memory_object_data_write (mach_port_t obj,
+_pager_seqnos_memory_object_data_write (struct pager *p,
                                 mach_port_seqno_t seq,
                                 mach_port_t ctl,
                                 vm_offset_t off,
@@ -45,13 +45,13 @@ _pager_seqnos_memory_object_data_write (mach_port_t obj,
 {
   printf ("m_o_data_write called\n");
 
-  _pager_update_seqno (obj, seq);
+  _pager_update_seqno_p (p, seq);
 
   return EOPNOTSUPP;
 }
 
 kern_return_t
-_pager_seqnos_memory_object_supply_completed (mach_port_t obj,
+_pager_seqnos_memory_object_supply_completed (struct pager *p,
                                       mach_port_seqno_t seq,
                                       mach_port_t ctl,
                                       vm_offset_t off,
@@ -61,7 +61,7 @@ _pager_seqnos_memory_object_supply_completed (mach_port_t obj,
 {
   printf ("m_o_supply_completed called\n");
 
-  _pager_update_seqno (obj, seq);
+  _pager_update_seqno_p (p, seq);
 
   return EOPNOTSUPP;
 }
diff --git a/libports/Makefile b/libports/Makefile
index 767ee73..30da1c1 100644
--- a/libports/Makefile
+++ b/libports/Makefile
@@ -45,5 +45,6 @@ LDLIBS += -lpthread
 OBJS = $(SRCS:.c=.o) notifyServer.o interruptServer.o
 
 MIGCOMSFLAGS = -prefix ports_
+MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
 
 include ../Makeconf
diff --git a/libports/bucket-iterate.c b/libports/bucket-iterate.c
index dc1c7b1..babc204 100644
--- a/libports/bucket-iterate.c
+++ b/libports/bucket-iterate.c
@@ -31,40 +31,57 @@ _ports_bucket_class_iterate (struct port_bucket *bucket,
 {
   /* This is obscenely ineffecient.  ihash and ports need to cooperate
      more closely to do it efficiently. */
-  struct item
-    {
-      struct item *next;
-      void *p;
-    } *list = 0;
-  struct item *i, *nxt;
+  void **p;
+  size_t i, n, nr_items;
   error_t err;
 
   pthread_mutex_lock (&_ports_lock);
+
+  if (bucket->htable.nr_items == 0)
+    {
+      pthread_mutex_unlock (&_ports_lock);
+      return 0;
+    }
+
+  nr_items = bucket->htable.nr_items;
+  p = malloc (nr_items * sizeof *p);
+  if (p == NULL)
+    {
+      pthread_mutex_unlock (&_ports_lock);
+      return ENOMEM;
+    }
+
+  n = 0;
   HURD_IHASH_ITERATE (&bucket->htable, arg)
     {
       struct port_info *const pi = arg;
-      struct item *j;
 
       if (class == 0 || pi->class == class)
        {
-         j = malloc (sizeof (struct item));
-         j->next = list;
-         j->p = pi;
-         list = j;
          pi->refcnt++;
+         p[n] = pi;
+         n++;
        }
     }
   pthread_mutex_unlock (&_ports_lock);
 
+  if (n != nr_items)
+    {
+      /* We allocated too much.  Release unused memory.  */
+      void **new = realloc (p, n * sizeof *p);
+      if (new)
+        p = new;
+    }
+
   err = 0;
-  for (i = list; i; i = nxt)
+  for (i = 0; i < n; i++)
     {
       if (!err)
-       err = (*fun)(i->p);
-      ports_port_deref (i->p);
-      nxt = i->next;
-      free (i);
+       err = (*fun)(p[i]);
+      ports_port_deref (p[i]);
     }
+
+  free (p);
   return err;
 }
 
diff --git a/libports/interrupt-operation.c b/libports/interrupt-operation.c
index 19c0edf..943bd4f 100644
--- a/libports/interrupt-operation.c
+++ b/libports/interrupt-operation.c
@@ -24,10 +24,9 @@
 /* Cause a pending request on this object to immediately return.  The
    exact semantics are dependent on the specific object.  */
 kern_return_t
-ports_S_interrupt_operation (mach_port_t port,
+ports_S_interrupt_operation (struct port_info *pi,
                             mach_port_seqno_t seqno)
 {
-  struct port_info *pi = ports_lookup_port (0, port, 0);
   if (!pi)
     return EOPNOTSUPP;
   pthread_mutex_lock (&_ports_lock);
@@ -35,6 +34,5 @@ ports_S_interrupt_operation (mach_port_t port,
     pi->cancel_threshold = seqno;
   pthread_mutex_unlock (&_ports_lock);
   ports_interrupt_rpcs (pi);
-  ports_port_deref (pi);
   return 0;
 }
diff --git a/libports/manage-one-thread.c b/libports/manage-one-thread.c
index 4ea740b..cbd2df7 100644
--- a/libports/manage-one-thread.c
+++ b/libports/manage-one-thread.c
@@ -85,7 +85,14 @@ ports_manage_port_operations_one_thread (struct port_bucket 
*bucket,
 
       return status;
     }
-  
+
+  /* XXX It is currently unsafe for most servers to terminate based on
+     inactivity because a request may arrive after a server has
+     started shutting down, causing the client to receive an error.
+     Prevent the service loop from terminating by setting TIMEOUT to
+     zero.  */
+  timeout = 0;
+
   do
     err = mach_msg_server_timeout (internal_demuxer, 0, bucket->portset, 
                                   timeout ? MACH_RCV_TIMEOUT : 0, timeout);
diff --git a/proc/mig-decls.h b/libports/mig-decls.h
similarity index 60%
copy from proc/mig-decls.h
copy to libports/mig-decls.h
index 0d5bd4d..f8c4f15 100644
--- a/proc/mig-decls.h
+++ b/libports/mig-decls.h
@@ -1,8 +1,6 @@
-/* Translation functions for mig.
-
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
+/*
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Justus Winter.
 
    This file is part of the GNU Hurd.
 
@@ -19,24 +17,24 @@
    You should have received a copy of the GNU General Public License
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#ifndef __MIG_DECLS_H__
-#define __MIG_DECLS_H__
+#ifndef __LIBPORTS_MIG_DECLS_H__
+#define __LIBPORTS_MIG_DECLS_H__
 
-#include "proc.h"
+#include "ports.h"
 
-typedef struct exc* exc_t;
+/* Called by server stub functions.  */
 
-static inline exc_t __attribute__ ((unused))
-begin_using_exc_port (mach_port_t port)
+static inline struct port_info * __attribute__ ((unused))
+begin_using_port_info_port (mach_port_t port)
 {
-  return ports_lookup_port (NULL, port, exc_class);
+  return ports_lookup_port (0, port, 0);
 }
 
 static inline void __attribute__ ((unused))
-end_using_exc (exc_t exc)
+end_using_port_info (struct port_info *p)
 {
-  if (exc != NULL)
-    ports_port_deref (exc);
+  if (p)
+    ports_port_deref (p);
 }
 
-#endif
+#endif /* __LIBPORTS_MIG_DECLS_H__ */
diff --git a/proc/mig-decls.h b/libports/mig-mutate.h
similarity index 56%
copy from proc/mig-decls.h
copy to libports/mig-mutate.h
index 0d5bd4d..4c011b6 100644
--- a/proc/mig-decls.h
+++ b/libports/mig-mutate.h
@@ -1,8 +1,6 @@
-/* Translation functions for mig.
-
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
+/*
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Justus Winter.
 
    This file is part of the GNU Hurd.
 
@@ -19,24 +17,16 @@
    You should have received a copy of the GNU General Public License
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#ifndef __MIG_DECLS_H__
-#define __MIG_DECLS_H__
-
-#include "proc.h"
-
-typedef struct exc* exc_t;
-
-static inline exc_t __attribute__ ((unused))
-begin_using_exc_port (mach_port_t port)
-{
-  return ports_lookup_port (NULL, port, exc_class);
-}
-
-static inline void __attribute__ ((unused))
-end_using_exc (exc_t exc)
-{
-  if (exc != NULL)
-    ports_port_deref (exc);
-}
-
-#endif
+#define NOTIFY_INTRAN                                          \
+  port_info_t begin_using_port_info_port (mach_port_t)
+#define NOTIFY_DESTRUCTOR                                      \
+  end_using_port_info (port_info_t)
+#define NOTIFY_IMPORTS                                         \
+  import "libports/mig-decls.h";
+
+#define INTERRUPT_INTRAN                                       \
+  port_info_t begin_using_port_info_port (mach_port_t)
+#define INTERRUPT_DESTRUCTOR                                   \
+  end_using_port_info (port_info_t)
+#define INTERRUPT_IMPORTS                                      \
+  import "libports/mig-decls.h";
diff --git a/libports/notify-dead-name.c b/libports/notify-dead-name.c
index c67145d..f974e33 100644
--- a/libports/notify-dead-name.c
+++ b/libports/notify-dead-name.c
@@ -22,13 +22,12 @@
 #include "notify_S.h"
 
 error_t
-ports_do_mach_notify_dead_name (mach_port_t notify, mach_port_t dead_name)
+ports_do_mach_notify_dead_name (struct port_info *pi,
+                               mach_port_t dead_name)
 {
-  void *pi = ports_lookup_port (0, notify, 0);
   if (!pi)
     return EOPNOTSUPP;
   ports_dead_name (pi, dead_name);
-  ports_port_deref (pi);
 
   /* Drop gratuitous extra reference that the notification creates. */
   mach_port_deallocate (mach_task_self (), dead_name);
diff --git a/libports/notify-msg-accepted.c b/libports/notify-msg-accepted.c
index c975083..0e49715 100644
--- a/libports/notify-msg-accepted.c
+++ b/libports/notify-msg-accepted.c
@@ -22,7 +22,8 @@
 #include "notify_S.h"
 
 error_t
-ports_do_mach_notify_msg_accepted (mach_port_t notify, mach_port_t name)
+ports_do_mach_notify_msg_accepted (struct port_info *pi,
+                                  mach_port_t name)
 {
   return 0;
 }
diff --git a/libports/notify-no-senders.c b/libports/notify-no-senders.c
index dc9b316..55aa853 100644
--- a/libports/notify-no-senders.c
+++ b/libports/notify-no-senders.c
@@ -22,12 +22,11 @@
 #include "notify_S.h"
 
 error_t
-ports_do_mach_notify_no_senders (mach_port_t port, mach_port_mscount_t count)
+ports_do_mach_notify_no_senders (struct port_info *pi,
+                                mach_port_mscount_t count)
 {
-  void *pi = ports_lookup_port (0, port, 0);
   if (!pi)
     return EOPNOTSUPP;
   ports_no_senders (pi, count);
-  ports_port_deref (pi);
   return 0;
 }
diff --git a/libports/notify-port-deleted.c b/libports/notify-port-deleted.c
index 85012af..cfd3379 100644
--- a/libports/notify-port-deleted.c
+++ b/libports/notify-port-deleted.c
@@ -22,7 +22,8 @@
 #include "notify_S.h"
 
 error_t
-ports_do_mach_notify_port_deleted (mach_port_t notify, mach_port_t name)
+ports_do_mach_notify_port_deleted (struct port_info *pi,
+                                  mach_port_t name)
 {
   return 0;
 }
diff --git a/libports/notify-port-destroyed.c b/libports/notify-port-destroyed.c
index 78eaf21..b8ece2a 100644
--- a/libports/notify-port-destroyed.c
+++ b/libports/notify-port-destroyed.c
@@ -22,7 +22,8 @@
 #include "notify_S.h"
 
 error_t
-ports_do_mach_notify_port_destroyed (mach_port_t notify, mach_port_t name)
+ports_do_mach_notify_port_destroyed (struct port_info *pi,
+                                    mach_port_t name)
 {
   return 0;
 }
diff --git a/libports/notify-send-once.c b/libports/notify-send-once.c
index 09ffcf2..ad0ba33 100644
--- a/libports/notify-send-once.c
+++ b/libports/notify-send-once.c
@@ -22,7 +22,7 @@
 #include "notify_S.h"
 
 error_t
-ports_do_mach_notify_send_once (mach_port_t notify)
+ports_do_mach_notify_send_once (struct port_info *pi)
 {
   return 0;
 }
diff --git a/libports/ports.h b/libports/ports.h
index 0791841..7f13124 100644
--- a/libports/ports.h
+++ b/libports/ports.h
@@ -50,6 +50,8 @@ struct port_info
   hurd_ihash_locp_t hentry;
   struct port_info *next, **prevp; /* links on port_class list */
 };
+typedef struct port_info *port_info_t;
+
 /* FLAGS above are the following: */
 #define PORT_HAS_SENDRIGHTS    0x0001 /* send rights extant */
 #define PORT_INHIBITED         PORTS_INHIBITED
@@ -383,18 +385,19 @@ void ports_interrupt_notified_rpcs (void *object, 
mach_port_t port,
 int ports_notify_server (mach_msg_header_t *, mach_msg_header_t *);
 
 /* Notification server routines called by ports_notify_server.  */
-extern kern_return_t ports_do_mach_notify_dead_name (mach_port_t notify, 
mach_port_t deadport);
-extern kern_return_t ports_do_mach_notify_msg_accepted (mach_port_t notify, 
mach_port_t name);
-extern kern_return_t ports_do_mach_notify_no_senders (mach_port_t port, 
mach_port_mscount_t count);
-extern kern_return_t ports_do_mach_notify_port_deleted (mach_port_t notify, 
mach_port_t name);
-extern kern_return_t ports_do_mach_notify_port_destroyed (mach_port_t notify, 
mach_port_t name);
 extern kern_return_t
- ports_do_mach_notify_send_once (mach_port_t notify);
-
-/* A default interrupt server */
-int ports_interrupt_server (mach_msg_header_t *, mach_msg_header_t *);
-extern kern_return_t ports_S_interrupt_operation (mach_port_t,
-                                                 mach_port_seqno_t);
+ ports_do_mach_notify_dead_name (struct port_info *pi, mach_port_t deadport);
+extern kern_return_t
+ ports_do_mach_notify_msg_accepted (struct port_info *pi, mach_port_t name);
+extern kern_return_t
+ ports_do_mach_notify_no_senders (struct port_info *pi,
+                                 mach_port_mscount_t count);
+extern kern_return_t
+ ports_do_mach_notify_port_deleted (struct port_info *pi, mach_port_t name);
+extern kern_return_t
+ ports_do_mach_notify_port_destroyed (struct port_info *pi, mach_port_t name);
+extern kern_return_t
+ ports_do_mach_notify_send_once (struct port_info *pi);
 
 /* Private data */
 extern pthread_mutex_t _ports_lock;
diff --git a/libtrivfs/file-access.c b/libtrivfs/file-access.c
index 8702954..f289a23 100644
--- a/libtrivfs/file-access.c
+++ b/libtrivfs/file-access.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 error_t
 trivfs_S_file_check_access (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-chauthor.c b/libtrivfs/file-chauthor.c
index 0460bfe..660181c 100644
--- a/libtrivfs/file-chauthor.c
+++ b/libtrivfs/file-chauthor.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 kern_return_t
 trivfs_S_file_chauthor (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-chflags.c b/libtrivfs/file-chflags.c
index c28f12f..d427015 100644
--- a/libtrivfs/file-chflags.c
+++ b/libtrivfs/file-chflags.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 kern_return_t
 trivfs_S_file_chflags (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-chg.c b/libtrivfs/file-chg.c
index 3af71b3..0e8c839 100644
--- a/libtrivfs/file-chg.c
+++ b/libtrivfs/file-chg.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 kern_return_t
 trivfs_S_file_notice_changes (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-chmod.c b/libtrivfs/file-chmod.c
index f42a43c..8c15ec2 100644
--- a/libtrivfs/file-chmod.c
+++ b/libtrivfs/file-chmod.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 kern_return_t
 trivfs_S_file_chmod (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-chown.c b/libtrivfs/file-chown.c
index 44f7920..416103f 100644
--- a/libtrivfs/file-chown.c
+++ b/libtrivfs/file-chown.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 kern_return_t
 trivfs_S_file_chown (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-exec.c b/libtrivfs/file-exec.c
index a3ab048..b353d8a 100644
--- a/libtrivfs/file-exec.c
+++ b/libtrivfs/file-exec.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 kern_return_t
 trivfs_S_file_exec (trivfs_protid_t exec_file,
diff --git a/libtrivfs/file-get-children.c b/libtrivfs/file-get-children.c
index a3afbba..4126119 100644
--- a/libtrivfs/file-get-children.c
+++ b/libtrivfs/file-get-children.c
@@ -20,6 +20,7 @@
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 /* Return any active translators bound to nodes of the receiving
    filesystem.  CHILDREN is an argz vector containing file names
diff --git a/libtrivfs/file-get-fs-options.c b/libtrivfs/file-get-fs-options.c
index 2e06c2d..3c8bbca 100644
--- a/libtrivfs/file-get-fs-options.c
+++ b/libtrivfs/file-get-fs-options.c
@@ -22,6 +22,7 @@
 #include <hurd/fshelp.h>
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 error_t
 trivfs_S_file_get_fs_options (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-get-source.c b/libtrivfs/file-get-source.c
index 35636b5..f6637d8 100644
--- a/libtrivfs/file-get-source.c
+++ b/libtrivfs/file-get-source.c
@@ -20,6 +20,7 @@
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 /* Return information about the source of the receiving
    filesystem. */
diff --git a/libtrivfs/file-get-storage-info.c 
b/libtrivfs/file-get-storage-info.c
index 58bdbc5..60fdc98 100644
--- a/libtrivfs/file-get-storage-info.c
+++ b/libtrivfs/file-get-storage-info.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 error_t
 trivfs_S_file_get_storage_info (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-get-trans.c b/libtrivfs/file-get-trans.c
index 687dc8c..69de453 100644
--- a/libtrivfs/file-get-trans.c
+++ b/libtrivfs/file-get-trans.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 kern_return_t
 trivfs_S_file_get_translator (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-get-transcntl.c b/libtrivfs/file-get-transcntl.c
index 8af08fc..7deb304 100644
--- a/libtrivfs/file-get-transcntl.c
+++ b/libtrivfs/file-get-transcntl.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 kern_return_t
 trivfs_S_file_get_translator_cntl (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-getcontrol.c b/libtrivfs/file-getcontrol.c
index 2a58016..36c2ca3 100644
--- a/libtrivfs/file-getcontrol.c
+++ b/libtrivfs/file-getcontrol.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 kern_return_t
 trivfs_S_file_getcontrol (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-getfh.c b/libtrivfs/file-getfh.c
index 35deb7d..d585936 100644
--- a/libtrivfs/file-getfh.c
+++ b/libtrivfs/file-getfh.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 kern_return_t
 trivfs_S_file_getfh (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-getlinknode.c b/libtrivfs/file-getlinknode.c
index 078e5de..1802d9a 100644
--- a/libtrivfs/file-getlinknode.c
+++ b/libtrivfs/file-getlinknode.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 kern_return_t
 trivfs_S_file_getlinknode (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-lock.c b/libtrivfs/file-lock.c
index 993baff..c89f2fa 100644
--- a/libtrivfs/file-lock.c
+++ b/libtrivfs/file-lock.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 kern_return_t
 trivfs_S_file_lock (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-reparent.c b/libtrivfs/file-reparent.c
index 0682a91..5892013 100644
--- a/libtrivfs/file-reparent.c
+++ b/libtrivfs/file-reparent.c
@@ -19,6 +19,8 @@
    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
+#include "trivfs_io_S.h"
 
 error_t
 trivfs_S_file_reparent (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-set-size.c b/libtrivfs/file-set-size.c
index 287ed99..f90ceec 100644
--- a/libtrivfs/file-set-size.c
+++ b/libtrivfs/file-set-size.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 #include <assert.h>
 
 kern_return_t
diff --git a/libtrivfs/file-set-trans.c b/libtrivfs/file-set-trans.c
index 339bdb2..47a7f7c 100644
--- a/libtrivfs/file-set-trans.c
+++ b/libtrivfs/file-set-trans.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 kern_return_t
 trivfs_S_file_set_translator (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-statfs.c b/libtrivfs/file-statfs.c
index 648eef6..348126e 100644
--- a/libtrivfs/file-statfs.c
+++ b/libtrivfs/file-statfs.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 #include <string.h>
 #include <unistd.h>
 
diff --git a/libtrivfs/file-sync.c b/libtrivfs/file-sync.c
index cb0add3..f26f3c1 100644
--- a/libtrivfs/file-sync.c
+++ b/libtrivfs/file-sync.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 kern_return_t
 trivfs_S_file_sync (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-syncfs.c b/libtrivfs/file-syncfs.c
index d356296..e379df2 100644
--- a/libtrivfs/file-syncfs.c
+++ b/libtrivfs/file-syncfs.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 kern_return_t
 trivfs_S_file_syncfs (struct trivfs_protid *cred,
diff --git a/libtrivfs/file-utimes.c b/libtrivfs/file-utimes.c
index f9bedd7..827c055 100644
--- a/libtrivfs/file-utimes.c
+++ b/libtrivfs/file-utimes.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fs_S.h"
 
 kern_return_t
 trivfs_S_file_utimes (struct trivfs_protid *cred,
diff --git a/libtrivfs/fsys-forward.c b/libtrivfs/fsys-forward.c
index 106360e..8f92d45 100644
--- a/libtrivfs/fsys-forward.c
+++ b/libtrivfs/fsys-forward.c
@@ -21,6 +21,7 @@
    the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
 
 #include "priv.h"
+#include "trivfs_fsys_S.h"
 
 /* Ask SERVER to provide fsys translation service for us.  REQUESTOR is
    the bootstrap port supplied to the original translator, and ARGV are
diff --git a/libtrivfs/fsys-get-options.c b/libtrivfs/fsys-get-options.c
index 4f2d602..8030435 100644
--- a/libtrivfs/fsys-get-options.c
+++ b/libtrivfs/fsys-get-options.c
@@ -22,6 +22,7 @@
 #include <hurd/fshelp.h>
 
 #include "priv.h"
+#include "trivfs_fsys_S.h"
 
 error_t
 trivfs_S_fsys_get_options (struct trivfs_control *fsys,
diff --git a/libtrivfs/fsys-getroot.c b/libtrivfs/fsys-getroot.c
index 60528d7..d343e14 100644
--- a/libtrivfs/fsys-getroot.c
+++ b/libtrivfs/fsys-getroot.c
@@ -21,6 +21,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 
 #include "priv.h"
 #include "fsys_reply_U.h"
+#include "trivfs_fsys_S.h"
 #include <assert.h>
 #include <fcntl.h>
 #include <string.h>
diff --git a/libtrivfs/fsys-goaway.c b/libtrivfs/fsys-goaway.c
index 1ad119b..d551d55 100644
--- a/libtrivfs/fsys-goaway.c
+++ b/libtrivfs/fsys-goaway.c
@@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell.  */
 
 #include "priv.h"
+#include "trivfs_fsys_S.h"
 
 kern_return_t
 trivfs_S_fsys_goaway (struct trivfs_control *cred,
diff --git a/libtrivfs/fsys-set-options.c b/libtrivfs/fsys-set-options.c
index 43890df..135bc74 100644
--- a/libtrivfs/fsys-set-options.c
+++ b/libtrivfs/fsys-set-options.c
@@ -21,6 +21,7 @@
 #include <hurd/fshelp.h>
 
 #include "priv.h"
+#include "trivfs_fsys_S.h"
 
 error_t
 trivfs_S_fsys_set_options (struct trivfs_control *cntl,
diff --git a/libtrivfs/fsys-stubs.c b/libtrivfs/fsys-stubs.c
index 2899075..bcac43c 100644
--- a/libtrivfs/fsys-stubs.c
+++ b/libtrivfs/fsys-stubs.c
@@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell.  */
 
 #include "priv.h"
+#include "trivfs_fsys_S.h"
 
 kern_return_t
 trivfs_S_fsys_startup (mach_port_t bootport,
diff --git a/libtrivfs/fsys-syncfs.c b/libtrivfs/fsys-syncfs.c
index e94fda3..0c337f4 100644
--- a/libtrivfs/fsys-syncfs.c
+++ b/libtrivfs/fsys-syncfs.c
@@ -19,6 +19,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_fsys_S.h"
 
 kern_return_t
 trivfs_S_fsys_syncfs (struct trivfs_control *cntl,
diff --git a/libtrivfs/io-async-icky.c b/libtrivfs/io-async-icky.c
index bd9c549..3e0cf6f 100644
--- a/libtrivfs/io-async-icky.c
+++ b/libtrivfs/io-async-icky.c
@@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell.  */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <assert.h>
 
 kern_return_t
diff --git a/libtrivfs/io-async.c b/libtrivfs/io-async.c
index b02f57f..874c589 100644
--- a/libtrivfs/io-async.c
+++ b/libtrivfs/io-async.c
@@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell.  */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <assert.h>
 
 kern_return_t
diff --git a/libtrivfs/io-duplicate.c b/libtrivfs/io-duplicate.c
index c1b7798..5e2fabf 100644
--- a/libtrivfs/io-duplicate.c
+++ b/libtrivfs/io-duplicate.c
@@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell.  */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <string.h>
 
 kern_return_t
diff --git a/libtrivfs/io-identity.c b/libtrivfs/io-identity.c
index 44f60d3..a67ed7e 100644
--- a/libtrivfs/io-identity.c
+++ b/libtrivfs/io-identity.c
@@ -19,6 +19,7 @@
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA. */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 
 error_t
 trivfs_S_io_identity (struct trivfs_protid *cred,
diff --git a/libtrivfs/io-map.c b/libtrivfs/io-map.c
index 2959efb..39428ad 100644
--- a/libtrivfs/io-map.c
+++ b/libtrivfs/io-map.c
@@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell.  */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <assert.h>
 
 kern_return_t
diff --git a/libtrivfs/io-modes-get.c b/libtrivfs/io-modes-get.c
index 4d38d3a..9ed591c 100644
--- a/libtrivfs/io-modes-get.c
+++ b/libtrivfs/io-modes-get.c
@@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell.  */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <assert.h>
 
 kern_return_t
diff --git a/libtrivfs/io-modes-off.c b/libtrivfs/io-modes-off.c
index 33b0a57..786f0a1 100644
--- a/libtrivfs/io-modes-off.c
+++ b/libtrivfs/io-modes-off.c
@@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell.  */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <assert.h>
 
 kern_return_t
diff --git a/libtrivfs/io-modes-on.c b/libtrivfs/io-modes-on.c
index 7886dc5..74b10ad 100644
--- a/libtrivfs/io-modes-on.c
+++ b/libtrivfs/io-modes-on.c
@@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell.  */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <assert.h>
 
 kern_return_t
diff --git a/libtrivfs/io-modes-set.c b/libtrivfs/io-modes-set.c
index c1bc740..bc57626 100644
--- a/libtrivfs/io-modes-set.c
+++ b/libtrivfs/io-modes-set.c
@@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell.  */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <assert.h>
 
 error_t
diff --git a/libtrivfs/io-owner-get.c b/libtrivfs/io-owner-get.c
index f6c261c..5ffce4d 100644
--- a/libtrivfs/io-owner-get.c
+++ b/libtrivfs/io-owner-get.c
@@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell.  */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <assert.h>
 
 kern_return_t
diff --git a/libtrivfs/io-owner-mod.c b/libtrivfs/io-owner-mod.c
index 4e96a24..8b85e7c 100644
--- a/libtrivfs/io-owner-mod.c
+++ b/libtrivfs/io-owner-mod.c
@@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell.  */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <assert.h>
 
 kern_return_t
diff --git a/libtrivfs/io-pathconf.c b/libtrivfs/io-pathconf.c
index 51d4e09..f4a4edf 100644
--- a/libtrivfs/io-pathconf.c
+++ b/libtrivfs/io-pathconf.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 
 kern_return_t
 trivfs_S_io_pathconf (struct trivfs_protid *cred,
diff --git a/libtrivfs/io-read.c b/libtrivfs/io-read.c
index dcba818..7dfdc19 100644
--- a/libtrivfs/io-read.c
+++ b/libtrivfs/io-read.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <assert.h>
 
 kern_return_t
diff --git a/libtrivfs/io-readable.c b/libtrivfs/io-readable.c
index 792bd1a..90e66c7 100644
--- a/libtrivfs/io-readable.c
+++ b/libtrivfs/io-readable.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <assert.h>
 
 kern_return_t
diff --git a/libtrivfs/io-reauthenticate.c b/libtrivfs/io-reauthenticate.c
index 6623d94..7677697 100644
--- a/libtrivfs/io-reauthenticate.c
+++ b/libtrivfs/io-reauthenticate.c
@@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell.  */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <assert.h>
 #include <string.h>
 
diff --git a/libtrivfs/io-restrict-auth.c b/libtrivfs/io-restrict-auth.c
index db3c99a..65b4fd6 100644
--- a/libtrivfs/io-restrict-auth.c
+++ b/libtrivfs/io-restrict-auth.c
@@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell.  */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <string.h>
 
 /* Tell if the array LIST (of size N) contains a member equal to QUERY. */
diff --git a/libtrivfs/io-revoke.c b/libtrivfs/io-revoke.c
index 901de4c..b2fc00e 100644
--- a/libtrivfs/io-revoke.c
+++ b/libtrivfs/io-revoke.c
@@ -17,6 +17,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 
 /* Implement io_revoke as described in <hurd/io.defs>. */
 kern_return_t
diff --git a/libtrivfs/io-seek.c b/libtrivfs/io-seek.c
index 8e794cf..cfb7f53 100644
--- a/libtrivfs/io-seek.c
+++ b/libtrivfs/io-seek.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <assert.h>
 
 kern_return_t
diff --git a/libtrivfs/io-select.c b/libtrivfs/io-select.c
index e44a836..78018bb 100644
--- a/libtrivfs/io-select.c
+++ b/libtrivfs/io-select.c
@@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell.  */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <assert.h>
 
 kern_return_t
diff --git a/libtrivfs/io-stat.c b/libtrivfs/io-stat.c
index 6e430a2..7004741 100644
--- a/libtrivfs/io-stat.c
+++ b/libtrivfs/io-stat.c
@@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell.  */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <unistd.h>
 
 kern_return_t
diff --git a/libtrivfs/io-stubs.c b/libtrivfs/io-stubs.c
index a8cf3f5..af3ad38 100644
--- a/libtrivfs/io-stubs.c
+++ b/libtrivfs/io-stubs.c
@@ -20,6 +20,7 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 /* Written by Michael I. Bushnell.  */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 
 kern_return_t
 trivfs_S_io_map_cntl (struct trivfs_protid *cred,
diff --git a/libtrivfs/io-version.c b/libtrivfs/io-version.c
index ff820db..e656d5c 100644
--- a/libtrivfs/io-version.c
+++ b/libtrivfs/io-version.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 
 kern_return_t
 trivfs_S_io_server_version (trivfs_protid_t obj,
diff --git a/libtrivfs/io-write.c b/libtrivfs/io-write.c
index 106031d..c479c55 100644
--- a/libtrivfs/io-write.c
+++ b/libtrivfs/io-write.c
@@ -16,6 +16,7 @@
    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
 
 #include "priv.h"
+#include "trivfs_io_S.h"
 #include <assert.h>
 #include <fcntl.h>
 
diff --git a/libtrivfs/mig-mutate.h b/libtrivfs/mig-mutate.h
index fad5389..cc15d38 100644
--- a/libtrivfs/mig-mutate.h
+++ b/libtrivfs/mig-mutate.h
@@ -21,12 +21,12 @@
 
 #define FILE_INTRAN trivfs_protid_t trivfs_begin_using_protid (file_t)
 #define FILE_DESTRUCTOR trivfs_end_using_protid (trivfs_protid_t)
-#define FILE_IMPORTS import "mig-decls.h";
+#define FILE_IMPORTS import "libtrivfs/mig-decls.h";
 
 #define IO_INTRAN trivfs_protid_t trivfs_begin_using_protid (io_t)
 #define IO_DESTRUCTOR trivfs_end_using_protid (trivfs_protid_t)
-#define IO_IMPORTS import "mig-decls.h";
+#define IO_IMPORTS import "libtrivfs/mig-decls.h";
 
 #define FSYS_INTRAN trivfs_control_t trivfs_begin_using_control (fsys_t)
 #define FSYS_DESTRUCTOR trivfs_end_using_control (trivfs_control_t)
-#define FSYS_IMPORTS import "mig-decls.h";
+#define FSYS_IMPORTS import "libtrivfs/mig-decls.h";
diff --git a/pfinet/tunnel.c b/pfinet/tunnel.c
index 495356c..6a7f355 100644
--- a/pfinet/tunnel.c
+++ b/pfinet/tunnel.c
@@ -36,6 +36,9 @@
 #include <linux/ppp_defs.h>
 #include <linux/if_ppp.h>
 
+#include "libtrivfs/trivfs_fs_S.h"
+#include "libtrivfs/trivfs_io_S.h"
+
 struct port_class *tunnel_cntlclass;
 struct port_class *tunnel_class;
 
diff --git a/proc/Makefile b/proc/Makefile
index 2eed13c..aa31ffb 100644
--- a/proc/Makefile
+++ b/proc/Makefile
@@ -24,9 +24,7 @@ target = proc
 SRCS = wait.c hash.c host.c info.c main.c mgt.c        notify.c pgrp.c msg.c \
        cpu-types.c stubs.c
 
-MIGSFLAGS="-DPROCESS_INTRAN=pstruct_t reqport_find (process_t)" \
-       "-DPROCESS_DESTRUCTOR=process_drop (pstruct_t)" \
-       "-DPROCESS_IMPORTS=import \"proc.h\";"
+MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h
 
 MIGSTUBS = processServer.o notifyServer.o \
        ourmsgUser.o proc_excUser.o proc_excServer.o
diff --git a/proc/hash.c b/proc/hash.c
index ed670a1..e4dc5ff 100644
--- a/proc/hash.c
+++ b/proc/hash.c
@@ -76,17 +76,6 @@ task_find_nocreate (task_t task)
   return (!p || p->p_dead) ? 0 : p;
 }
 
-/* Find the process corresponding to a given request port. */
-struct proc *
-reqport_find (mach_port_t reqport)
-{
-  struct proc *p;
-  p = ports_lookup_port (proc_bucket, reqport, proc_class);
-  if (p && p->p_dead)
-    ports_port_deref (p);
-  return (!p || p->p_dead) ? 0 : p;
-}
-
 /* Find the process group corresponding to a given pgid. */
 struct pgrp *
 pgrp_find (pid_t pgid)
diff --git a/proc/mgt.c b/proc/mgt.c
index 5e0accd..b8aa0fc 100644
--- a/proc/mgt.c
+++ b/proc/mgt.c
@@ -435,7 +435,6 @@ S_proc_exception_raise (struct exc *e,
   if (! p)
     {
       /* Bogus RPC.  */
-      ports_port_deref (e);
       return EINVAL;
     }
 
diff --git a/proc/mig-decls.h b/proc/mig-decls.h
index 0d5bd4d..7d36a87 100644
--- a/proc/mig-decls.h
+++ b/proc/mig-decls.h
@@ -24,6 +24,24 @@
 
 #include "proc.h"
 
+/* Find the process corresponding to a given request port. */
+static inline struct proc * __attribute__ ((unused))
+begin_using_proc_port (mach_port_t port)
+{
+  struct proc *p;
+  p = ports_lookup_port (proc_bucket, port, proc_class);
+  if (p && p->p_dead)
+    ports_port_deref (p);
+  return (!p || p->p_dead) ? NULL : p;
+}
+
+static inline void __attribute__ ((unused))
+end_using_proc (struct proc *p)
+{
+  if (p)
+    ports_port_deref (p);
+}
+
 typedef struct exc* exc_t;
 
 static inline exc_t __attribute__ ((unused))
diff --git a/proc/mig-decls.h b/proc/mig-mutate.h
similarity index 56%
copy from proc/mig-decls.h
copy to proc/mig-mutate.h
index 0d5bd4d..ce9f88e 100644
--- a/proc/mig-decls.h
+++ b/proc/mig-mutate.h
@@ -1,8 +1,6 @@
-/* Translation functions for mig.
-
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
+/*
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Justus Winter.
 
    This file is part of the GNU Hurd.
 
@@ -19,24 +17,17 @@
    You should have received a copy of the GNU General Public License
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#ifndef __MIG_DECLS_H__
-#define __MIG_DECLS_H__
-
-#include "proc.h"
-
-typedef struct exc* exc_t;
-
-static inline exc_t __attribute__ ((unused))
-begin_using_exc_port (mach_port_t port)
-{
-  return ports_lookup_port (NULL, port, exc_class);
-}
 
-static inline void __attribute__ ((unused))
-end_using_exc (exc_t exc)
-{
-  if (exc != NULL)
-    ports_port_deref (exc);
-}
+#define PROCESS_INTRAN                                         \
+  pstruct_t begin_using_proc_port (process_t)
+#define PROCESS_DESTRUCTOR                                     \
+  end_using_proc (pstruct_t)
+#define PROCESS_IMPORTS                                                \
+  import "mig-decls.h";
 
-#endif
+#define NOTIFY_INTRAN                                          \
+  port_info_t begin_using_port_info_port (mach_port_t)
+#define NOTIFY_DESTRUCTOR                                      \
+  end_using_port_info (port_info_t)
+#define NOTIFY_IMPORTS                                         \
+  import "libports/mig-decls.h";
diff --git a/proc/notify.c b/proc/notify.c
index 5a112b0..b6731ae 100644
--- a/proc/notify.c
+++ b/proc/notify.c
@@ -36,33 +36,33 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
    message ports die.  Both notifications get sent to the process
    port.   */
 kern_return_t
-do_mach_notify_dead_name (mach_port_t notify,
+do_mach_notify_dead_name (struct port_info *pi,
                          mach_port_t deadport)
 {
   struct proc *p;
 
-  if (notify == generic_port)
+  if (pi->port_right == generic_port)
     {
       check_dead_execdata_notify (deadport);
       mach_port_deallocate (mach_task_self (), deadport);
       return 0;
     }
 
-  p = ports_lookup_port (proc_bucket, notify, proc_class);
+  p = (struct proc *) pi;
 
-  if (!p)
+  if (!p
+      || p->p_pi.bucket != proc_bucket
+      || p->p_pi.class != proc_class)
     return EOPNOTSUPP;
 
   if (p->p_task == deadport)
     {
       process_has_exited (p);
-      ports_port_deref (p);
       mach_port_deallocate (mach_task_self (), deadport);
       return 0;
     }
   else
     {
-      ports_port_deref (p);
       return EINVAL;
     }
 }
@@ -70,35 +70,35 @@ do_mach_notify_dead_name (mach_port_t notify,
 /* We get no-senders notifications on exception ports that we
    handle through proc_handle_exceptions. */
 kern_return_t
-do_mach_notify_no_senders (mach_port_t notify,
+do_mach_notify_no_senders (struct port_info *pi,
                           mach_port_mscount_t mscount)
 {
-  return ports_do_mach_notify_no_senders (notify, mscount);
+  return ports_do_mach_notify_no_senders (pi, mscount);
 }
 
 kern_return_t
-do_mach_notify_port_deleted (mach_port_t notify,
+do_mach_notify_port_deleted (struct port_info *pi,
                             mach_port_t name)
 {
   return 0;
 }
 
 kern_return_t
-do_mach_notify_msg_accepted (mach_port_t notify,
+do_mach_notify_msg_accepted (struct port_info *pi,
                             mach_port_t name)
 {
   return 0;
 }
 
 kern_return_t
-do_mach_notify_port_destroyed (mach_port_t notify,
+do_mach_notify_port_destroyed (struct port_info *pi,
                               mach_port_t name)
 {
   return 0;
 }
 
 kern_return_t
-do_mach_notify_send_once (mach_port_t notify)
+do_mach_notify_send_once (struct port_info *pi)
 {
   return 0;
 }
diff --git a/proc/proc.h b/proc/proc.h
index 12f56da..a2e3c53 100644
--- a/proc/proc.h
+++ b/proc/proc.h
@@ -145,13 +145,6 @@ mach_port_t generic_port;  /* messages not related to a 
specific proc */
 
 pthread_mutex_t global_lock;
 
-static inline void __attribute__ ((unused))
-process_drop (struct proc *p)
-{
-  if (p)
-    ports_port_deref (p);
-}
-
 /* Forward declarations */
 void complete_wait (struct proc *, int);
 int check_uid (struct proc *, uid_t);
diff --git a/random/Makefile b/random/Makefile
index 0949b63..6291da0 100644
--- a/random/Makefile
+++ b/random/Makefile
@@ -26,5 +26,6 @@ OBJS = $(SRCS:.c=.o) startup_notifyServer.o
 LCLHDRS = gnupg-random.h gnupg-rmd.h gnupg-bithelp.h random.h
 HURDLIBS = trivfs ports fshelp ihash shouldbeinlibc
 OTHERLIBS = -lpthread
+MIGSFLAGS = -DSEQNOS -imacros $(srcdir)/mig-mutate.h
 
 include ../Makeconf
diff --git a/proc/mig-decls.h b/random/mig-decls.h
similarity index 51%
copy from proc/mig-decls.h
copy to random/mig-decls.h
index 0d5bd4d..87b7eb2 100644
--- a/proc/mig-decls.h
+++ b/random/mig-decls.h
@@ -1,8 +1,6 @@
-/* Translation functions for mig.
-
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
+/*
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Justus Winter.
 
    This file is part of the GNU Hurd.
 
@@ -19,24 +17,31 @@
    You should have received a copy of the GNU General Public License
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#ifndef __MIG_DECLS_H__
-#define __MIG_DECLS_H__
+#ifndef __RANDOM_MIG_DECLS_H__
+#define __RANDOM_MIG_DECLS_H__
+
+#include <hurd/ports.h>
+
+typedef struct port_info *port_info_t;
 
-#include "proc.h"
+extern struct trivfs_control *fsys;
+extern struct port_class *shutdown_notify_class;
 
-typedef struct exc* exc_t;
+/* Called by server stub functions.  */
 
-static inline exc_t __attribute__ ((unused))
-begin_using_exc_port (mach_port_t port)
+static inline struct port_info * __attribute__ ((unused))
+begin_using_startup_port (mach_port_t port)
 {
-  return ports_lookup_port (NULL, port, exc_class);
+  return ports_lookup_port (fsys->pi.bucket,
+                            handle,
+                            shutdown_notify_class);
 }
 
 static inline void __attribute__ ((unused))
-end_using_exc (exc_t exc)
+end_using_startup (struct port_info *p)
 {
-  if (exc != NULL)
-    ports_port_deref (exc);
+  if (p)
+    ports_port_deref (p);
 }
 
-#endif
+#endif /* __RANDOM_MIG_DECLS_H__ */
diff --git a/proc/mig-decls.h b/random/mig-mutate.h
similarity index 56%
copy from proc/mig-decls.h
copy to random/mig-mutate.h
index 0d5bd4d..dab89e5 100644
--- a/proc/mig-decls.h
+++ b/random/mig-mutate.h
@@ -1,8 +1,6 @@
-/* Translation functions for mig.
-
-   Copyright (C) 2013 Free Software Foundation, Inc.
-
-   Written by Justus Winter <address@hidden>
+/*
+   Copyright (C) 2014 Free Software Foundation, Inc.
+   Written by Justus Winter.
 
    This file is part of the GNU Hurd.
 
@@ -19,24 +17,9 @@
    You should have received a copy of the GNU General Public License
    along with the GNU Hurd.  If not, see <http://www.gnu.org/licenses/>.  */
 
-#ifndef __MIG_DECLS_H__
-#define __MIG_DECLS_H__
-
-#include "proc.h"
-
-typedef struct exc* exc_t;
-
-static inline exc_t __attribute__ ((unused))
-begin_using_exc_port (mach_port_t port)
-{
-  return ports_lookup_port (NULL, port, exc_class);
-}
-
-static inline void __attribute__ ((unused))
-end_using_exc (exc_t exc)
-{
-  if (exc != NULL)
-    ports_port_deref (exc);
-}
-
-#endif
+#define STARTUP_INTRAN                                         \
+  port_info_t begin_using_startup_port (mach_port_t)
+#define STARTUP_DESTRUCTOR                                     \
+  end_using_startup (port_info_t)
+#define STARTUP_IMPORTS                                                \
+  import "mig-decls.h";
diff --git a/random/random.c b/random/random.c
index 5ef814f..ca96358 100644
--- a/random/random.c
+++ b/random/random.c
@@ -524,11 +524,8 @@ struct port_class *shutdown_notify_class;
 /* The system is going down; destroy all the extant port rights.  That
    will cause net channels and such to close promptly.  */
 error_t
-S_startup_dosync (mach_port_t handle)
+S_startup_dosync (struct port_info *inpi)
 {
-  struct port_info *inpi = ports_lookup_port (fsys->pi.bucket, handle,
-                                             shutdown_notify_class);
-
   if (!inpi)
     return EOPNOTSUPP;
 
diff --git a/storeio/io.c b/storeio/io.c
index eaa20de..2295615 100644
--- a/storeio/io.c
+++ b/storeio/io.c
@@ -23,6 +23,8 @@
 
 #include "open.h"
 #include "dev.h"
+#include "libtrivfs/trivfs_fs_S.h"
+#include "libtrivfs/trivfs_io_S.h"
 
 /* Return objects mapping the data underlying this memory object.  If
    the object can be read then memobjrd will be provided; if the
diff --git a/storeio/storeio.c b/storeio/storeio.c
index 3bde964..eb38349 100644
--- a/storeio/storeio.c
+++ b/storeio/storeio.c
@@ -31,6 +31,7 @@
 
 #include "open.h"
 #include "dev.h"
+#include "libtrivfs/trivfs_fsys_S.h"
 
 static struct argp_option options[] =
 {
diff --git a/term/devio.c b/term/devio.c
index 7c7d8fd..eedd7b8 100644
--- a/term/devio.c
+++ b/term/devio.c
@@ -731,18 +731,18 @@ device_write_reply (mach_port_t replyport,
 }
 
 error_t
-ports_do_mach_notify_send_once (mach_port_t notify)
+ports_do_mach_notify_send_once (struct port_info *pi)
 {
   error_t err;
 
   pthread_mutex_lock (&global_lock);
 
-  if (notify == phys_reply_writes)
+  if (pi->port_right == phys_reply_writes)
     {
       err = 0;
       devio_start_output ();
     }
-  else if (notify == phys_reply)
+  else if (pi->port_right == phys_reply)
     {
       if (input_pending)
        {
diff --git a/term/users.c b/term/users.c
index 9ec9594..97bc22c 100644
--- a/term/users.c
+++ b/term/users.c
@@ -43,6 +43,8 @@
 
 #include "term_S.h"
 #include "tioctl_S.h"
+#include "libtrivfs/trivfs_fs_S.h"
+#include "libtrivfs/trivfs_io_S.h"
 #include <sys/ioctl.h>
 
 #define TTYDEFCHARS
diff --git a/tmpfs/node.c b/tmpfs/node.c
index 9d5f9b7..acc029a 100644
--- a/tmpfs/node.c
+++ b/tmpfs/node.c
@@ -24,11 +24,13 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 
02139, USA.  */
 #include <hurd/hurd_types.h>
 #include <hurd/store.h>
 #include "default_pager_U.h"
+#include "libdiskfs/fs_S.h"
 
 unsigned int num_files;
 static unsigned int gen;
 
 struct node *all_nodes;
+static size_t all_nodes_nr_items;
 
 error_t
 diskfs_alloc_node (struct node *dp, mode_t mode, struct node **npp)
@@ -76,6 +78,7 @@ diskfs_free_node (struct node *np, mode_t mode)
   *np->dn->hprevp = np->dn->hnext;
   if (np->dn->hnext != 0)
     np->dn->hnext->dn->hprevp = np->dn->hprevp;
+  all_nodes_nr_items -= 1;
   free (np->dn);
   np->dn = 0;
 
@@ -119,6 +122,7 @@ diskfs_node_norefs (struct node *np)
       *np->dn->hprevp = np->dn->hnext;
       if (np->dn->hnext != 0)
        np->dn->hnext->dn->hprevp = np->dn->hprevp;
+      all_nodes_nr_items -= 1;
       np->dn->hnext = 0;
       np->dn->hprevp = 0;
     }
@@ -185,6 +189,7 @@ diskfs_cached_lookup (ino_t inum, struct node **npp)
        dn->hnext->dn->hprevp = &dn->hnext;
       dn->hprevp = &all_nodes;
       all_nodes = np;
+      all_nodes_nr_items += 1;
       pthread_spin_unlock (&diskfs_node_refcnt_lock);
 
       st = &np->dn_stat;
@@ -221,7 +226,7 @@ error_t
 diskfs_node_iterate (error_t (*fun) (struct node *))
 {
   error_t err = 0;
-  unsigned int num_nodes = 0;
+  size_t num_nodes;
   struct node *node, **node_list, **p;
 
   pthread_spin_lock (&diskfs_node_refcnt_lock);
@@ -232,8 +237,7 @@ diskfs_node_iterate (error_t (*fun) (struct node *))
      diskfs_node_refcnt_lock, but we can't hold this while locking the
      individual node locks).  */
 
-  for (node = all_nodes; node != 0; node = node->dn->hnext)
-    num_nodes++;
+  num_nodes = all_nodes_nr_items;
 
   p = node_list = alloca (num_nodes * sizeof (struct node *));
   for (node = all_nodes; node != 0; node = node->dn->hnext)
diff --git a/trans/Makefile b/trans/Makefile
index a294282..71e6424 100644
--- a/trans/Makefile
+++ b/trans/Makefile
@@ -1,6 +1,6 @@
 #
 #   Copyright (C) 1994, 1995, 1996, 1997, 1999, 2000, 2001, 2002, 2006, 2007,
-#   2008, 2013 Free Software Foundation, Inc.
+#   2008, 2013, 2014 Free Software Foundation, Inc.
 #
 #   This program is free software; you can redistribute it and/or
 #   modify it under the terms of the GNU General Public License as
@@ -31,7 +31,7 @@ OBJS = $(SRCS:.c=.o) fsysServer.o ifsockServer.o 
passwordServer.o \
        device_replyServer.o elfcore.o
 HURDLIBS = ports netfs trivfs iohelp fshelp pipe ihash shouldbeinlibc
 LDLIBS += -lpthread
-password-LDLIBS = $(LIBCRYPT)
+password-LDLIBS = -lcrypt
 password-MIGSFLAGS=\
     "-DIO_INTRAN=trivfs_protid_t trivfs_begin_using_protid (io_t)" \
     "-DIO_DESTRUCTOR=trivfs_end_using_protid (trivfs_protid_t)" \
diff --git a/trans/fakeroot.c b/trans/fakeroot.c
index c519180..4175b55 100644
--- a/trans/fakeroot.c
+++ b/trans/fakeroot.c
@@ -31,6 +31,12 @@
 
 #include <version.h>
 
+#include "libnetfs/fs_S.h"
+#include "libnetfs/io_S.h"
+#include "libnetfs/fsys_S.h"
+#include "libports/notify_S.h"
+#include "libports/interrupt_S.h"
+
 const char *argp_program_version = STANDARD_HURD_VERSION (fakeroot);
 
 char *netfs_server_name = "fakeroot";
@@ -216,7 +222,7 @@ check_openmodes (struct netnode *nn, int newmodes, file_t 
file)
          mach_port_deallocate (mach_task_self (), file);
          file = MACH_PORT_NULL;
        }
-      if (file == MACH_PORT_NULL);
+      if (file == MACH_PORT_NULL)
        {
          enum retry_type bad_retry;
          char bad_retryname[1024];     /* XXX */
@@ -473,16 +479,26 @@ netfs_validate_stat (struct node *np, struct iouser *cred)
   return 0;
 }
 
+/* Various netfs functions will call fshelp_isowner to check whether
+   USER is allowed to do some operation.  As fakeroot is not running
+   within the fakeauth'ed environment, USER contains the real
+   user.  Hence, we override this check.  */
+error_t
+fshelp_isowner (struct stat *st, struct iouser *user)
+{
+  return 0;
+}
+
 error_t
 netfs_attempt_chown (struct iouser *cred, struct node *np,
                     uid_t uid, uid_t gid)
 {
-  if (uid != -1)
+  if (uid != ~0U)
     {
       set_faked_attribute (np, FAKE_UID);
       np->nn_stat.st_uid = uid;
     }
-  if (gid != -1)
+  if (gid != ~0U)
     {
       set_faked_attribute (np, FAKE_GID);
       np->nn_stat.st_gid = gid;
@@ -934,12 +950,6 @@ int
 netfs_demuxer (mach_msg_header_t *inp,
               mach_msg_header_t *outp)
 {
-  mig_routine_t netfs_io_server_routine (mach_msg_header_t *);
-  mig_routine_t netfs_fs_server_routine (mach_msg_header_t *);
-  mig_routine_t ports_notify_server_routine (mach_msg_header_t *);
-  mig_routine_t netfs_fsys_server_routine (mach_msg_header_t *);
-  mig_routine_t ports_interrupt_server_routine (mach_msg_header_t *);
-
   mig_routine_t routine;
   if ((routine = netfs_io_server_routine (inp)) ||
       (routine = netfs_fs_server_routine (inp)) ||
@@ -993,7 +1003,7 @@ main (int argc, char **argv)
   error_t err;
   mach_port_t bootstrap;
 
-  struct argp argp = { NULL, NULL, NULL, "\
+  struct argp argp = { .doc = "\
 A translator for faking privileged access to an underlying filesystem.\v\
 This translator appears to give transparent access to the underlying \
 directory node.  However, all accesses are made using the credentials \
diff --git a/trans/fifo.c b/trans/fifo.c
index e6fbd0e..a9ad2dd 100644
--- a/trans/fifo.c
+++ b/trans/fifo.c
@@ -35,6 +35,9 @@
 
 #include <version.h>
 
+#include "libtrivfs/trivfs_fs_S.h"
+#include "libtrivfs/trivfs_io_S.h"
+
 /* Global options.  These defaults are the standard ones, I think...   */
 int wait_for_reader = 1, wait_for_writer = 1;
 int one_reader = 1;
diff --git a/trans/firmlink.c b/trans/firmlink.c
index 9c063c0..69d4aae 100644
--- a/trans/firmlink.c
+++ b/trans/firmlink.c
@@ -32,6 +32,8 @@
 
 #include <version.h>
 
+#include "libtrivfs/trivfs_io_S.h"
+
 const char *argp_program_version = STANDARD_HURD_VERSION (firmlink);
 
 static const struct argp_option options[] =
diff --git a/trans/hello-mt.c b/trans/hello-mt.c
index c2d4cc9..ba9329a 100644
--- a/trans/hello-mt.c
+++ b/trans/hello-mt.c
@@ -30,6 +30,8 @@
 
 #include <version.h>
 
+#include "libtrivfs/trivfs_io_S.h"
+
 const char *argp_program_version = STANDARD_HURD_VERSION (hello-mt);
 
 /* The message we return when we are read.  */
diff --git a/trans/hello.c b/trans/hello.c
index c49feeb..4e88c60 100644
--- a/trans/hello.c
+++ b/trans/hello.c
@@ -29,6 +29,8 @@
 
 #include <version.h>
 
+#include "libtrivfs/trivfs_io_S.h"
+
 const char *argp_program_version = STANDARD_HURD_VERSION (hello);
 
 /* The message we return when we are read.  */
diff --git a/trans/magic.c b/trans/magic.c
index 1a8427c..5808483 100644
--- a/trans/magic.c
+++ b/trans/magic.c
@@ -35,6 +35,8 @@
 #include <argp.h>
 #include <argz.h>
 #include <assert.h>
+
+#include "fsys_S.h"
 
 const char *argp_program_version = STANDARD_HURD_VERSION (magic);
 
diff --git a/trans/mtab.c b/trans/mtab.c
index da83e6f..8c9f8d3 100644
--- a/trans/mtab.c
+++ b/trans/mtab.c
@@ -36,6 +36,7 @@
 #include <unistd.h>
 #include <version.h>
 
+#include "libtrivfs/trivfs_io_S.h"
 #include "fs_U.h"
 
 static char *target_path = NULL;
diff --git a/trans/new-fifo.c b/trans/new-fifo.c
index dc3cc79..e71c95c 100644
--- a/trans/new-fifo.c
+++ b/trans/new-fifo.c
@@ -38,6 +38,10 @@
 
 #include <version.h>
 
+#include "libtrivfs/trivfs_fs_S.h"
+#include "libtrivfs/trivfs_fsys_S.h"
+#include "libtrivfs/trivfs_io_S.h"
+
 #define DEFAULT_SERVER _SERVERS "fifo";
 
 const char *argp_program_version = STANDARD_HURD_VERSION (new-fifo);
diff --git a/trans/null.c b/trans/null.c
index 4828cce..bd082dc 100644
--- a/trans/null.c
+++ b/trans/null.c
@@ -32,6 +32,9 @@
 #include <limits.h>
 #include <argp.h>
 #include <nullauth.h>
+
+#include "libtrivfs/trivfs_fs_S.h"
+#include "libtrivfs/trivfs_io_S.h"
 
 const char *argp_program_version = STANDARD_HURD_VERSION (null);
 
diff --git a/trans/proxy-defpager.c b/trans/proxy-defpager.c
index 0a5ab65..9817657 100644
--- a/trans/proxy-defpager.c
+++ b/trans/proxy-defpager.c
@@ -24,6 +24,7 @@
 #include <version.h>
 #include <hurd/paths.h>
 
+#include "libtrivfs/trivfs_io_S.h"
 #include "default_pager_S.h"
 #include "default_pager_U.h"
 
diff --git a/trans/streamio.c b/trans/streamio.c
index 68badd2..54627b7 100644
--- a/trans/streamio.c
+++ b/trans/streamio.c
@@ -34,6 +34,9 @@
 #include <hurd/trivfs.h>
 #include <version.h>
 
+#include "libtrivfs/trivfs_fs_S.h"
+#include "libtrivfs/trivfs_io_S.h"
+
 /* The global lock */
 pthread_mutex_t global_lock;
 
diff --git a/utils/Makefile b/utils/Makefile
index 81fa293..241b060 100644
--- a/utils/Makefile
+++ b/utils/Makefile
@@ -1,4 +1,4 @@
-#   Copyright (C) 1994,95,96,97,98,99,2000,01,02,12 Free Software Foundation,
+#   Copyright (C) 1994,95,96,97,98,99,2000,01,02,12,14 Free Software 
Foundation,
 #   Inc.
 #
 #   This program is free software; you can redistribute it and/or
@@ -36,9 +36,9 @@ SRCS = shd.c ps.c settrans.c syncfs.c showtrans.c addauth.c 
rmauth.c \
 OBJS = $(filter-out %.sh,$(SRCS:.c=.o))
 HURDLIBS = ps ihash store fshelp ports ftpconn shouldbeinlibc
 LDLIBS += -lpthread
-login-LDLIBS = -lutil $(LIBCRYPT)
-addauth-LDLIBS = $(LIBCRYPT)
-setauth-LDLIBS = $(LIBCRYPT)
+login-LDLIBS = -lutil -lcrypt
+addauth-LDLIBS = -lcrypt
+setauth-LDLIBS = -lcrypt
 mount-LDLIBS = $(libblkid_LIBS)
 mount-CPPFLAGS = $(libblkid_CFLAGS)
 
diff --git a/utils/rpctrace.c b/utils/rpctrace.c
index d7ee203..fc913e3 100644
--- a/utils/rpctrace.c
+++ b/utils/rpctrace.c
@@ -768,6 +768,8 @@ rewrite_right (mach_port_t *right, mach_msg_type_name_t 
*type,
           * We ignore it. */
          if (source != unknown_task)
            {
+             /* TODO: this happens on fork() when the new process does not
+                have the send right yet (it is about to get inserted).  */
              error (0, 0, "get an unknown send right from process %d",
                     task2pid (source));
              return dummy_wrapper.name;

-- 
Alioth's /usr/local/bin/git-commit-notice on 
/srv/git.debian.org/git/pkg-hurd/hurd.git



reply via email to

[Prev in Thread] Current Thread [Next in Thread]