mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 23:18:21 +00:00
vfs: vfs_iscacheable
This commit is contained in:
+2
-2
@@ -230,7 +230,7 @@ static int writenocache(vnode_t *node, page_t *page, uintmax_t pageoffset) {
|
|||||||
int vfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t *written, int flags) {
|
int vfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t *written, int flags) {
|
||||||
VOP_LOCK(node);
|
VOP_LOCK(node);
|
||||||
int err = 0;
|
int err = 0;
|
||||||
if (node->type == V_TYPE_REGULAR || node->type == V_TYPE_BLKDEV) {
|
if (vfs_iscacheable(node)) {
|
||||||
*written = 0;
|
*written = 0;
|
||||||
// can't write a size 0 buffer
|
// can't write a size 0 buffer
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
@@ -328,7 +328,7 @@ int vfs_write(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t
|
|||||||
int vfs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t *bytesread, int flags) {
|
int vfs_read(vnode_t *node, void *buffer, size_t size, uintmax_t offset, size_t *bytesread, int flags) {
|
||||||
VOP_LOCK(node);
|
VOP_LOCK(node);
|
||||||
int err = 0;
|
int err = 0;
|
||||||
if (node->type == V_TYPE_REGULAR || node->type == V_TYPE_BLKDEV) {
|
if (vfs_iscacheable(node)) {
|
||||||
*bytesread = 0;
|
*bytesread = 0;
|
||||||
// can't read 0 bytes from the cache
|
// can't read 0 bytes from the cache
|
||||||
if (size == 0)
|
if (size == 0)
|
||||||
|
|||||||
@@ -270,4 +270,14 @@ static inline mode_t vfs_getsystemtype(int type) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline bool vfs_iscacheable(vnode_t *vnode) {
|
||||||
|
int type = vnode->type;
|
||||||
|
// vnodes will be cacheable if:
|
||||||
|
// - the vnode is a regular or block device
|
||||||
|
// AND
|
||||||
|
// - the filesystem implementation exposes the VOP_*PAGE operations.
|
||||||
|
|
||||||
|
return (type == V_TYPE_REGULAR || type == V_TYPE_BLKDEV) && vnode->ops->putpage && vnode->ops->getpage;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+8
-8
@@ -227,10 +227,10 @@ static void destroyrange(vmmrange_t *range, uintmax_t _offset, size_t size, int
|
|||||||
proc_t *proc = thread ? thread->proc : NULL;
|
proc_t *proc = thread ? thread->proc : NULL;
|
||||||
cred_t *cred = proc ? &proc->cred : NULL;
|
cred_t *cred = proc ? &proc->cred : NULL;
|
||||||
|
|
||||||
if ((range->flags & VMM_FLAGS_FILE) && ((range->flags & VMM_FLAGS_SHARED) || range->vnode->type == V_TYPE_CHDEV)) {
|
if ((range->flags & VMM_FLAGS_FILE) && ((range->flags & VMM_FLAGS_SHARED) || vfs_iscacheable(range->vnode) == false)) {
|
||||||
// shared file mapping or character device mapping
|
// shared file mapping or non cacheable mapping
|
||||||
if (range->vnode->type == V_TYPE_CHDEV) {
|
if (vfs_iscacheable(range->vnode) == false) {
|
||||||
// character device mapping
|
// non cacheable mapping
|
||||||
VOP_LOCK(range->vnode);
|
VOP_LOCK(range->vnode);
|
||||||
__assert(VOP_MUNMAP(range->vnode, vaddr, range->offset + offset, mmuflagstovnodeflags(range->mmuflags) | (range->flags & VMM_FLAGS_SHARED ? V_FFLAGS_SHARED : 0), cred) == 0);
|
__assert(VOP_MUNMAP(range->vnode, vaddr, range->offset + offset, mmuflagstovnodeflags(range->mmuflags) | (range->flags & VMM_FLAGS_SHARED ? V_FFLAGS_SHARED : 0), cred) == 0);
|
||||||
VOP_UNLOCK(range->vnode);
|
VOP_UNLOCK(range->vnode);
|
||||||
@@ -280,7 +280,7 @@ static void changemmurange(vmmrange_t *range, void *base, size_t size, mmuflags_
|
|||||||
CHANGE_MASK_CHECK(mask, ARCH_MMU_FLAGS_USER, currentflags, newflags);
|
CHANGE_MASK_CHECK(mask, ARCH_MMU_FLAGS_USER, currentflags, newflags);
|
||||||
CHANGE_MASK_CHECK(mask, ARCH_MMU_FLAGS_NOEXEC, currentflags, newflags);
|
CHANGE_MASK_CHECK(mask, ARCH_MMU_FLAGS_NOEXEC, currentflags, newflags);
|
||||||
|
|
||||||
if ((range->flags & VMM_FLAGS_FILE) && (range->flags & VMM_FLAGS_SHARED) && (mask & ARCH_MMU_FLAGS_WRITE)) {
|
if ((range->flags & VMM_FLAGS_FILE) && (range->flags & VMM_FLAGS_SHARED) && (mask & ARCH_MMU_FLAGS_WRITE) && vfs_iscacheable(range->vnode)) {
|
||||||
// removing write permissions from a writeable dirty shared mapped page, mark it as dirty, as
|
// removing write permissions from a writeable dirty shared mapped page, mark it as dirty, as
|
||||||
// it won't be marked dirty upon a vmm_unmap after this
|
// it won't be marked dirty upon a vmm_unmap after this
|
||||||
page_t *page = pmm_getpage(physical);
|
page_t *page = pmm_getpage(physical);
|
||||||
@@ -568,7 +568,7 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
|
|||||||
// page not present in the page tables
|
// page not present in the page tables
|
||||||
if (range->flags & VMM_FLAGS_FILE) {
|
if (range->flags & VMM_FLAGS_FILE) {
|
||||||
uintmax_t mapoffset = (uintptr_t)addr - (uintptr_t)range->start;
|
uintmax_t mapoffset = (uintptr_t)addr - (uintptr_t)range->start;
|
||||||
if (range->vnode->type != V_TYPE_BLKDEV && range->vnode->type != V_TYPE_REGULAR) {
|
if (vfs_iscacheable(range->vnode) == false) {
|
||||||
// map non cacheable vnodes
|
// map non cacheable vnodes
|
||||||
VOP_LOCK(range->vnode);
|
VOP_LOCK(range->vnode);
|
||||||
__assert(VOP_MMAP(range->vnode, addr, range->offset + mapoffset, mmuflagstovnodeflags(range->mmuflags) | (range->flags & VMM_FLAGS_SHARED ? V_FFLAGS_SHARED : 0), cred) == 0);
|
__assert(VOP_MMAP(range->vnode, addr, range->offset + mapoffset, mmuflagstovnodeflags(range->mmuflags) | (range->flags & VMM_FLAGS_SHARED ? V_FFLAGS_SHARED : 0), cred) == 0);
|
||||||
@@ -617,7 +617,7 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
|
|||||||
if ((range->flags & VMM_FLAGS_FILE) && (range->flags & VMM_FLAGS_SHARED)) {
|
if ((range->flags & VMM_FLAGS_FILE) && (range->flags & VMM_FLAGS_SHARED)) {
|
||||||
// shared file, remap it as writable
|
// shared file, remap it as writable
|
||||||
arch_mmu_remap(_cpu()->vmmctx->pagetable, oldphys, addr, range->mmuflags);
|
arch_mmu_remap(_cpu()->vmmctx->pagetable, oldphys, addr, range->mmuflags);
|
||||||
if (range->vnode->type != V_TYPE_CHDEV) {
|
if (vfs_iscacheable(range->vnode)) {
|
||||||
// and if its a cache page, mark it as dirty
|
// and if its a cache page, mark it as dirty
|
||||||
VOP_LOCK(range->vnode);
|
VOP_LOCK(range->vnode);
|
||||||
vmmcache_makedirty(pmm_getpage(oldphys));
|
vmmcache_makedirty(pmm_getpage(oldphys));
|
||||||
@@ -635,7 +635,7 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
|
|||||||
} else {
|
} else {
|
||||||
memcpy(MAKE_HHDM(newphys), MAKE_HHDM(oldphys), PAGE_SIZE);
|
memcpy(MAKE_HHDM(newphys), MAKE_HHDM(oldphys), PAGE_SIZE);
|
||||||
arch_mmu_remap(_cpu()->vmmctx->pagetable, newphys, addr, range->mmuflags);
|
arch_mmu_remap(_cpu()->vmmctx->pagetable, newphys, addr, range->mmuflags);
|
||||||
if ((range->flags & VMM_FLAGS_FILE) == 0 || range->vnode->type != V_TYPE_CHDEV)
|
if ((range->flags & VMM_FLAGS_FILE) == 0 || vfs_iscacheable(range->vnode))
|
||||||
pmm_release(oldphys);
|
pmm_release(oldphys);
|
||||||
|
|
||||||
status = true;
|
status = true;
|
||||||
|
|||||||
@@ -78,10 +78,9 @@ syscallret_t syscall_mmap(context_t *context, void *hint, size_t len, int prot,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
// not all charcter devices support mapping, so check if its supported
|
// if the vnode is not cacheable, we need to make sure we can map it
|
||||||
// (regular files and block devices go through the page cache)
|
|
||||||
// TODO move this check to vmm_map once the return value of mmap is fixed to return an errno
|
// TODO move this check to vmm_map once the return value of mmap is fixed to return an errno
|
||||||
if (type == V_TYPE_CHDEV) {
|
if (vfs_iscacheable(file->vnode) == false) {
|
||||||
ret.errno = VOP_MMAP(file->vnode, VOP_MMAP_ADDRESS_MMAP_SUPPORTED, 0, 0, NULL);
|
ret.errno = VOP_MMAP(file->vnode, VOP_MMAP_ADDRESS_MMAP_SUPPORTED, 0, 0, NULL);
|
||||||
if (ret.errno)
|
if (ret.errno)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|||||||
Reference in New Issue
Block a user