mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-27 12:48:22 +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) {
|
||||
VOP_LOCK(node);
|
||||
int err = 0;
|
||||
if (node->type == V_TYPE_REGULAR || node->type == V_TYPE_BLKDEV) {
|
||||
if (vfs_iscacheable(node)) {
|
||||
*written = 0;
|
||||
// can't write a size 0 buffer
|
||||
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) {
|
||||
VOP_LOCK(node);
|
||||
int err = 0;
|
||||
if (node->type == V_TYPE_REGULAR || node->type == V_TYPE_BLKDEV) {
|
||||
if (vfs_iscacheable(node)) {
|
||||
*bytesread = 0;
|
||||
// can't read 0 bytes from the cache
|
||||
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
|
||||
|
||||
+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;
|
||||
cred_t *cred = proc ? &proc->cred : NULL;
|
||||
|
||||
if ((range->flags & VMM_FLAGS_FILE) && ((range->flags & VMM_FLAGS_SHARED) || range->vnode->type == V_TYPE_CHDEV)) {
|
||||
// shared file mapping or character device mapping
|
||||
if (range->vnode->type == V_TYPE_CHDEV) {
|
||||
// character device mapping
|
||||
if ((range->flags & VMM_FLAGS_FILE) && ((range->flags & VMM_FLAGS_SHARED) || vfs_iscacheable(range->vnode) == false)) {
|
||||
// shared file mapping or non cacheable mapping
|
||||
if (vfs_iscacheable(range->vnode) == false) {
|
||||
// non cacheable mapping
|
||||
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);
|
||||
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_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
|
||||
// it won't be marked dirty upon a vmm_unmap after this
|
||||
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
|
||||
if (range->flags & VMM_FLAGS_FILE) {
|
||||
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
|
||||
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);
|
||||
@@ -617,7 +617,7 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
|
||||
if ((range->flags & VMM_FLAGS_FILE) && (range->flags & VMM_FLAGS_SHARED)) {
|
||||
// shared file, remap it as writable
|
||||
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
|
||||
VOP_LOCK(range->vnode);
|
||||
vmmcache_makedirty(pmm_getpage(oldphys));
|
||||
@@ -635,7 +635,7 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
|
||||
} else {
|
||||
memcpy(MAKE_HHDM(newphys), MAKE_HHDM(oldphys), PAGE_SIZE);
|
||||
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);
|
||||
|
||||
status = true;
|
||||
|
||||
@@ -78,10 +78,9 @@ syscallret_t syscall_mmap(context_t *context, void *hint, size_t len, int prot,
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
// not all charcter devices support mapping, so check if its supported
|
||||
// (regular files and block devices go through the page cache)
|
||||
// if the vnode is not cacheable, we need to make sure we can map it
|
||||
// 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);
|
||||
if (ret.errno)
|
||||
goto cleanup;
|
||||
|
||||
Reference in New Issue
Block a user