diff options
Diffstat (limited to 'ext2fs')
-rw-r--r-- | ext2fs/ext2fs.c | 12 | ||||
-rw-r--r-- | ext2fs/ext2fs.h | 6 | ||||
-rw-r--r-- | ext2fs/pager.c | 33 |
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 |