mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-31 06:28:22 +00:00
vfs: redo locking
This commit is contained in:
+12
-1
@@ -231,11 +231,15 @@ static void destroyrange(vmmrange_t *range, uintmax_t _offset, size_t size, int
|
||||
// shared file mapping or character device mapping
|
||||
if (range->vnode->type == V_TYPE_CHDEV) {
|
||||
// character device 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);
|
||||
} else if (arch_mmu_iswritable(_cpu()->vmmctx->pagetable, vaddr) && arch_mmu_isdirty(_cpu()->vmmctx->pagetable, vaddr)) {
|
||||
// dirty page cache mapping
|
||||
arch_mmu_unmap(_cpu()->vmmctx->pagetable, vaddr);
|
||||
VOP_LOCK(range->vnode);
|
||||
vmmcache_makedirty(pmm_getpage(physical));
|
||||
VOP_UNLOCK(range->vnode);
|
||||
pmm_release(physical);
|
||||
} else {
|
||||
// non dirty page mapping
|
||||
@@ -499,12 +503,16 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
|
||||
uintmax_t mapoffset = (uintptr_t)addr - (uintptr_t)range->start;
|
||||
if (range->vnode->type != V_TYPE_BLKDEV && range->vnode->type != V_TYPE_REGULAR) {
|
||||
// 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);
|
||||
VOP_UNLOCK(range->vnode);
|
||||
status = true;
|
||||
} else {
|
||||
// cacheable vnode
|
||||
page_t *res = NULL;
|
||||
VOP_LOCK(range->vnode);
|
||||
int error = vmmcache_getpage(range->vnode, range->offset + mapoffset, &res);
|
||||
VOP_UNLOCK(range->vnode);
|
||||
if (error == ENXIO || error == ENOMEM) {
|
||||
if (error == ENOMEM)
|
||||
printf("vmm: out of memory to handle getpage (sending SIGBUS)\n");
|
||||
@@ -540,8 +548,11 @@ bool vmm_pagefault(void *addr, bool user, int actions) {
|
||||
void *oldphys = arch_mmu_getphysical(_cpu()->vmmctx->pagetable, addr);
|
||||
if ((range->flags & VMM_FLAGS_FILE) && (range->flags & VMM_FLAGS_SHARED)) {
|
||||
arch_mmu_remap(_cpu()->vmmctx->pagetable, oldphys, addr, range->mmuflags);
|
||||
if (range->vnode->type != V_TYPE_CHDEV)
|
||||
if (range->vnode->type != V_TYPE_CHDEV) {
|
||||
VOP_LOCK(range->vnode);
|
||||
vmmcache_makedirty(pmm_getpage(oldphys));
|
||||
VOP_UNLOCK(range->vnode);
|
||||
}
|
||||
|
||||
status = true;
|
||||
} else {
|
||||
|
||||
@@ -102,6 +102,7 @@ static void removepage(page_t *page) {
|
||||
--vmmcache_cachedpages;
|
||||
}
|
||||
|
||||
// vnode expected locked
|
||||
int vmmcache_getpage(vnode_t *vnode, uintmax_t offset, page_t **res) {
|
||||
__assert(vnode->type == V_TYPE_REGULAR || vnode->type == V_TYPE_BLKDEV);
|
||||
__assert((offset % PAGE_SIZE) == 0);
|
||||
@@ -292,6 +293,7 @@ int vmmcache_truncate(vnode_t *vnode, uintmax_t offset) {
|
||||
|
||||
// called with lock held
|
||||
// returns with lock released
|
||||
// expects backing lock to be held
|
||||
static int syncpage(page_t *page) {
|
||||
__assert(page->flags & PAGE_FLAGS_DIRTY);
|
||||
page->flags &= ~PAGE_FLAGS_DIRTY;
|
||||
@@ -312,6 +314,7 @@ static int syncpage(page_t *page) {
|
||||
|
||||
static page_t *dirtylist;
|
||||
|
||||
// expects vnode to be held
|
||||
int vmmcache_syncvnode(vnode_t *vnode, uintmax_t offset, size_t size) {
|
||||
offset = ROUND_DOWN(offset, PAGE_SIZE);
|
||||
uintmax_t top = offset + size;
|
||||
@@ -381,6 +384,7 @@ int vmmcache_sync() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// backing expected locked
|
||||
int vmmcache_makedirty(page_t *page) {
|
||||
bool madedirty = false;
|
||||
HOLD_LOCK();
|
||||
@@ -437,7 +441,9 @@ static void writer() {
|
||||
|
||||
page->writenext = NULL;
|
||||
// TODO notify error on vmmcache_syncvnode
|
||||
VOP_LOCK(page->backing);
|
||||
syncpage((page_t *)page);
|
||||
VOP_UNLOCK(page->backing);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user