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,
|
off_t offset,
|
||||||
enum vm_object_flags flags,
|
enum vm_object_flags flags,
|
||||||
unsigned long *irq_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(
|
extern kern_status_t vm_object_read(
|
||||||
struct vm_object *vo,
|
struct vm_object *vo,
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
#include <kernel/address-space.h>
|
#include <kernel/address-space.h>
|
||||||
|
#include <kernel/panic.h>
|
||||||
#include <kernel/printk.h>
|
#include <kernel/printk.h>
|
||||||
#include <kernel/sched.h>
|
#include <kernel/sched.h>
|
||||||
#include <kernel/util.h>
|
#include <kernel/util.h>
|
||||||
@@ -342,6 +343,54 @@ static struct vm_page *alloc_page(struct vm_object *vo, off_t offset)
|
|||||||
return NULL;
|
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)
|
static struct vm_page *get_page(struct vm_object *vo, off_t offset)
|
||||||
{
|
{
|
||||||
struct btree_node *cur = vo->vo_pages.b_root;
|
struct btree_node *cur = vo->vo_pages.b_root;
|
||||||
|
|||||||
Reference in New Issue
Block a user