From 7c3323a25bc1d5844feb7f9ed241fdbdb4819739 Mon Sep 17 00:00:00 2001 From: Sergey Bugaev Date: Fri, 21 May 2021 13:21:15 +0300 Subject: tmpfs: Return read-only memory objects when appropriate --- tmpfs/node.c | 37 +++++++++++++++++++++++++++++++------ 1 file changed, 31 insertions(+), 6 deletions(-) (limited to 'tmpfs/node.c') diff --git a/tmpfs/node.c b/tmpfs/node.c index 02d213ed..1a73a164 100644 --- a/tmpfs/node.c +++ b/tmpfs/node.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include "default_pager_U.h" @@ -72,9 +73,11 @@ diskfs_free_node (struct node *np, mode_t mode) switch (np->dn->type) { case DT_REG: + /* XXX GNU Mach will terminate the object, and thus existing mappings + * will get SIGBUS. */ + if (np->dn->u.reg.ro_memobj != MACH_PORT_NULL) + mach_port_deallocate (mach_task_self (), np->dn->u.reg.ro_memobj); if (np->dn->u.reg.memobj != MACH_PORT_NULL) { - /* XXX GNU Mach will terminate the object, and thus existing mappings - * will get SIGBUS. */ vm_deallocate (mach_task_self (), np->dn->u.reg.memref, 4096); mach_port_deallocate (mach_task_self (), np->dn->u.reg.memobj); } @@ -520,6 +523,7 @@ mach_port_t diskfs_get_filemap (struct node *np, vm_prot_t prot) { error_t err; + mach_port_t right; if (np->dn->type != DT_REG) { @@ -561,14 +565,35 @@ diskfs_get_filemap (struct node *np, vm_prot_t prot) assert_perror_backtrace (err); } - /* XXX always writable */ + if (prot & VM_PROT_WRITE) + right = np->dn->u.reg.memobj; + else if (np->dn->u.reg.ro_memobj == MACH_PORT_NULL) + { + vm_offset_t offset = 0; + vm_offset_t start = 0; + vm_size_t len = ~0; + err = memory_object_create_proxy (mach_task_self (), + VM_PROT_READ | VM_PROT_EXECUTE, + &np->dn->u.reg.memobj, 1, + &offset, 1, &start, 1, &len, 1, + &np->dn->u.reg.ro_memobj); + if (err) + { + errno = err; + return MACH_PORT_NULL; + } + + right = np->dn->u.reg.ro_memobj; + } + else + right = np->dn->u.reg.ro_memobj; /* Add a reference for each call, the caller will deallocate it. */ - err = mach_port_mod_refs (mach_task_self (), np->dn->u.reg.memobj, - MACH_PORT_RIGHT_SEND, +1); + err = mach_port_mod_refs (mach_task_self (), right, + MACH_PORT_RIGHT_SEND, +1); assert_perror_backtrace (err); - return np->dn->u.reg.memobj; + return right; } /* The user must define this function. Return a `struct pager *' suitable -- cgit v1.2.3