mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +00:00
tmpfs: mmap and munmap
This commit is contained in:
+45
-2
@@ -8,6 +8,10 @@
|
||||
#include <util.h>
|
||||
#include <kernel/abi.h>
|
||||
#include <kernel/devfs.h>
|
||||
#include <kernel/pmm.h>
|
||||
#include <kernel/vmm.h>
|
||||
#include <arch/cpu.h>
|
||||
#include <string.h>
|
||||
|
||||
static scache_t *nodecache;
|
||||
static tmpfsnode_t *newnode(vfs_t *vfs, int type);
|
||||
@@ -234,7 +238,7 @@ static int tmpfs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset
|
||||
return 0;
|
||||
}
|
||||
|
||||
// rtop of read goes past end of file
|
||||
// top of read goes past end of file
|
||||
if (offset + size > tmpnode->attr.size)
|
||||
size = tmpnode->attr.size - offset;
|
||||
|
||||
@@ -354,6 +358,43 @@ static int tmpfs_readlink(vnode_t *node, char **link, cred_t *cred) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tmpfs_mmap(vnode_t *node, void *addr, uintmax_t offset, int flags, cred_t *cred) {
|
||||
void *paddr = pmm_alloc(1, PMM_SECTION_DEFAULT);
|
||||
if (paddr == NULL)
|
||||
return ENOMEM;
|
||||
|
||||
if (arch_mmu_map(_cpu()->vmmctx->pagetable, paddr, addr, vnodeflagstommuflags(flags)) == false) {
|
||||
pmm_free(paddr, 1);
|
||||
return ENOMEM;
|
||||
}
|
||||
|
||||
size_t readc;
|
||||
int e = tmpfs_read(node, addr, PAGE_SIZE, offset, flags, &readc, cred);
|
||||
if (e) {
|
||||
arch_mmu_unmap(_cpu()->vmmctx->pagetable, addr);
|
||||
pmm_free(paddr, 1);
|
||||
return e;
|
||||
}
|
||||
|
||||
memset((void *)((uintptr_t)addr + readc), 0, PAGE_SIZE - readc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tmpfs_munmap(vnode_t *node, void *addr, uintmax_t offset, int flags, cred_t *cred) {
|
||||
if ((flags & V_FFLAGS_SHARED) == 0) {
|
||||
size_t wc;
|
||||
// TODO no growing flag
|
||||
__assert(tmpfs_write(node, addr, PAGE_SIZE, offset, flags, &wc, cred) == 0);
|
||||
}
|
||||
|
||||
void *paddr = arch_mmu_getphysical(_cpu()->vmmctx->pagetable, addr);
|
||||
__assert(paddr);
|
||||
arch_mmu_unmap(_cpu()->vmmctx->pagetable, addr);
|
||||
pmm_free(paddr, 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int tmpfs_inactive(vnode_t *node) {
|
||||
freenode((tmpfsnode_t *)node);
|
||||
return 0;
|
||||
@@ -379,7 +420,9 @@ static vops_t vnops = {
|
||||
.link = tmpfs_link,
|
||||
.symlink = tmpfs_symlink,
|
||||
.readlink = tmpfs_readlink,
|
||||
.inactive = tmpfs_inactive
|
||||
.inactive = tmpfs_inactive,
|
||||
.mmap = tmpfs_mmap,
|
||||
.munmap = tmpfs_munmap
|
||||
};
|
||||
|
||||
static tmpfsnode_t *newnode(vfs_t *vfs, int type) {
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
#include <arch/mmu.h>
|
||||
#include <spinlock.h>
|
||||
#include <kernel/vfs.h>
|
||||
|
||||
#define VMM_FLAGS_PAGESIZE 1
|
||||
#define VMM_FLAGS_ALLOCATE 2
|
||||
@@ -57,6 +58,18 @@ typedef struct {
|
||||
|
||||
extern vmmcontext_t vmm_kernelctx;
|
||||
|
||||
static inline mmuflags_t vnodeflagstommuflags(int flags) {
|
||||
mmuflags_t mmuflags = 0;
|
||||
if (flags & V_FFLAGS_READ)
|
||||
mmuflags |= ARCH_MMU_FLAGS_READ;
|
||||
if (flags & V_FFLAGS_WRITE)
|
||||
mmuflags |= ARCH_MMU_FLAGS_WRITE;
|
||||
if ((flags & V_FFLAGS_EXEC) == 0)
|
||||
mmuflags |= ARCH_MMU_FLAGS_NOEXEC;
|
||||
|
||||
return mmuflags;
|
||||
}
|
||||
|
||||
void *vmm_map(void *addr, size_t size, int flags, mmuflags_t mmuflags, void *private);
|
||||
void vmm_unmap(void *addr, size_t size, int flags);
|
||||
bool vmm_pagefault(void *addr, bool user, int actions);
|
||||
|
||||
Reference in New Issue
Block a user