From d1a9c5cd45d88a3f62748751566459bd6072ff33 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Sat, 21 Mar 2026 10:46:15 +0000 Subject: [PATCH] lib: fs: implement private and shared file mappings --- lib/libfs/include/fs/inode.h | 3 ++ lib/libfs/interface/map.c | 76 +++++++++++++++++++++++++++--------- lib/libfs/mapping.h | 7 +++- 3 files changed, 66 insertions(+), 20 deletions(-) diff --git a/lib/libfs/include/fs/inode.h b/lib/libfs/include/fs/inode.h index da0d2b3..36b4648 100644 --- a/lib/libfs/include/fs/inode.h +++ b/lib/libfs/include/fs/inode.h @@ -2,12 +2,14 @@ #define FS_INODE_H_ #include +#include #include struct fs_inode; struct fs_dentry; struct fs_superblock; struct fs_file_ops; +struct file_mapping; enum fs_inode_mode { FS_INODE_REG = 0x01u, @@ -27,6 +29,7 @@ struct fs_inode { const struct fs_inode_ops *i_ops; const struct fs_file_ops *i_fops; size_t i_size; + struct file_mapping *i_shared_mapping; }; extern enum fs_status fs_inode_lookup( diff --git a/lib/libfs/interface/map.c b/lib/libfs/interface/map.c index c855f57..a0632b8 100644 --- a/lib/libfs/interface/map.c +++ b/lib/libfs/interface/map.c @@ -11,29 +11,25 @@ #include #include -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; diff --git a/lib/libfs/mapping.h b/lib/libfs/mapping.h index 30f3c0d..572ae26 100644 --- a/lib/libfs/mapping.h +++ b/lib/libfs/mapping.h @@ -7,10 +7,15 @@ struct fs_file; +enum file_mapping_type { + FILE_MAPPING_PRIVATE, + FILE_MAPPING_SHARED, +}; + struct file_mapping { + enum file_mapping_type m_type; struct fs_file *m_file; kern_handle_t m_vmo; - off_t m_file_offset; struct queue_entry m_entry; };