lib: fs: implement private and shared file mappings

This commit is contained in:
2026-03-21 10:46:15 +00:00
parent 3bf995cdf6
commit d1a9c5cd45
3 changed files with 66 additions and 20 deletions

View File

@@ -11,29 +11,25 @@
#include <stdio.h>
#include <sys/mman.h>
extern kern_status_t fs_msg_map(
xpc_context_t *xpc,
const xpc_endpoint_t *sender,
static int create_file_mapping(
struct fs_context *ctx,
int prot,
int flags,
int *out_err,
kern_handle_t *out_vmo,
void *arg)
struct fs_file *f,
struct file_mapping **out)
{
struct fs_context *ctx = arg;
struct fs_file *f = fs_context_get_file(ctx, sender->e_port);
if (!f) {
*out_err = EBADF;
return KERN_OK;
if ((flags & MAP_SHARED) && f->f_inode->i_shared_mapping) {
*out = f->f_inode->i_shared_mapping;
return SUCCESS;
}
struct file_mapping *mapping = fs_context_alloc(ctx, sizeof *mapping);
if (!mapping) {
*out_err = ENOMEM;
return KERN_OK;
return ENOMEM;
}
kern_logf("mapping file %s", f->f_dent->d_name);
memset(mapping, 0x0, sizeof *mapping);
vm_prot_t vm_prot = VM_PROT_USER;
if (prot & PROT_READ) {
vm_prot |= VM_PROT_READ;
@@ -59,14 +55,56 @@ extern kern_status_t fs_msg_map(
if (status != KERN_OK) {
fs_context_free(ctx, mapping);
*out_err = __errno_from_kern_status(status);
return KERN_OK;
return __errno_from_kern_status(status);
}
mapping->m_file = f;
mapping->m_file_offset = 0;
kern_handle_duplicate(vmo, &mapping->m_vmo);
queue_push_back(&f->f_mappings, &mapping->m_entry);
mapping->m_vmo = vmo;
if (flags & MAP_SHARED) {
mapping->m_type = FILE_MAPPING_SHARED;
f->f_inode->i_shared_mapping = mapping;
} else {
mapping->m_type = FILE_MAPPING_PRIVATE;
queue_push_back(&f->f_mappings, &mapping->m_entry);
}
*out = mapping;
return SUCCESS;
}
extern kern_status_t fs_msg_map(
xpc_context_t *xpc,
const xpc_endpoint_t *sender,
int prot,
int flags,
int *out_err,
kern_handle_t *out_vmo,
void *arg)
{
struct fs_context *ctx = arg;
struct fs_file *f = fs_context_get_file(ctx, sender->e_port);
if (!f) {
*out_err = EBADF;
return KERN_OK;
}
struct file_mapping *mapping = NULL;
int err = create_file_mapping(ctx, prot, flags, f, &mapping);
if (err != SUCCESS) {
*out_err = err;
return KERN_OK;
}
kern_tracef(
"mapping file %s (%s) using vmo %zx",
f->f_dent->d_name,
(flags & MAP_SHARED) ? "shared" : "private",
mapping->m_vmo);
kern_handle_t vmo;
kern_handle_duplicate(mapping->m_vmo, &vmo);
*out_err = SUCCESS;
*out_vmo = vmo;