From: Samuel Thibault <samuel.thibault@ens-lyon.org>

We cannot properly detect when to release the ro_proxy, so let's just not cache
it.

Index: hurd-debian/ext2fs/pager.c
===================================================================
--- hurd-debian.orig/ext2fs/pager.c
+++ hurd-debian/ext2fs/pager.c
@@ -1338,11 +1338,7 @@ diskfs_get_filemap (struct node *node, v
   if (prot & VM_PROT_WRITE)
     right = ports_get_send_right (pager);
   else
-    {
-      right = pager_get_ro_port (pager);
-      mach_port_mod_refs (mach_task_self (), right,
-                          MACH_PORT_RIGHT_SEND, +1);
-    }
+    right = pager_create_ro_port (pager);
 
   ports_port_deref (pager);
 
Index: hurd-debian/libpager/pager-ro-port.c
===================================================================
--- hurd-debian.orig/libpager/pager-ro-port.c
+++ hurd-debian/libpager/pager-ro-port.c
@@ -20,7 +20,7 @@
 #include <mach/mach4.h>
 
 mach_port_t
-pager_get_ro_port (struct pager *p)
+pager_create_ro_port (struct pager *p)
 {
   error_t err = 0;;
   mach_port_t port = MACH_PORT_NULL;
@@ -29,33 +29,22 @@ pager_get_ro_port (struct pager *p)
   vm_offset_t start = 0;
   vm_size_t len = ~0;
 
-  pthread_mutex_lock (&p->interlock);
-
-  if (!MACH_PORT_VALID (p->ro_proxy))
+  rw_port = ports_get_send_right (p);
+  if (!MACH_PORT_VALID (rw_port))
     {
-      rw_port = ports_get_send_right (p);
-      if (!MACH_PORT_VALID (rw_port))
-        {
-          err = errno;
-          goto out;
-        }
-
-      err = memory_object_create_proxy (mach_task_self (),
-                                        VM_PROT_READ | VM_PROT_EXECUTE,
-                                        &rw_port, 1,
-                                        &offset, 1, &start, 1, &len, 1,
-                                        &p->ro_proxy);
-
-      mach_port_deallocate (mach_task_self (), rw_port);
-
-      if (err)
-        goto out;
+      err = errno;
+      goto out;
     }
 
-  port = p->ro_proxy;
+  err = memory_object_create_proxy (mach_task_self (),
+				    VM_PROT_READ | VM_PROT_EXECUTE,
+				    &rw_port, 1,
+				    &offset, 1, &start, 1, &len, 1,
+				    &port);
+
+  mach_port_deallocate (mach_task_self (), rw_port);
 
  out:
-  pthread_mutex_unlock (&p->interlock);
   errno = err;
   return port;
 }
Index: hurd-debian/libpager/object-terminate.c
===================================================================
--- hurd-debian.orig/libpager/object-terminate.c
+++ hurd-debian/libpager/object-terminate.c
@@ -114,11 +114,6 @@ _pager_free_structure (struct pager *p)
       mach_port_deallocate (mach_task_self (), p->memobjname);
       p->memobjname = MACH_PORT_NULL;
     }
-  if (p->ro_proxy != MACH_PORT_NULL)
-    {
-      mach_port_deallocate (mach_task_self (), p->ro_proxy);
-      p->ro_proxy = MACH_PORT_NULL;
-    }
 
   /* Free the pagemap */
   if (p->pagemapsize)
