diff -dur hurd-20111206/ext2fs.bak/pager.c hurd-20111206/ext2fs/pager.c
--- hurd-20111206/ext2fs.bak/pager.c	2011-12-29 23:55:26.000000000 +0000
+++ hurd-20111206/ext2fs/pager.c	2011-12-30 00:03:43.000000000 +0000
@@ -409,6 +409,50 @@
 
   return err;
 }
+
+static error_t
+file_pager_write_multipage (struct node *node, vm_offset_t offset, void *buf, vm_size_t length)
+{
+  error_t err = 0;
+  struct pending_blocks pb;
+  struct rwlock *lock = &node->dn->alloc_lock;
+  block_t block;
+  int left = length;
+
+  pending_blocks_init (&pb, buf);
+
+  /* Holding NODE->dn->alloc_lock effectively locks NODE->allocsize,
+     at least for the cases we care about: pager_unlock_page,
+     diskfs_grow and diskfs_truncate.  */
+  rwlock_reader_lock (&node->dn->alloc_lock);
+
+  if (offset >= node->allocsize)
+    left = 0;
+  else if (offset + left > node->allocsize)
+    left = node->allocsize - offset;
+
+  ext2_debug ("writing inode %Ld page %u[%d]", node->cache_id, offset, left);
+
+  STAT_INC (file_pageouts);
+
+  while (left > 0)
+    {
+      err = find_block (node, offset, &block, &lock);
+      if (err)
+        break;
+      assert (block);
+      pending_blocks_add (&pb, block);
+      offset += block_size;
+      left -= block_size;
+    }
+
+  if (!err)
+    pending_blocks_write (&pb);
+
+  rwlock_reader_unlock (&node->dn->alloc_lock);
+
+  return err;
+}
 
 static error_t
 disk_pager_read_page (vm_offset_t page, void **buf, int *writelock)
@@ -1472,3 +1516,245 @@
 
   return max_prot;
 }
