vm: object: implement transferring pages between objects

This commit is contained in:
2026-03-14 22:36:21 +00:00
parent 5d04dbb15a
commit f04c524bb5
2 changed files with 54 additions and 0 deletions

View File

@@ -85,6 +85,13 @@ extern kern_status_t vm_object_copy(
off_t src_offset,
size_t count,
size_t *nr_copied);
extern kern_status_t vm_object_transfer(
struct vm_object *dst,
off_t dst_offset,
struct vm_object *src,
off_t src_offset,
size_t count,
size_t *nr_moved);
DEFINE_OBJECT_LOCK_FUNCTION(vm_object, vo_base)

View File

@@ -780,3 +780,50 @@ kern_status_t vm_object_copy(
return KERN_OK;
}
kern_status_t vm_object_transfer(
struct vm_object *dst,
off_t dst_offset,
struct vm_object *src,
off_t src_offset,
size_t count,
size_t *nr_moved)
{
dst_offset &= ~VM_PAGE_MASK;
src_offset &= ~VM_PAGE_MASK;
if (count & VM_PAGE_MASK) {
count &= ~VM_PAGE_MASK;
count += VM_PAGE_SIZE;
}
size_t moved = 0;
for (size_t i = 0; i < count; i += VM_PAGE_SIZE) {
struct vm_page *src_pg
= vm_object_get_page(src, src_offset + i);
if (!src_pg) {
continue;
}
btree_delete(&src->vo_pages, &src_pg->p_bnode);
struct vm_page *dst_pg
= vm_object_get_page(src, dst_offset + i);
if (dst_pg) {
vm_page_free(src_pg);
continue;
}
put_page(dst, src_pg, dst_offset + i);
moved += VM_PAGE_SIZE;
}
/* TODO evict all page table entries that reference the transferred
* pages in `src` */
if (nr_moved) {
*nr_moved = moved;
}
return KERN_OK;
}