summaryrefslogtreecommitdiff
path: root/ext2fs
diff options
context:
space:
mode:
Diffstat (limited to 'ext2fs')
-rw-r--r--ext2fs/ext2fs.c12
-rw-r--r--ext2fs/ext2fs.h6
-rw-r--r--ext2fs/pager.c33
3 files changed, 49 insertions, 2 deletions
diff --git a/ext2fs/ext2fs.c b/ext2fs/ext2fs.c
index d0fdfe7a..03c9eedc 100644
--- a/ext2fs/ext2fs.c
+++ b/ext2fs/ext2fs.c
@@ -207,10 +207,20 @@ main (int argc, char **argv)
error_t
diskfs_reload_global_state ()
{
+ error_t err;
+
pokel_flush (&global_pokel);
pager_flush (diskfs_disk_pager, 1);
- sblock = NULL;
+
+ /* libdiskfs is not responsible for inhibiting paging. */
+ err = inhibit_ext2_pager ();
+ if (err)
+ return err;
+
get_hypermetadata ();
map_hypermetadata ();
+
+ resume_ext2_pager ();
+
return 0;
}
diff --git a/ext2fs/ext2fs.h b/ext2fs/ext2fs.h
index 72b7b09d..42717c52 100644
--- a/ext2fs/ext2fs.h
+++ b/ext2fs/ext2fs.h
@@ -202,6 +202,12 @@ struct user_pager_info
/* Set up the disk pager. */
void create_disk_pager (void);
+/* Inhibit the disk pager. */
+error_t inhibit_ext2_pager (void);
+
+/* Resume the disk pager. */
+void resume_ext2_pager (void);
+
/* Call this when we should turn off caching so that unused memory object
ports get freed. */
void drop_pager_softrefs (struct node *node);
diff --git a/ext2fs/pager.c b/ext2fs/pager.c
index b56c923a..3e080f87 100644
--- a/ext2fs/pager.c
+++ b/ext2fs/pager.c
@@ -34,6 +34,10 @@ struct port_bucket *disk_pager_bucket;
/* A ports bucket to hold file pager ports. */
struct port_bucket *file_pager_bucket;
+/* Stores a reference to the requests instance used by the file pager so its
+ worker threads can be inhibited and resumed. */
+struct pager_requests *file_pager_requests;
+
pthread_spinlock_t node_to_page_lock = PTHREAD_SPINLOCK_INITIALIZER;
@@ -1217,11 +1221,38 @@ create_disk_pager (void)
file_pager_bucket = ports_create_bucket ();
/* Start libpagers worker threads. */
- err = pager_start_workers (file_pager_bucket);
+ err = pager_start_workers (file_pager_bucket, &file_pager_requests);
if (err)
ext2_panic ("can't create libpager worker threads: %s", strerror (err));
}
+error_t
+inhibit_ext2_pager (void)
+{
+ error_t err;
+
+ /* The file pager can rely on the disk pager, so inhibit the file
+ pager first. */
+
+ err = pager_inhibit_workers (file_pager_requests);
+ if (err)
+ return err;
+
+ err = pager_inhibit_workers (diskfs_disk_pager_requests);
+ /* We don't want only one pager disabled. */
+ if (err)
+ pager_resume_workers (file_pager_requests);
+
+ return err;
+}
+
+void
+resume_ext2_pager (void)
+{
+ pager_resume_workers (diskfs_disk_pager_requests);
+ pager_resume_workers (file_pager_requests);
+}
+
/* Call this to create a FILE_DATA pager and return a send right.
NODE must be locked. */
mach_port_t