+
+/* Temporal override */
+kern_return_t
+_pager_do_write_request (mach_port_t object,
+                         mach_port_seqno_t seqno,
+                         mach_port_t control,
+                         vm_offset_t offset,
+                         pointer_t data,
+                         vm_size_t length,
+                         int dirty,
+                         int kcopy,
+                         int initializing)
+{
+  struct pager *p;
+  short *pm_entries;
+  int npages, i;
+  char *notified;
+  error_t *pagerrs;
+  struct lock_request *lr;
+  struct lock_list {struct lock_request *lr;
+                    struct lock_list *next;} *lock_list, *ll;
+  int wakeup;
+  int omitdata = 0;
+
+  p = ports_lookup_port (0, object, _pager_class);
+  if (!p)
+    return EOPNOTSUPP;
+
+  /* Acquire the right to meddle with the pagemap */
+  mutex_lock (&p->interlock);
+  _pager_wait_for_seqno (p, seqno);
+
+  /* sanity checks -- we don't do multi-page requests yet.  */
+  if (control != p->memobjcntl)
+    {
+      printf ("incg data return: wrong control port\n");
+      goto release_out;
+    }
+  if (length % __vm_page_size)
+    {
+      printf ("incg data return: bad length size %zd\n", length);
+      goto release_out;
+    }
+  if (offset % __vm_page_size)
+    {
+      printf ("incg data return: misaligned request\n");
+      goto release_out;
+    }
+
+  if (p->pager_state != NORMAL)
+    {
+      printf ("pager in wrong state for write\n");
+      goto release_out;
+    }
+
+  npages = length / __vm_page_size;
+  pagerrs = alloca (npages * sizeof (error_t));
+
+  notified = alloca (npages * (sizeof *notified));
+#ifndef NDEBUG
+  memset (notified, -1, npages * (sizeof *notified));
+#endif
+
+  _pager_block_termination (p); /* until we are done with the pagemap
+                                   when the write completes. */
+
+  _pager_pagemap_resize (p, offset + length);
+
+  pm_entries = &p->pagemap[offset / __vm_page_size];
+
+  if (! dirty && ! kcopy)
+    {
+      /* Prepare notified array.  */
+      for (i = 0; i < npages; i++)
+        notified[i] = (p->notify_on_evict
+                       && ! (pm_entries[i] & PM_PAGEINWAIT));
+
+      _pager_release_seqno (p, seqno);
+      goto notify;
+    }
+
+  if (! dirty)
+    {
+      _pager_allow_termination (p);
+      goto release_out;
+    }
+
+  /* Make sure there are no other in-progress writes for any of these
+     pages before we begin.  This imposes a little more serialization
+     than we really have to require (because *all* future writes on
+     this object are going to wait for seqno while we wait for the
+     previous write), but the case is relatively infrequent.  */
+ retry:
+  for (i = 0; i < npages; i++)
+    if (pm_entries[i] & PM_PAGINGOUT)
+      {
+        pm_entries[i] |= PM_WRITEWAIT;
+        condition_wait (&p->wakeup, &p->interlock);
+        goto retry;
+      }
+
+  /* Mark these pages as being paged out.  */
+  if (initializing)
+    {
+      assert (npages <= 32);
+      for (i = 0; i < npages; i++)
+        {
+          if (pm_entries[i] & PM_INIT)
+            omitdata |= 1 << i;
+          else
+            pm_entries[i] |= PM_PAGINGOUT | PM_INIT;
+        }
+    }
+  else
+    for (i = 0; i < npages; i++)
+      pm_entries[i] |= PM_PAGINGOUT | PM_INIT;
+
+  /* If this write occurs while a lock is pending, record
+     it.  We have to keep this list because a lock request
+     might come in while we do the I/O; in that case there
+     would be a new entry on p->lock_requests and we must
+     make sure we don't decrement it.  So we have to keep
+     track independently of which lock requests we incremented. */
+  lock_list = 0;
+  for (lr = p->lock_requests; lr; lr = lr->next)
+    if (offset < lr->end && offset + length >= lr->start)
+      {
+        ll = alloca (sizeof (struct lock_list));
+        ll->lr = lr;
+        ll->next = lock_list;
+        lock_list = ll;
+        lr->pending_writes++;
+      }
+
+  /* Let someone else in. */
+  _pager_release_seqno (p, seqno);
+  mutex_unlock (&p->interlock);
+
+  if (!omitdata && !p->notify_on_evict)
+    {
+      error_t err;
+      err = pager_write_multipage (p->upi, offset, data, npages * vm_page_size);
+      for (i = 0; i < npages; i++)
+        pagerrs[i] = err;
+    }
+  else
+    {
+      for (i = 0; i < npages; i++)
+        if (!(omitdata & (1 << i)))
+          pagerrs[i] = pager_write_page (p->upi,
+                                         offset + (vm_page_size * i),
+                                         data + (vm_page_size * i));
+    }
+
+  /* Acquire the right to meddle with the pagemap */
+  mutex_lock (&p->interlock);
+  _pager_pagemap_resize (p, offset + length);
+  pm_entries = &p->pagemap[offset / __vm_page_size];
+
+  wakeup = 0;
+  for (i = 0; i < npages; i++)
+    {
+      if (omitdata & (1 << i))
+        {
+          notified[i] = 0;
+          continue;
+        }
+
+      if (pm_entries[i] & PM_WRITEWAIT)
+        wakeup = 1;
+
+      if (pagerrs[i] && ! (pm_entries[i] & PM_PAGEINWAIT))
+        /* The only thing we can do here is mark the page, and give
+           errors from now on when it is to be read.  This is
+           imperfect, because if all users go away, the pagemap will
+           be freed, and this information lost.  Oh well.  It's still
+           better than Un*x.  Of course, if we are about to hand this
+           data to the kernel, the error isn't a problem, hence the
+           check for pageinwait.  */
+        pm_entries[i] |= PM_INVALID;
+
+      if (pm_entries[i] & PM_PAGEINWAIT)
+        {
+          memory_object_data_supply (p->memobjcntl,
+                                     offset + (vm_page_size * i),
+                                     data + (vm_page_size * i),
+                                     vm_page_size, 1,
+                                     VM_PROT_NONE, 0, MACH_PORT_NULL);
+          notified[i] = 0;
+        }
+      else
+        {
+          munmap ((caddr_t) (data + (vm_page_size * i)),
+                  vm_page_size);
+          notified[i] = (! kcopy && p->notify_on_evict);
+          if (! kcopy)
+            pm_entries[i] &= ~PM_INCORE;
+        }
+
+      pm_entries[i] &= ~(PM_PAGINGOUT | PM_PAGEINWAIT | PM_WRITEWAIT);
+    }
+
+  for (ll = lock_list; ll; ll = ll->next)
+    if (!--ll->lr->pending_writes && !ll->lr->locks_pending)
+      wakeup = 1;
+
+  if (wakeup)
+    condition_broadcast (&p->wakeup);
+
+ notify:
+  _pager_allow_termination (p);
+  mutex_unlock (&p->interlock);
+
+  for (i = 0; i < npages; i++)
+    {
+      assert (notified[i] == 0 || notified[i] == 1);
+      if (notified[i])
+        {
+          short *pm_entry = &pm_entries[i];
+
+          /* Do notify user.  */
+          pager_notify_evict (p->upi, offset + (i * vm_page_size));
+
+          /* Clear any error that is left.  Notification on eviction
+             is used only to change association of page, so any
+             error may no longer be valid.  */
+          mutex_lock (&p->interlock);
+          *pm_entry = SET_PM_ERROR (SET_PM_NEXTERROR (*pm_entry, 0), 0);
+          mutex_unlock (&p->interlock);
+        }
+    }
+
+  ports_port_deref (p);
+  return 0;
+
+ release_out:
+  _pager_release_seqno (p, seqno);
+  mutex_unlock (&p->interlock);
+  ports_port_deref (p);
+  return 0;
+}
+
