lib: fs: implement memory-mapped file i/o
This commit is contained in:
14
lib/libfs/interface/close.c
Normal file
14
lib/libfs/interface/close.c
Normal file
@@ -0,0 +1,14 @@
|
||||
#include "../interface.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <mango/status.h>
|
||||
|
||||
extern kern_status_t fs_msg_close(
|
||||
xpc_context_t *ctx,
|
||||
const xpc_endpoint_t *sender,
|
||||
int *out_err,
|
||||
void *arg)
|
||||
{
|
||||
*out_err = ENOSYS;
|
||||
return KERN_OK;
|
||||
}
|
||||
74
lib/libfs/interface/map.c
Normal file
74
lib/libfs/interface/map.c
Normal file
@@ -0,0 +1,74 @@
|
||||
#include "../file.h"
|
||||
#include "../mapping.h"
|
||||
|
||||
#include <errno.h>
|
||||
#include <fs/context.h>
|
||||
#include <fs/file.h>
|
||||
#include <fs/status.h>
|
||||
#include <mango/handle.h>
|
||||
#include <mango/log.h>
|
||||
#include <mango/vm.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/mman.h>
|
||||
|
||||
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 = fs_context_alloc(ctx, sizeof *mapping);
|
||||
if (!mapping) {
|
||||
*out_err = ENOMEM;
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
kern_logf("mapping file %s", f->f_dent->d_name);
|
||||
vm_prot_t vm_prot = VM_PROT_USER;
|
||||
if (prot & PROT_READ) {
|
||||
vm_prot |= VM_PROT_READ;
|
||||
}
|
||||
|
||||
if (prot & PROT_WRITE) {
|
||||
vm_prot |= VM_PROT_WRITE;
|
||||
}
|
||||
|
||||
if (prot & PROT_EXEC) {
|
||||
vm_prot |= VM_PROT_EXEC;
|
||||
}
|
||||
|
||||
kern_handle_t vmo = KERN_HANDLE_INVALID;
|
||||
kern_status_t status = vm_controller_create_object(
|
||||
fs_context_get_vm_controller(ctx),
|
||||
f->f_dent->d_name,
|
||||
strlen(f->f_dent->d_name),
|
||||
(equeue_key_t)mapping,
|
||||
f->f_inode->i_size,
|
||||
vm_prot,
|
||||
&vmo);
|
||||
|
||||
if (status != KERN_OK) {
|
||||
fs_context_free(ctx, mapping);
|
||||
*out_err = __errno_from_kern_status(status);
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
*out_err = SUCCESS;
|
||||
*out_vmo = vmo;
|
||||
return KERN_OK;
|
||||
}
|
||||
29
lib/libfs/interface/write.c
Normal file
29
lib/libfs/interface/write.c
Normal file
@@ -0,0 +1,29 @@
|
||||
#include <errno.h>
|
||||
#include <fs/context.h>
|
||||
#include <fs/file.h>
|
||||
#include <fs/status.h>
|
||||
|
||||
extern kern_status_t fs_msg_write(
|
||||
xpc_context_t *xpc,
|
||||
const xpc_endpoint_t *sender,
|
||||
const xpc_buffer_t *data,
|
||||
int *out_err,
|
||||
size_t *out_nr_written,
|
||||
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;
|
||||
}
|
||||
|
||||
size_t start = fs_file_get_cursor(f);
|
||||
enum fs_status status = fs_file_write(f, data, data->buf_len);
|
||||
size_t end = fs_file_get_cursor(f);
|
||||
|
||||
*out_err = fs_status_to_errno(status);
|
||||
*out_nr_written = end - start;
|
||||
|
||||
return KERN_OK;
|
||||
}
|
||||
Reference in New Issue
Block a user