diff options
Diffstat (limited to 'ufs/pager.c')
-rw-r--r-- | ufs/pager.c | 90 |
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; } |