mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-11-01 15:08:21 +00:00
page cache: zero upper bytes on unaligned truncate
This commit is contained in:
+23
-4
@@ -2,6 +2,7 @@
|
|||||||
#include <semaphore.h>
|
#include <semaphore.h>
|
||||||
#include <logging.h>
|
#include <logging.h>
|
||||||
#include <kernel/init.h>
|
#include <kernel/init.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
list_node_t list_node;
|
list_node_t list_node;
|
||||||
@@ -228,10 +229,7 @@ void mm_cache_take_page(page_t *page) {
|
|||||||
page_notify_waiters(page);
|
page_notify_waiters(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void truncate_iterate(void *p) {
|
static void truncate_page(page_t *page) {
|
||||||
page_t *page = p;
|
|
||||||
__atomic_sub_fetch(&mm_cache_cached_pages, 1, __ATOMIC_RELAXED);
|
|
||||||
|
|
||||||
int old_flags = __atomic_load_n(&page->flags, __ATOMIC_RELAXED);
|
int old_flags = __atomic_load_n(&page->flags, __ATOMIC_RELAXED);
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int new_flags = (old_flags | PAGE_FLAGS_TRUNCATED) & ~PAGE_FLAGS_PINNED;
|
int new_flags = (old_flags | PAGE_FLAGS_TRUNCATED) & ~PAGE_FLAGS_PINNED;
|
||||||
@@ -248,11 +246,32 @@ static void truncate_iterate(void *p) {
|
|||||||
mm_release_page(mm_get_page_address(page));
|
mm_release_page(mm_get_page_address(page));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void truncate_iterate(void *p) {
|
||||||
|
__atomic_sub_fetch(&mm_cache_cached_pages, 1, __ATOMIC_RELAXED);
|
||||||
|
truncate_page(p);
|
||||||
|
}
|
||||||
|
|
||||||
int mm_cache_truncate(vnode_t *vnode, uintmax_t offset) {
|
int mm_cache_truncate(vnode_t *vnode, uintmax_t offset) {
|
||||||
uintmax_t min_page = ROUND_UP(offset, PAGE_SIZE) / PAGE_SIZE;
|
uintmax_t min_page = ROUND_UP(offset, PAGE_SIZE) / PAGE_SIZE;
|
||||||
|
size_t page_offset = offset % PAGE_SIZE;
|
||||||
|
|
||||||
pushlock_acquire_exclusive(&vnode->pages_lock);
|
pushlock_acquire_exclusive(&vnode->pages_lock);
|
||||||
|
|
||||||
|
if (page_offset) {
|
||||||
|
uintmax_t page_start = offset - page_offset;
|
||||||
|
page_t *page = lookup_page(vnode, page_start);
|
||||||
|
if (page) {
|
||||||
|
int flags = __atomic_load_n(&page->flags, __ATOMIC_ACQUIRE);
|
||||||
|
if (flags & PAGE_FLAGS_READY) {
|
||||||
|
void *address = MAKE_HHDM(mm_get_page_address(page));
|
||||||
|
memset((char *)address + page_offset, 0, PAGE_SIZE - page_offset);
|
||||||
|
} else {
|
||||||
|
remove_page(vnode, page_start);
|
||||||
|
truncate_page(page);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
trie_iterate(&vnode->pages, min_page, UINT64_MAX, truncate_iterate);
|
trie_iterate(&vnode->pages, min_page, UINT64_MAX, truncate_iterate);
|
||||||
trie_truncate(&vnode->pages, min_page);
|
trie_truncate(&vnode->pages, min_page);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user