diff options
author | Sergey Bugaev <bugaevc@gmail.com> | 2021-05-21 12:54:13 +0300 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2022-08-10 22:04:21 +0200 |
commit | 736c90333e887da5215e3c8a0bb489342b5fd23c (patch) | |
tree | e097878e08201eb3ca7e6a2dba413dbf403cfdb4 /ext2fs | |
parent | ff0487ddf0ba1f98daef8265eb3a50b1570b8f41 (diff) | |
download | hurd-736c90333e887da5215e3c8a0bb489342b5fd23c.tar.gz hurd-736c90333e887da5215e3c8a0bb489342b5fd23c.tar.bz2 hurd-736c90333e887da5215e3c8a0bb489342b5fd23c.zip |
ext2fs: Return read-only memory objects when appropriate
Diffstat (limited to 'ext2fs')
-rw-r--r-- | ext2fs/pager.c | 73 |
1 files changed, 39 insertions, 34 deletions
diff --git a/ext2fs/pager.c b/ext2fs/pager.c index a47c53ce..105dc93d 100644 --- a/ext2fs/pager.c +++ b/ext2fs/pager.c @@ -1296,6 +1296,7 @@ resume_ext2_pager (void) mach_port_t diskfs_get_filemap (struct node *node, vm_prot_t prot) { + struct pager *pager; mach_port_t right; assert_backtrace (S_ISDIR (node->dn_stat.st_mode) @@ -1303,45 +1304,49 @@ diskfs_get_filemap (struct node *node, vm_prot_t prot) || (S_ISLNK (node->dn_stat.st_mode))); pthread_spin_lock (&node_to_page_lock); - do - { - struct pager *pager = diskfs_node_disknode (node)->pager; - if (pager) - { - right = pager_get_port (pager); - assert_backtrace (MACH_PORT_VALID (right)); - pager_get_upi (pager)->max_prot |= prot; - } - else - { - struct user_pager_info *upi; - pager = pager_create_alloc (sizeof *upi, file_pager_bucket, - MAY_CACHE, MEMORY_OBJECT_COPY_DELAY, 0); - if (pager == NULL) - { - pthread_spin_unlock (&node_to_page_lock); - return MACH_PORT_NULL; - } - upi = pager_get_upi (pager); - upi->type = FILE_DATA; - upi->node = node; - upi->max_prot = prot; - diskfs_nref_light (node); - diskfs_node_disknode (node)->pager = pager; + pager = diskfs_node_disknode (node)->pager; + if (pager) + { + ports_port_ref (pager); + pager_get_upi (pager)->max_prot |= prot; + } + else + { + struct user_pager_info *upi; + pager = pager_create_alloc (sizeof *upi, file_pager_bucket, + MAY_CACHE, MEMORY_OBJECT_COPY_DELAY, 0); + if (pager == NULL) + { + pthread_spin_unlock (&node_to_page_lock); + return MACH_PORT_NULL; + } + + upi = pager_get_upi (pager); + upi->type = FILE_DATA; + upi->node = node; + upi->max_prot = prot; + diskfs_nref_light (node); + diskfs_node_disknode (node)->pager = pager; + + /* A weak reference for being part of the node. */ + ports_port_ref_weak (pager); + } - /* A weak reference for being part of the node. */ - ports_port_ref_weak (diskfs_node_disknode (node)->pager); + pthread_spin_unlock (&node_to_page_lock); - right = pager_get_port (diskfs_node_disknode (node)->pager); - ports_port_deref (diskfs_node_disknode (node)->pager); - } + if (prot & VM_PROT_WRITE) + right = ports_get_send_right (pager); + else + { + right = pager_get_ro_port (pager); + mach_port_mod_refs (mach_task_self (), right, + MACH_PORT_RIGHT_SEND, +1); } - while (right == MACH_PORT_NULL); - pthread_spin_unlock (&node_to_page_lock); - mach_port_insert_right (mach_task_self (), right, right, - MACH_MSG_TYPE_MAKE_SEND); + ports_port_deref (pager); + + assert_backtrace (MACH_PORT_VALID (right)); return right; } |