aboutsummaryrefslogtreecommitdiff
path: root/ufs/pager.c
diff options
context:
space:
mode:
Diffstat (limited to 'ufs/pager.c')
-rw-r--r--ufs/pager.c90
1 files changed, 61 insertions, 29 deletions
diff --git a/ufs/pager.c b/ufs/pager.c
index bea290ab..3038932d 100644
--- a/ufs/pager.c
+++ b/ufs/pager.c
@@ -1,5 +1,5 @@
/* Pager for ufs
- Copyright (C) 1994, 1995, 1996 Free Software Foundation
+ Copyright (C) 1994, 1995, 1996, 1997, 1999 Free Software Foundation
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
@@ -19,6 +19,7 @@
#include <strings.h>
#include <stdio.h>
#include <unistd.h>
+#include <hurd/store.h>
spin_lock_t node2pagelock = SPIN_LOCK_INITIALIZER;
@@ -32,6 +33,9 @@ spin_lock_t unlocked_pagein_lock = SPIN_LOCK_INITIALIZER;
struct port_bucket *pager_bucket;
+/* Mapped image of the disk. */
+void *disk_image;
+
/* Find the location on disk of page OFFSET in pager UPI. Return the
disk address (in disk block) in *ADDR. If *NPLOCK is set on
return, then release that mutex after I/O on the data has
@@ -117,7 +121,14 @@ find_address (struct user_pager_info *upi,
{
if (*nplock)
rwlock_reader_unlock (*nplock);
- return EIO;
+ if (isread)
+ return EIO;
+ else
+ {
+ *addr = 0;
+ *disksize = 0;
+ return 0;
+ }
}
if (offset + __vm_page_size > np->allocsize)
@@ -161,7 +172,11 @@ pager_read_page (struct user_pager_info *pager,
if (addr)
{
- err = diskfs_device_read_sync (addr, (void *)buf, disksize);
+ size_t read = 0;
+ err = store_read (store, addr << log2_dev_blocks_per_dev_bsize,
+ disksize, (void **)buf, &read);
+ if (read != disksize)
+ err = EIO;
if (!err && disksize != __vm_page_size)
bzero ((void *)(*buf + disksize), __vm_page_size - disksize);
*writelock = 0;
@@ -172,7 +187,8 @@ pager_read_page (struct user_pager_info *pager,
printf ("Write-locked pagein Object %#x\tOffset %#x\n", pager, page);
fflush (stdout);
#endif
- vm_allocate (mach_task_self (), buf, __vm_page_size, 1);
+ *buf = (vm_address_t) mmap (0, vm_page_size, PROT_READ|PROT_WRITE,
+ MAP_ANON, 0, 0);
*writelock = 1;
}
@@ -199,15 +215,15 @@ pager_write_page (struct user_pager_info *pager,
return err;
if (addr)
- err = diskfs_device_write_sync (addr, buf, disksize);
- else
{
- printf ("Attempt to write unallocated disk\n.");
- printf ("Object %p\tOffset %#x\n", pager, page);
- fflush (stdout);
- err = 0; /* unallocated disk;
- error would be pointless */
+ size_t wrote;
+ err = store_write (store, addr << log2_dev_blocks_per_dev_bsize,
+ (void *)buf, disksize, &wrote);
+ if (wrote != disksize)
+ err = EIO;
}
+ else
+ err = 0;
if (nplock)
rwlock_reader_unlock (nplock);
@@ -286,6 +302,8 @@ pager_unlock_page (struct user_pager_info *pager,
/* Check to see if this block is allocated. */
if (indirs[0].bno == 0)
{
+ size_t wrote;
+
if (indirs[0].offset == -1)
{
err = ffs_alloc (np, lblkno (sblock, address),
@@ -294,9 +312,17 @@ pager_unlock_page (struct user_pager_info *pager,
sblock->fs_bsize, &bno, 0);
if (err)
goto out;
+
assert (lblkno (sblock, address) < NDADDR);
- diskfs_device_write_sync (fsbtodb (sblock, bno),
- zeroblock, sblock->fs_bsize);
+ err = store_write (store,
+ fsbtodb (sblock, bno)
+ << log2_dev_blocks_per_dev_bsize,
+ zeroblock, sblock->fs_bsize, &wrote);
+ if (!err && wrote != sblock->fs_bsize)
+ err = EIO;
+ if (err)
+ goto out;
+
indirs[0].bno = bno;
write_disk_entry (di->di_db[lblkno (sblock, address)], bno);
record_poke (di, sizeof (struct dinode));
@@ -378,8 +404,14 @@ pager_unlock_page (struct user_pager_info *pager,
if (err)
goto out;
- diskfs_device_write_sync (fsbtodb (sblock, bno),
- zeroblock, sblock->fs_bsize);
+ err = store_write (store,
+ fsbtodb (sblock, bno)
+ << log2_dev_blocks_per_dev_bsize,
+ zeroblock, sblock->fs_bsize, &wrote);
+ if (!err && wrote != sblock->fs_bsize)
+ err = EIO;
+ if (err)
+ goto out;
indirs[0].bno = bno;
write_disk_entry (siblock[indirs[0].offset], bno);
@@ -405,7 +437,7 @@ pager_report_extent (struct user_pager_info *pager,
*offset = 0;
if (pager->type == DISK)
- *size = diskfs_device_size << diskfs_log2_device_block_size;
+ *size = store->size;
else
*size = pager->np->allocsize;
@@ -436,15 +468,6 @@ pager_dropweak (struct user_pager_info *upi __attribute__ ((unused)))
-static void
-thread_function (any_t foo __attribute__ ((unused)))
-{
- for (;;)
- ports_manage_port_operations_multithread (pager_bucket, pager_demuxer,
- 1000 * 60 * 2, 0,
- 1, MACH_PORT_NULL);
-}
-
/* Create the DISK pager. */
void
create_disk_pager (void)
@@ -453,8 +476,10 @@ create_disk_pager (void)
upi->type = DISK;
upi->np = 0;
- disk_pager_setup (upi, MAY_CACHE);
- upi->p = disk_pager;
+ pager_bucket = ports_create_bucket ();
+ diskfs_start_disk_pager (upi, pager_bucket, MAY_CACHE, store->size,
+ &disk_image);
+ upi->p = diskfs_disk_pager;
}
/* This syncs a single file (NP) to disk. Wait for all I/O to complete
@@ -546,6 +571,13 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot)
diskfs_nref_light (np);
upi->p = pager_create (upi, pager_bucket,
MAY_CACHE, MEMORY_OBJECT_COPY_DELAY);
+ if (upi->p == 0)
+ {
+ diskfs_nrele_light (np);
+ free (upi);
+ spin_unlock (&node2pagelock);
+ return MACH_PORT_NULL;
+ }
np->dn->fileinfo = upi;
right = pager_get_port (np->dn->fileinfo->p);
ports_port_deref (np->dn->fileinfo->p);
@@ -743,7 +775,7 @@ diskfs_shutdown_pager ()
{
struct pager *p = arg;
/* Don't ever shut down the disk pager. */
- if (p != disk_pager)
+ if (p != diskfs_disk_pager)
pager_shutdown (p);
return 0;
}
@@ -762,7 +794,7 @@ diskfs_sync_everything (int wait)
{
struct pager *p = arg;
/* Make sure the disk pager is done last. */
- if (p != disk_pager)
+ if (p != diskfs_disk_pager)
pager_sync (p, wait);
return 0;
}