vm: object: implement vm_object_put_page to add existing pages to a vmo
This commit is contained in:
@@ -89,6 +89,10 @@ extern struct vm_page *vm_object_get_page(
|
||||
off_t offset,
|
||||
enum vm_object_flags flags,
|
||||
unsigned long *irq_flags);
|
||||
extern kern_status_t vm_object_put_page(
|
||||
struct vm_object *vo,
|
||||
off_t offset,
|
||||
struct vm_page *pg);
|
||||
|
||||
extern kern_status_t vm_object_read(
|
||||
struct vm_object *vo,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
#include <kernel/address-space.h>
|
||||
#include <kernel/panic.h>
|
||||
#include <kernel/printk.h>
|
||||
#include <kernel/sched.h>
|
||||
#include <kernel/util.h>
|
||||
@@ -342,6 +343,54 @@ static struct vm_page *alloc_page(struct vm_object *vo, off_t offset)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kern_status_t vm_object_put_page(
|
||||
struct vm_object *vo,
|
||||
off_t offset,
|
||||
struct vm_page *pg)
|
||||
{
|
||||
struct btree_node *cur = vo->vo_pages.b_root;
|
||||
if (!vo->vo_pages.b_root) {
|
||||
vo->vo_pages.b_root = &pg->p_bnode;
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
while (cur) {
|
||||
struct vm_page *page
|
||||
= BTREE_CONTAINER(struct vm_page, p_bnode, cur);
|
||||
struct btree_node *next = NULL;
|
||||
|
||||
off_t base = page->p_vmo_offset;
|
||||
off_t limit = base + vm_page_get_size_bytes(page);
|
||||
if (offset < base) {
|
||||
next = btree_left(cur);
|
||||
} else if (offset >= limit) {
|
||||
next = btree_right(cur);
|
||||
} else {
|
||||
panic("vm_object_put_page: page already exists");
|
||||
return KERN_NAME_EXISTS;
|
||||
}
|
||||
|
||||
if (next) {
|
||||
cur = next;
|
||||
continue;
|
||||
}
|
||||
|
||||
pg->p_vmo_offset = offset;
|
||||
|
||||
if (offset < base) {
|
||||
btree_put_left(cur, &pg->p_bnode);
|
||||
} else {
|
||||
btree_put_right(cur, &pg->p_bnode);
|
||||
}
|
||||
|
||||
btree_insert_fixup(&vo->vo_pages, &pg->p_bnode);
|
||||
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
return KERN_FATAL_ERROR;
|
||||
}
|
||||
|
||||
static struct vm_page *get_page(struct vm_object *vo, off_t offset)
|
||||
{
|
||||
struct btree_node *cur = vo->vo_pages.b_root;
|
||||
|
||||
Reference in New Issue
Block a user