Hi,
This patch fixes external objects interface in mach_defpager (current
default pager in Hurd), so it can be used as backing store by other
translators (like tmpfs).
diff -du hurd-deb.orig/serverboot/default_pager.c hurd/serverboot/default_pager.c
--- hurd-deb.orig/serverboot/default_pager.c 2010-05-06 11:37:31.000000000 +0200
+++ hurd/serverboot/default_pager.c 2010-05-18 13:50:40.000000000 +0200
@@ -1154,6 +1154,7 @@
{
ddprintf ("%spager_read_offset pager %x: bad page %d >= size %d",
my_name, pager, f_page, pager->size);
+ mutex_unlock(&pager->lock);
return (union dp_map) (union dp_map *) NO_BLOCK;
#if 0
panic("%spager_read_offset",my_name);
@@ -1667,7 +1668,7 @@
* if it is different from <addr>, it must be deallocated after use.
*/
int
-default_read(ds, addr, size, offset, out_addr, deallocate)
+default_read(ds, addr, size, offset, out_addr, deallocate, external)
register dpager_t ds;
vm_offset_t addr; /* pointer to block to fill */
register vm_size_t size;
@@ -1675,6 +1676,7 @@
vm_offset_t *out_addr;
/* returns pointer to data */
boolean_t deallocate;
+ boolean_t external;
{
register union dp_map block;
vm_offset_t raddr;
@@ -1691,8 +1693,18 @@
* Find the block in the paging partition
*/
block = pager_read_offset(ds, offset);
- if ( no_block(block) )
+ if ( no_block(block) ) {
+ if (external) {
+ /*
+ * An external object is requesting unswapped data,
+ * zero fill the page and return.
+ */
+ bzero((char *) addr, vm_page_size);
+ *out_addr = addr;
+ return (PAGER_SUCCESS);
+ }
return (PAGER_ABSENT);
+ }
/*
* Read it, trying for the entire page.
@@ -1843,6 +1855,7 @@
mach_port_urefs_t request_refs; /* Request port user-refs */
mach_port_t pager_name; /* Name port */
mach_port_urefs_t name_refs; /* Name port user-refs */
+ boolean_t external; /* Is an external object? */
unsigned int readers; /* Reads in progress */
unsigned int writers; /* Writes in progress */
@@ -2300,10 +2313,12 @@
/* possibly generate an immediate no-senders notification */
sync = 0;
pset = default_pager_internal_set;
+ ds->external = FALSE;
} else {
/* delay notification till send right is created */
sync = 1;
pset = default_pager_external_set;
+ ds->external = TRUE;
}
kr = mach_port_request_notification(default_pager_self, pager,
@@ -2497,28 +2512,11 @@
pager_port_unlock(ds);
/*
- * Now we deallocate our various port rights.
+ * Now we destroy our port rights.
*/
- kr = mach_port_mod_refs(default_pager_self, pager_request,
- MACH_PORT_RIGHT_SEND, -request_refs);
- if (kr != KERN_SUCCESS)
- panic(here,my_name);
-
- kr = mach_port_mod_refs(default_pager_self, pager_request,
- MACH_PORT_RIGHT_RECEIVE, -1);
- if (kr != KERN_SUCCESS)
- panic(here,my_name);
-
- kr = mach_port_mod_refs(default_pager_self, pager_name,
- MACH_PORT_RIGHT_SEND, -name_refs);
- if (kr != KERN_SUCCESS)
- panic(here,my_name);
-
- kr = mach_port_mod_refs(default_pager_self, pager_name,
- MACH_PORT_RIGHT_RECEIVE, -1);
- if (kr != KERN_SUCCESS)
- panic(here,my_name);
+ mach_port_destroy(mach_task_self(), pager_request);
+ mach_port_destroy(mach_task_self(), pager_name);
return (KERN_SUCCESS);
}
@@ -2627,7 +2625,6 @@
ddprintf ("seqnos_memory_object_data_request <%p>: pager_port_lock: <%p>[s:%d,r:%d,w:%d,l:%d], %d\n",
&ds, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held, seqno);
pager_port_lock(ds, seqno);
- pager_port_check_request(ds, reply_to);
pager_port_wait_for_writers(ds);
pager_port_start_read(ds);
@@ -2654,7 +2651,8 @@
else
rc = default_read(&ds->dpager, dpt->dpt_buffer,
vm_page_size, offset,
- &addr, protection_required & VM_PROT_WRITE);
+ &addr, protection_required & VM_PROT_WRITE,
+ ds->external);
switch (rc) {
case PAGER_SUCCESS:
@@ -2729,7 +2727,6 @@
ddprintf ("seqnos_memory_object_data_initialize <%p>: pager_port_lock: <%p>[s:%d,r:%d,w:%d,l:%d], %d\n",
&ds, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held, seqno);
pager_port_lock(ds, seqno);
- pager_port_check_request(ds, pager_request);
pager_port_start_write(ds);
ddprintf ("seqnos_memory_object_data_initialize <%p>: pager_port_unlock: <%p>[s:%d,r:%d,w:%d,l:%d]\n",
&ds, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held);
@@ -2809,7 +2806,6 @@
&err, ds, ds->seqno, ds->readers, ds->writers, ds->lock.held, seqno);
pager_port_lock(ds, seqno);
ddprintf ("seqnos_memory_object_data_write <%p>: 5\n", &err);
- pager_port_check_request(ds, pager_request);
ddprintf ("seqnos_memory_object_data_write <%p>: 6\n", &err);
pager_port_start_write(ds);
ddprintf ("seqnos_memory_object_data_write <%p>: 7\n", &err);
@@ -3312,7 +3308,8 @@
mach_port_t port;
kern_return_t result;
- if (pager != default_pager_default_port)
+ if (pager != default_pager_default_port ||
+ size != vm_page_size)
return KERN_INVALID_ARGUMENT;
ds = pager_port_alloc(size);
@@ -3709,7 +3706,6 @@
kern_return_t
S_default_pager_object_set_size (mach_port_t pager,
mach_port_seqno_t seqno,
- mach_port_t reply_to,
vm_size_t limit)
{
kern_return_t kr;
@@ -3720,7 +3716,6 @@
return KERN_INVALID_ARGUMENT;
pager_port_lock(ds, seqno);
- pager_port_check_request(ds, reply_to);
pager_port_wait_for_readers(ds);
pager_port_wait_for_writers(ds);
@@ -3731,26 +3726,22 @@
ds->dpager.limit = limit;
kr = KERN_SUCCESS;
}
- else if (ds->lock_request == MACH_PORT_NULL)
+ else
{
- /* Tell the kernel to flush from core all the pages being removed.
- We will get the memory_object_lock_completed callback when they
- have been flushed. We handle that by completing the limit update
- and posting the reply to the pending truncation. */
+ /* Tell the kernel to flush from core all the pages being removed. */
kr = memory_object_lock_request (ds->pager_request,
limit,
- ds->dpager.size * vm_page_size - limit,
+ ds->dpager.limit - limit,
MEMORY_OBJECT_RETURN_NONE, TRUE,
- VM_PROT_ALL, ds->pager);
+ VM_PROT_ALL, MACH_PORT_NULL);
if (kr != KERN_SUCCESS)
panic ("memory_object_lock_request: %d", kr);
- ds->lock_request = reply_to;
- kr = MIG_NO_REPLY;
+ ds->dpager.limit = limit;
+ /* FIXME: Currently, we're unable to free used swap space
+ if (ds->dpager.size > ds->dpager.limit / vm_page_size)
+ pager_truncate (&ds->dpager, ds->dpager.limit / vm_page_size);
+ */
}
- else
- /* There is already another call in progress. Tough titties. */
- kr = KERN_FAILURE;
-
pager_port_unlock(ds, seqno);
return kr;
diff -du hurd-deb.orig/hurd/default_pager.defs hurd/hurd/default_pager.defs
--- hurd-deb.orig/hurd/default_pager.defs 2010-05-06 11:37:31.000000000 +0200
+++ hurd/hurd/default_pager.defs 2010-05-18 13:49:19.000000000 +0200
@@ -91,6 +91,5 @@
will fail. */
routine default_pager_object_set_size(
memory_object : mach_port_t;
- sreplyport reply_port : mach_port_send_once_t;
msgseqno seqno : mach_port_seqno_t;
object_size_limit : vm_size_t);