vm: object: implement creating copy-on-write duplicates of vm-objects
This commit is contained in:
@@ -84,6 +84,9 @@ extern struct vm_object *vm_object_create_in_place(
|
||||
size_t data_len,
|
||||
vm_prot_t prot);
|
||||
|
||||
/* create a copy-on-write duplicate of a vm-object */
|
||||
extern struct vm_object *vm_object_duplicate_cow(struct vm_object *vmo);
|
||||
|
||||
extern struct vm_page *vm_object_get_page(
|
||||
struct vm_object *vo,
|
||||
off_t offset,
|
||||
|
||||
@@ -278,6 +278,43 @@ extern struct vm_object *vm_object_create_in_place(
|
||||
return vmo;
|
||||
}
|
||||
|
||||
struct vm_object *vm_object_duplicate_cow(struct vm_object *vmo)
|
||||
{
|
||||
struct object *obj = object_create(&vm_object_type);
|
||||
if (!obj) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct vm_object *out = VM_OBJECT_CAST(obj);
|
||||
|
||||
memcpy(out->vo_name, vmo->vo_name, sizeof out->vo_name);
|
||||
out->vo_flags = vmo->vo_flags;
|
||||
out->vo_ctrl = vmo->vo_ctrl;
|
||||
out->vo_prot = vmo->vo_prot;
|
||||
out->vo_size = vmo->vo_size;
|
||||
memcpy(out->vo_name, vmo->vo_name, sizeof vmo->vo_name);
|
||||
|
||||
struct btree_node *cur = btree_first(&vmo->vo_pages);
|
||||
while (cur) {
|
||||
struct vm_page *pg
|
||||
= BTREE_CONTAINER(struct vm_page, p_bnode, cur);
|
||||
int x = atomic_fetch_add(&pg->p_cow_ref, 1);
|
||||
if (x == 0) {
|
||||
/* this is the first cow-reference for this page, so
|
||||
* the address-space it belongs to will need one too */
|
||||
atomic_fetch_add(&pg->p_cow_ref, 1);
|
||||
}
|
||||
|
||||
tracek("convert page %zx to cow %u",
|
||||
vm_page_get_paddr(pg),
|
||||
pg->p_cow_ref);
|
||||
|
||||
cur = btree_next(cur);
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
static struct vm_page *alloc_page(struct vm_object *vo, off_t offset)
|
||||
{
|
||||
struct vm_page *page = NULL;
|
||||
|
||||
Reference in New Issue
Block a user