diff options
author | Michael I. Bushnell <mib@gnu.org> | 1995-06-27 00:17:38 +0000 |
---|---|---|
committer | Michael I. Bushnell <mib@gnu.org> | 1995-06-27 00:17:38 +0000 |
commit | e6b0b6965bef8825569d6d4bd4cc60a46acb14ae (patch) | |
tree | d5b627b0b75c983f9e18e9b9f4eacee0629fcc29 /ufs | |
parent | e85d0c8b15fba224d27e898082e677aaa3db02ce (diff) |
(diskfs_pager_users): New function.
Diffstat (limited to 'ufs')
-rw-r--r-- | ufs/pager.c | 67 |
1 files changed, 67 insertions, 0 deletions
diff --git a/ufs/pager.c b/ufs/pager.c index 355af46c..34c4d232 100644 --- a/ufs/pager.c +++ b/ufs/pager.c @@ -508,6 +508,73 @@ allow_pager_softrefs (struct node *np) ports_port_deref (upi->p); } +/* Tell diskfs if there are pagers exported, and if none, then + prevent any new ones from showing up. */ +int +diskfs_pager_users () +{ + int npagers; + + 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; + struct user_pager_info *upi = pager_get_upi (p); + + pager_change_attributes (p, 1, MEMORY_OBJECT_COPY_DELAY, 0); + + /* It's possible that we didn't have caching on before, because + the user here is the only reference to the underlying node + (actually, that's quite likely inside this particular + routine), and if that node has no links. So dinkle the node + ref counting scheme here, which will cause caching to be + turned off, if that's really necessary. */ + if (upi->pager_type == FILE_DATA) + { + diskfs_nref (upi->np); + diskfs_nrele (upi->np); + } + + return 0; + } + + npagers = ports_count_bucket (pager_bucket); + if (npagers == 0) + return 0; + + if (MAY_CACHE == 0) + { + ports_enable_bucket (pager_bucket); + return 1 + } + + /* Loop through the pagers and turn off caching one by one, + synchronously. That should cause termination of each pager. */ + ports_bucket_iterate (pager_bucket, block_cache); + + /* Give it a second; the kernel doesn't actually shutdown + immediately. XXX */ + sleep (1); + + npagers = ports_count_bucket (pager_bucket); + + if (npagers == 0) + return 0; + + /* Darn, there are actual honest users. Turn caching back on, + and return failure. */ + ports_bucket_iterate (pager_bucket, enable_cache); + return 1; +} + + /* Call this to find out the struct pager * corresponding to the FILE_DATA pager of inode IP. This should be used *only* as a subsequent argument to register_memory_fault_area, and will be deleted when |