vm: object: implement creating copy-on-write duplicates of vm-objects

This commit is contained in:
2026-04-01 18:33:24 +01:00
parent 4143e12a29
commit 2cbfa7d7d2
2 changed files with 40 additions and 0 deletions
+3
View File
@@ -84,6 +84,9 @@ extern struct vm_object *vm_object_create_in_place(
size_t data_len, size_t data_len,
vm_prot_t prot); 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( extern struct vm_page *vm_object_get_page(
struct vm_object *vo, struct vm_object *vo,
off_t offset, off_t offset,
+37
View File
@@ -278,6 +278,43 @@ extern struct vm_object *vm_object_create_in_place(
return vmo; 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) static struct vm_page *alloc_page(struct vm_object *vo, off_t offset)
{ {
struct vm_page *page = NULL; struct vm_page *page = NULL;