Index: hurd-debian/libpager/pager-create.c
===================================================================
--- hurd-debian.orig/libpager/pager-create.c
+++ hurd-debian/libpager/pager-create.c
@@ -42,7 +42,6 @@ _pager_create (size_t size,
   p->notify_on_evict = notify_on_evict;
   p->memobjcntl = MACH_PORT_NULL;
   p->memobjname = MACH_PORT_NULL;
-  p->ro_proxy = MACH_PORT_NULL;
   p->noterm = 0;
   p->termwaiting = 0;
   p->pagemap = 0;
Index: hurd-debian/libpager/priv.h
===================================================================
--- hurd-debian.orig/libpager/priv.h
+++ hurd-debian/libpager/priv.h
@@ -55,8 +55,6 @@ struct pager
   memory_object_control_t memobjcntl;
   memory_object_name_t memobjname;
 
-  memory_object_t ro_proxy;
-
   int noterm;			/* number of threads blocking termination */
 
   int termwaiting:1;
Index: hurd-debian/fatfs/pager.c
===================================================================
--- hurd-debian.orig/fatfs/pager.c
+++ hurd-debian/fatfs/pager.c
@@ -861,11 +861,7 @@ diskfs_get_filemap (struct node *node, v
   if (prot & VM_PROT_WRITE)
     right = ports_get_send_right (pager);
   else
-    {
-      right = pager_get_ro_port (pager);
-      mach_port_mod_refs (mach_task_self (), right,
-                          MACH_PORT_RIGHT_SEND, +1);
-    }
+    right = pager_create_ro_port (pager);
 
   ports_port_deref (pager);
 
Index: hurd-debian/tmpfs/node.c
===================================================================
--- hurd-debian.orig/tmpfs/node.c
+++ hurd-debian/tmpfs/node.c
@@ -73,11 +73,9 @@ diskfs_free_node (struct node *np, mode_
   switch (np->dn->type)
     {
     case DT_REG:
+      if (np->dn->u.reg.memobj != MACH_PORT_NULL) {
       /* XXX GNU Mach will terminate the object, and thus existing mappings
        * will get SIGBUS.  */
-      if (np->dn->u.reg.ro_memobj != MACH_PORT_NULL)
-        mach_port_deallocate (mach_task_self (), np->dn->u.reg.ro_memobj);
-      if (np->dn->u.reg.memobj != MACH_PORT_NULL) {
 	vm_deallocate (mach_task_self (), np->dn->u.reg.memref, 4096);
 	mach_port_deallocate (mach_task_self (), np->dn->u.reg.memobj);
       }	
@@ -567,7 +565,7 @@ diskfs_get_filemap (struct node *np, vm_
 
   if (prot & VM_PROT_WRITE)
     right = np->dn->u.reg.memobj;
-  else if (np->dn->u.reg.ro_memobj == MACH_PORT_NULL)
+  else
     {
       vm_offset_t offset = 0;
       vm_offset_t start = 0;
@@ -576,21 +574,17 @@ diskfs_get_filemap (struct node *np, vm_
                                         VM_PROT_READ | VM_PROT_EXECUTE,
                                         &np->dn->u.reg.memobj, 1,
                                         &offset, 1, &start, 1, &len, 1,
-                                        &np->dn->u.reg.ro_memobj);
+                                        &right);
       if (err)
         {
           errno = err;
           return MACH_PORT_NULL;
         }
-
-      right = np->dn->u.reg.ro_memobj;
     }
-  else
-      right = np->dn->u.reg.ro_memobj;
 
   /* Add a reference for each call, the caller will deallocate it.  */
-  err = mach_port_mod_refs (mach_task_self (), right,
-                            MACH_PORT_RIGHT_SEND, +1);
+  err = mach_port_mod_refs (mach_task_self (), np->dn->u.reg.memobj,
+			    MACH_PORT_RIGHT_SEND, +1);
   assert_perror_backtrace (err);
 
   return right;
Index: hurd-debian/libpager/pager.h
===================================================================
--- hurd-debian.orig/libpager/pager.h
+++ hurd-debian/libpager/pager.h
@@ -155,8 +155,9 @@ pager_change_attributes (struct pager *p
 mach_port_t
 pager_get_port (struct pager *pager);
 
+/* Create a read-only proxy for requests to the pager.  */
 mach_port_t
-pager_get_ro_port (struct pager *pager);
+pager_create_ro_port (struct pager *pager);
 
 /* Force termination of a pager.  After this returns, no
    more paging requests on the pager will be honored, and the
