summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--console/pager.c22
-rw-r--r--doc/hurd.texi5
-rw-r--r--ext2fs/pager.c25
-rw-r--r--fatfs/pager.c21
-rw-r--r--isofs/pager.c18
-rw-r--r--libpager/pager-create.c50
-rw-r--r--libpager/pager.h8
7 files changed, 91 insertions, 58 deletions
diff --git a/console/pager.c b/console/pager.c
index 05074a75..d60935a1 100644
--- a/console/pager.c
+++ b/console/pager.c
@@ -49,12 +49,11 @@ static struct pager_requests *pager_requests;
void
pager_clear_user_data (struct user_pager_info *upi)
{
- int idx;
+ size_t idx;
for (idx = 0; idx < upi->memobj_npages; idx++)
if (upi->memobj_pages[idx])
vm_deallocate (mach_task_self (), upi->memobj_pages[idx], vm_page_size);
- free (upi);
}
@@ -148,21 +147,17 @@ user_pager_create (struct user_pager *user_pager, unsigned int npages,
error_t err;
struct user_pager_info *upi;
- upi = calloc (1, sizeof (struct user_pager_info)
- + sizeof (vm_address_t) * npages);
- if (!upi)
+ /* XXX Are the values 1 and MEMORY_OBJECT_COPY_DELAY correct? */
+ user_pager->pager = \
+ pager_create_alloc (sizeof *upi + sizeof (vm_address_t) * npages,
+ pager_bucket, 1, MEMORY_OBJECT_COPY_DELAY, 0);
+ if (!user_pager->pager)
return errno;
+ upi = pager_get_upi (user_pager->pager);
upi->memobj_npages = npages;
+ memset (upi->memobj_pages, 0, sizeof (vm_address_t) * npages);
- /* XXX Are the values 1 and MEMORY_OBJECT_COPY_DELAY correct? */
- user_pager->pager = pager_create (upi, pager_bucket,
- 1, MEMORY_OBJECT_COPY_DELAY, 0);
- if (!user_pager->pager)
- {
- free (upi);
- return errno;
- }
user_pager->memobj = pager_get_port (user_pager->pager);
ports_port_deref (user_pager->pager);
@@ -182,7 +177,6 @@ user_pager_create (struct user_pager *user_pager, unsigned int npages,
VM_INHERIT_NONE);
if (err)
{
- /* UPI will be cleaned up by libpager. */
mach_port_deallocate (mach_task_self (), user_pager->memobj);
return err;
}
diff --git a/doc/hurd.texi b/doc/hurd.texi
index 2bcf561b..8428a77b 100644
--- a/doc/hurd.texi
+++ b/doc/hurd.texi
@@ -1410,6 +1410,11 @@ create references to pagers by use of the relevant ports library
functions. On errors, return null and set @code{errno}.
@end deftypefun
+@deftypefun {struct pager *} pager_create_alloc (@w{size_t @var{u_pager_size}}, @w{struct port_bucket *@var{bucket}}, @w{boolean_t @var{may_cache}}, @w{memory_object_copy_strategy_t @var{copy_strategy}})
+Likewise, but allocate space for the user hook adjacent to the pager
+data.
+@end deftypefun
+
Once you are ready to turn over control to the pager library, you should
call @code{ports_manage_port_operations_multithread} on the
@var{bucket}, using @code{pager_demuxer} as the ports @var{demuxer}.
diff --git a/ext2fs/pager.c b/ext2fs/pager.c
index 485f69cd..456b582c 100644
--- a/ext2fs/pager.c
+++ b/ext2fs/pager.c
@@ -822,8 +822,6 @@ pager_clear_user_data (struct user_pager_info *upi)
diskfs_nrele_light (upi->node);
}
-
- free (upi);
}
/* This will be called when the ports library wants to drop weak references.
@@ -1316,23 +1314,22 @@ diskfs_get_filemap (struct node *node, vm_prot_t prot)
}
else
{
- struct user_pager_info *upi =
- malloc (sizeof (struct user_pager_info));
- upi->type = FILE_DATA;
- upi->node = node;
- upi->max_prot = prot;
- diskfs_nref_light (node);
- diskfs_node_disknode (node)->pager =
- pager_create (upi, file_pager_bucket, MAY_CACHE,
- MEMORY_OBJECT_COPY_DELAY, 0);
- if (diskfs_node_disknode (node)->pager == 0)
+ struct user_pager_info *upi;
+ pager = pager_create_alloc (sizeof *upi, file_pager_bucket,
+ MAY_CACHE, MEMORY_OBJECT_COPY_DELAY, 0);
+ if (pager == NULL)
{
- diskfs_nrele_light (node);
- free (upi);
pthread_spin_unlock (&node_to_page_lock);
return MACH_PORT_NULL;
}
+ upi = pager_get_upi (pager);
+ upi->type = FILE_DATA;
+ upi->node = node;
+ upi->max_prot = prot;
+ diskfs_nref_light (node);
+ diskfs_node_disknode (node)->pager = pager;
+
/* A weak reference for being part of the node. */
ports_port_ref_weak (diskfs_node_disknode (node)->pager);
diff --git a/fatfs/pager.c b/fatfs/pager.c
index 84376bd7..bef8dbeb 100644
--- a/fatfs/pager.c
+++ b/fatfs/pager.c
@@ -747,8 +747,6 @@ pager_clear_user_data (struct user_pager_info *upi)
diskfs_nrele_light (upi->node);
}
-
- free (upi);
}
/* This will be called when the ports library wants to drop weak
@@ -839,22 +837,21 @@ diskfs_get_filemap (struct node *node, vm_prot_t prot)
}
else
{
- struct user_pager_info *upi =
- malloc (sizeof (struct user_pager_info));
- upi->type = FILE_DATA;
- upi->node = node;
- upi->max_prot = prot;
- diskfs_nref_light (node);
+ struct user_pager_info *upi;
node->dn->pager =
- pager_create (upi, file_pager_bucket, MAY_CACHE,
- MEMORY_OBJECT_COPY_DELAY, 0);
- if (node->dn->pager == 0)
+ pager_create_alloc (sizeof *upi, file_pager_bucket, MAY_CACHE,
+ MEMORY_OBJECT_COPY_DELAY, 0);
+ if (node->dn->pager == NULL)
{
diskfs_nrele_light (node);
- free (upi);
pthread_spin_unlock (&node_to_page_lock);
return MACH_PORT_NULL;
}
+ upi = pager_get_upi (node->dn->pager);
+ upi->type = FILE_DATA;
+ upi->node = node;
+ upi->max_prot = prot;
+ diskfs_nref_light (node);
right = pager_get_port (node->dn->pager);
ports_port_deref (node->dn->pager);
diff --git a/isofs/pager.c b/isofs/pager.c
index b4be4e2d..42cad8db 100644
--- a/isofs/pager.c
+++ b/isofs/pager.c
@@ -128,7 +128,6 @@ pager_clear_user_data (struct user_pager_info *upi)
pthread_spin_unlock (&node2pagelock);
diskfs_nrele_light (upi->np);
}
- free (upi);
}
void
@@ -176,19 +175,20 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot)
do
if (!np->dn->fileinfo)
{
- upi = malloc (sizeof (struct user_pager_info));
- upi->type = FILE_DATA;
- upi->np = np;
- diskfs_nref_light (np);
- upi->p = pager_create (upi, pager_bucket, 1,
- MEMORY_OBJECT_COPY_DELAY, 0);
- if (upi->p == 0)
+ struct pager *p;
+ p = pager_create_alloc (sizeof *upi, pager_bucket, 1,
+ MEMORY_OBJECT_COPY_DELAY, 0);
+ if (p == NULL)
{
diskfs_nrele_light (np);
- free (upi);
pthread_spin_unlock (&node2pagelock);
return MACH_PORT_NULL;
}
+ upi = pager_get_upi (p);
+ upi->type = FILE_DATA;
+ upi->np = np;
+ diskfs_nref_light (np);
+ upi->p = p;
np->dn->fileinfo = upi;
right = pager_get_port (np->dn->fileinfo->p);
ports_port_deref (np->dn->fileinfo->p);
diff --git a/libpager/pager-create.c b/libpager/pager-create.c
index b583f023..b3b7c8f0 100644
--- a/libpager/pager-create.c
+++ b/libpager/pager-create.c
@@ -17,21 +17,19 @@
#include "priv.h"
-/* Create and return a new pager with user info UPI. */
-struct pager *
-pager_create (struct user_pager_info *upi,
- struct port_bucket *bucket,
- boolean_t may_cache,
- memory_object_copy_strategy_t copy_strategy,
- boolean_t notify_on_evict)
+static struct pager *
+_pager_create (size_t size,
+ struct port_bucket *bucket,
+ boolean_t may_cache,
+ memory_object_copy_strategy_t copy_strategy,
+ boolean_t notify_on_evict)
{
struct pager *p;
- errno = ports_create_port (_pager_class, bucket, sizeof (struct pager), &p);
+ errno = ports_create_port (_pager_class, bucket, sizeof *p + size, &p);
if (errno)
return 0;
- p->upi = upi;
p->pager_state = NOTINIT;
pthread_mutex_init (&p->interlock, NULL);
pthread_cond_init (&p->wakeup, NULL);
@@ -50,6 +48,40 @@ pager_create (struct user_pager_info *upi,
return p;
}
+/* Create and return a new pager with user info UPI. */
+struct pager *
+pager_create (struct user_pager_info *upi,
+ struct port_bucket *bucket,
+ boolean_t may_cache,
+ memory_object_copy_strategy_t copy_strategy,
+ boolean_t notify_on_evict)
+{
+ struct pager *p;
+
+ p = _pager_create (0, bucket, may_cache, copy_strategy, notify_on_evict);
+ if (p)
+ p->upi = upi;
+
+ return p;
+}
+
+struct pager *
+pager_create_alloc (size_t u_pager_size,
+ struct port_bucket *bucket,
+ boolean_t may_cache,
+ memory_object_copy_strategy_t copy_strategy,
+ boolean_t notify_on_evict)
+{
+ struct pager *p;
+
+ p = _pager_create (u_pager_size, bucket, may_cache, copy_strategy,
+ notify_on_evict);
+ if (p)
+ p->upi = (struct user_pager_info *) ((char *) p + sizeof *p);
+
+ return p;
+}
+
/* This causes the function to be run at startup by compiler magic. */
static void create_class (void) __attribute__ ((constructor));
diff --git a/libpager/pager.h b/libpager/pager.h
index df4db686..d2a8d397 100644
--- a/libpager/pager.h
+++ b/libpager/pager.h
@@ -69,6 +69,14 @@ pager_create (struct user_pager_info *u_pager,
memory_object_copy_strategy_t copy_strategy,
boolean_t notify_on_evict);
+/* Likewise, but also allocate space for the user hook. */
+struct pager *
+pager_create_alloc (size_t u_pager_size,
+ struct port_bucket *bucket,
+ boolean_t may_cache,
+ memory_object_copy_strategy_t copy_strategy,
+ boolean_t notify_on_evict);
+
/* Return the user_pager_info struct associated with a pager. */
struct user_pager_info *
pager_get_upi (struct pager *p);