summaryrefslogtreecommitdiff
path: root/ufs
diff options
context:
space:
mode:
authorMichael I. Bushnell <mib@gnu.org>1995-06-27 00:17:38 +0000
committerMichael I. Bushnell <mib@gnu.org>1995-06-27 00:17:38 +0000
commite6b0b6965bef8825569d6d4bd4cc60a46acb14ae (patch)
treed5b627b0b75c983f9e18e9b9f4eacee0629fcc29 /ufs
parente85d0c8b15fba224d27e898082e677aaa3db02ce (diff)
(diskfs_pager_users): New function.
Diffstat (limited to 'ufs')
-rw-r--r--ufs/pager.c67
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