diff options
author | Miles Bader <miles@gnu.org> | 1997-07-16 18:53:41 +0000 |
---|---|---|
committer | Miles Bader <miles@gnu.org> | 1997-07-16 18:53:41 +0000 |
commit | 8ba3d92e48fe96e1cb9380c5f989441017ce053f (patch) | |
tree | db8a7081e052714e139935c1c902ec447b88479b /storeio | |
parent | d7052cce81b50a339c367dca10ef21143faf6cc9 (diff) | |
download | hurd-8ba3d92e48fe96e1cb9380c5f989441017ce053f.tar.gz hurd-8ba3d92e48fe96e1cb9380c5f989441017ce053f.tar.bz2 hurd-8ba3d92e48fe96e1cb9380c5f989441017ce053f.zip |
(dev_get_memory_object): Implement correctly.
(dev_stop_paging): Work entirely by flushing user pagers; don't kill pager.
(pager_clear_user_data): Zero our pointer to the pager.
Diffstat (limited to 'storeio')
-rw-r--r-- | storeio/pager.c | 103 |
1 files changed, 49 insertions, 54 deletions
diff --git a/storeio/pager.c b/storeio/pager.c index 3794403e..b70ca71c 100644 --- a/storeio/pager.c +++ b/storeio/pager.c @@ -1,6 +1,6 @@ /* Paging interface for storeio devices - Copyright (C) 1995, 1996 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. Written by Miles Bader <miles@gnu.ai.mit.edu> @@ -124,6 +124,10 @@ pager_report_extent (struct user_pager_info *upi, void pager_clear_user_data (struct user_pager_info *upi) { + struct dev *dev = (struct dev *)upi; + mutex_lock (&dev->pager_lock); + dev->pager = 0; + mutex_unlock (&dev->pager_lock); } static struct port_bucket *pager_port_bucket = 0; @@ -172,60 +176,39 @@ pager_dropweak (struct user_pager_info *upi __attribute__ ((unused))) int dev_stop_paging (struct dev *dev, int nosync) { - int success = 1; /* Initially assume success. */ - - mutex_lock (&dev->pager_lock); + size_t num_pagers = ports_count_bucket (pager_port_bucket); - if (dev->pager != NULL) + if (num_pagers > 0 && !nosync) { - int num_pagers = ports_count_bucket (pager_port_bucket); - if (num_pagers > 0 && !nosync) + error_t block_cache (void *arg) { - error_t block_cache (void *arg) - { - struct pager *p = arg; - pager_change_attributes (p, 0, MEMORY_OBJECT_COPY_DELAY, 1); - return 0; - } - error_t enable_cache (void *arg) - { - struct pager *p = arg; - pager_change_attributes (p, 1, MEMORY_OBJECT_COPY_DELAY, 0); - return 0; - } - - /* Loop through the pagers and turn off caching one by one, - synchronously. That should cause termination of each pager. */ - ports_bucket_iterate (pager_port_bucket, block_cache); - - /* Give it a second; the kernel doesn't actually shutdown - immediately. XXX */ - sleep (1); - - num_pagers = ports_count_bucket (pager_port_bucket); - if (num_pagers > 0) - /* Darn, there are actual honest users. Turn caching back on, - and return failure. */ - { - ports_bucket_iterate (pager_port_bucket, enable_cache); - success = 0; - } + struct pager *p = arg; + pager_change_attributes (p, 0, MEMORY_OBJECT_COPY_DELAY, 1); + return 0; + } + error_t enable_cache (void *arg) + { + struct pager *p = arg; + pager_change_attributes (p, 1, MEMORY_OBJECT_COPY_DELAY, 0); + return 0; } - if (success && !nosync) - /* shutdown the pager on DEV. If NOSYNC is set, we don't bother, for - fear that this may result in I/O. In this case we've disabled - rpcs on the pager's ports, so this will result in hanging... What - do we do??? XXXX */ - pager_shutdown (dev->pager); - } + /* Loop through the pagers and turn off caching one by one, + synchronously. That should cause termination of each pager. */ + ports_bucket_iterate (pager_port_bucket, block_cache); - if (success) - dev->pager = NULL; + /* Give it a second; the kernel doesn't actually shutdown + immediately. XXX */ + sleep (1); - mutex_unlock (&dev->pager_lock); + num_pagers = ports_count_bucket (pager_port_bucket); + if (num_pagers > 0) + /* Darn, there are actual honest users. Turn caching back on, + and return failure. */ + ports_bucket_iterate (pager_port_bucket, enable_cache); + } - return success; + return num_pagers == 0; } /* Returns in MEMOBJ the port for a memory object backed by the storage on @@ -233,6 +216,7 @@ dev_stop_paging (struct dev *dev, int nosync) error_t dev_get_memory_object (struct dev *dev, memory_object_t *memobj) { + int created = 0; error_t err = 0; init_dev_paging (); @@ -240,24 +224,35 @@ dev_get_memory_object (struct dev *dev, memory_object_t *memobj) mutex_lock (&dev->pager_lock); if (dev->pager == NULL) - dev->pager = - pager_create ((struct user_pager_info *)dev, pager_port_bucket, - 1, MEMORY_OBJECT_COPY_DELAY); - else - ports_port_ref (dev->pager); + { + dev->pager = + pager_create ((struct user_pager_info *)dev, pager_port_bucket, + 1, MEMORY_OBJECT_COPY_DELAY); + created = 1; + } if (dev->pager == NULL) err = ENODEV; /* XXX ??? */ else { *memobj = pager_get_port (dev->pager); - if (*memobj != MACH_PORT_NULL) + + if (*memobj == MACH_PORT_NULL) + /* Pager is currently being destroyed, try again. */ + { + dev->pager = 0; + mutex_unlock (&dev->pager_lock); + return dev_get_memory_object (dev, memobj); + } + else err = mach_port_insert_right (mach_task_self (), *memobj, *memobj, MACH_MSG_TYPE_MAKE_SEND); - ports_port_deref (dev->pager); /* Drop our original ref on PAGER. */ } + if (created) + ports_port_deref (dev->pager); + mutex_unlock (&dev->pager_lock); return err; |