Compare commits
2 Commits
bc575aa1a1
...
278fe39c0d
| Author | SHA1 | Date | |
|---|---|---|---|
| 278fe39c0d | |||
| 8b7382fa13 |
@@ -22,6 +22,8 @@ struct vm_area {
|
|||||||
struct address_space *vma_space;
|
struct address_space *vma_space;
|
||||||
/* used to link to vm_object->vo_mappings */
|
/* used to link to vm_object->vo_mappings */
|
||||||
struct queue_entry vma_object_entry;
|
struct queue_entry vma_object_entry;
|
||||||
|
/* the memory control flags applied to this area */
|
||||||
|
vm_flags_t vma_flags;
|
||||||
/* the memory protection flags applied to this area */
|
/* the memory protection flags applied to this area */
|
||||||
vm_prot_t vma_prot;
|
vm_prot_t vma_prot;
|
||||||
/* offset in bytes to the start of the object data that was mapped */
|
/* offset in bytes to the start of the object data that was mapped */
|
||||||
@@ -83,6 +85,7 @@ extern kern_status_t address_space_map(
|
|||||||
struct vm_object *object,
|
struct vm_object *object,
|
||||||
off_t object_offset,
|
off_t object_offset,
|
||||||
size_t length,
|
size_t length,
|
||||||
|
vm_flags_t flags,
|
||||||
vm_prot_t prot,
|
vm_prot_t prot,
|
||||||
virt_addr_t *out);
|
virt_addr_t *out);
|
||||||
extern kern_status_t address_space_unmap(
|
extern kern_status_t address_space_unmap(
|
||||||
|
|||||||
@@ -128,6 +128,7 @@ extern kern_status_t sys_address_space_map(
|
|||||||
kern_handle_t object,
|
kern_handle_t object,
|
||||||
off_t object_offset,
|
off_t object_offset,
|
||||||
size_t length,
|
size_t length,
|
||||||
|
vm_flags_t flags,
|
||||||
vm_prot_t prot,
|
vm_prot_t prot,
|
||||||
virt_addr_t *out_base_address);
|
virt_addr_t *out_base_address);
|
||||||
extern kern_status_t sys_address_space_unmap(
|
extern kern_status_t sys_address_space_unmap(
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ struct vm_object {
|
|||||||
struct queue vo_mappings;
|
struct queue vo_mappings;
|
||||||
|
|
||||||
struct vm_controller *vo_ctrl;
|
struct vm_controller *vo_ctrl;
|
||||||
equeue_key_t vo_key, vo_src_key;
|
equeue_key_t vo_key;
|
||||||
struct btree_node vo_ctrl_node;
|
struct btree_node vo_ctrl_node;
|
||||||
|
|
||||||
/* memory protection flags. mappings of this vm_object can only
|
/* memory protection flags. mappings of this vm_object can only
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ static kern_status_t map_executable_exec(
|
|||||||
bsp->bsp_vmo,
|
bsp->bsp_vmo,
|
||||||
text_foffset,
|
text_foffset,
|
||||||
bsp->bsp_trailer.bsp_text_size,
|
bsp->bsp_trailer.bsp_text_size,
|
||||||
|
VM_SHARED,
|
||||||
VM_PROT_READ | VM_PROT_EXEC | VM_PROT_USER,
|
VM_PROT_READ | VM_PROT_EXEC | VM_PROT_USER,
|
||||||
&text_base);
|
&text_base);
|
||||||
if (status != KERN_OK) {
|
if (status != KERN_OK) {
|
||||||
@@ -132,6 +133,7 @@ static kern_status_t map_executable_exec(
|
|||||||
data,
|
data,
|
||||||
data_foffset,
|
data_foffset,
|
||||||
bsp->bsp_trailer.bsp_data_size,
|
bsp->bsp_trailer.bsp_data_size,
|
||||||
|
VM_PRIVATE,
|
||||||
VM_PROT_READ | VM_PROT_WRITE | VM_PROT_USER,
|
VM_PROT_READ | VM_PROT_WRITE | VM_PROT_USER,
|
||||||
&data_base);
|
&data_base);
|
||||||
if (status != KERN_OK) {
|
if (status != KERN_OK) {
|
||||||
@@ -165,6 +167,7 @@ kern_status_t bsp_launch_async(struct bsp *bsp, struct task *task)
|
|||||||
user_stack,
|
user_stack,
|
||||||
0,
|
0,
|
||||||
BOOTSTRAP_STACK_SIZE,
|
BOOTSTRAP_STACK_SIZE,
|
||||||
|
VM_PRIVATE,
|
||||||
VM_PROT_READ | VM_PROT_WRITE | VM_PROT_USER,
|
VM_PROT_READ | VM_PROT_WRITE | VM_PROT_USER,
|
||||||
&stack_buffer);
|
&stack_buffer);
|
||||||
|
|
||||||
@@ -178,6 +181,7 @@ kern_status_t bsp_launch_async(struct bsp *bsp, struct task *task)
|
|||||||
bsp->bsp_vmo,
|
bsp->bsp_vmo,
|
||||||
0,
|
0,
|
||||||
bsp->bsp_trailer.bsp_exec_offset,
|
bsp->bsp_trailer.bsp_exec_offset,
|
||||||
|
VM_PRIVATE,
|
||||||
VM_PROT_READ | VM_PROT_USER,
|
VM_PROT_READ | VM_PROT_USER,
|
||||||
&bsp_data_base);
|
&bsp_data_base);
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ SYSCALL_GATE vm_object_copy SYS_VM_OBJECT_COPY 6
|
|||||||
|
|
||||||
SYSCALL_GATE address_space_read SYS_ADDRESS_SPACE_READ 5
|
SYSCALL_GATE address_space_read SYS_ADDRESS_SPACE_READ 5
|
||||||
SYSCALL_GATE address_space_write SYS_ADDRESS_SPACE_WRITE 5
|
SYSCALL_GATE address_space_write SYS_ADDRESS_SPACE_WRITE 5
|
||||||
SYSCALL_GATE address_space_map SYS_ADDRESS_SPACE_MAP 7
|
SYSCALL_GATE address_space_map SYS_ADDRESS_SPACE_MAP 8
|
||||||
SYSCALL_GATE address_space_unmap SYS_ADDRESS_SPACE_UNMAP 3
|
SYSCALL_GATE address_space_unmap SYS_ADDRESS_SPACE_UNMAP 3
|
||||||
SYSCALL_GATE address_space_reserve SYS_ADDRESS_SPACE_RESERVE 4
|
SYSCALL_GATE address_space_reserve SYS_ADDRESS_SPACE_RESERVE 4
|
||||||
SYSCALL_GATE address_space_release SYS_ADDRESS_SPACE_RELEASE 3
|
SYSCALL_GATE address_space_release SYS_ADDRESS_SPACE_RELEASE 3
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ extern kern_status_t address_space_map(
|
|||||||
kern_handle_t object,
|
kern_handle_t object,
|
||||||
off_t object_offset,
|
off_t object_offset,
|
||||||
size_t length,
|
size_t length,
|
||||||
|
vm_flags_t flags,
|
||||||
vm_prot_t prot,
|
vm_prot_t prot,
|
||||||
virt_addr_t *out_base_address);
|
virt_addr_t *out_base_address);
|
||||||
extern kern_status_t address_space_unmap(
|
extern kern_status_t address_space_unmap(
|
||||||
|
|||||||
@@ -34,6 +34,16 @@
|
|||||||
#define KERN_HANDLE_FLAG2 0x40000000UL
|
#define KERN_HANDLE_FLAG2 0x40000000UL
|
||||||
#define KERN_HANDLE_FLAG3 0x80000000UL
|
#define KERN_HANDLE_FLAG3 0x80000000UL
|
||||||
|
|
||||||
|
/* flags to specify when creating address-space mappings */
|
||||||
|
/* this mapping is private. if a task with this mapping is duplicated,
|
||||||
|
the duplicate task will receive a copy-on-write mapping. changes to one
|
||||||
|
mapping will not be visible to the other. */
|
||||||
|
#define VM_PRIVATE 0x0000u
|
||||||
|
/* this mapping is shared. if a task with this mapping is duplicated,
|
||||||
|
* the duplicate will receive a mapping of the same data. changes to one mapping
|
||||||
|
* will be visibile to the other */
|
||||||
|
#define VM_SHARED 0x0001u
|
||||||
|
|
||||||
/* maximum number of handles that can be sent in a single message */
|
/* maximum number of handles that can be sent in a single message */
|
||||||
#define KERN_MSG_MAX_HANDLES 64
|
#define KERN_MSG_MAX_HANDLES 64
|
||||||
|
|
||||||
@@ -107,6 +117,7 @@ typedef unsigned int kern_status_t;
|
|||||||
typedef uint32_t kern_handle_t;
|
typedef uint32_t kern_handle_t;
|
||||||
typedef uint32_t kern_config_key_t;
|
typedef uint32_t kern_config_key_t;
|
||||||
typedef uint32_t vm_prot_t;
|
typedef uint32_t vm_prot_t;
|
||||||
|
typedef uint32_t vm_flags_t;
|
||||||
typedef int64_t ssize_t;
|
typedef int64_t ssize_t;
|
||||||
typedef uint32_t kern_futex_t;
|
typedef uint32_t kern_futex_t;
|
||||||
typedef uint32_t kern_msg_type_t;
|
typedef uint32_t kern_msg_type_t;
|
||||||
|
|||||||
+11
-9
@@ -125,6 +125,7 @@ kern_status_t sys_address_space_map(
|
|||||||
kern_handle_t object_handle,
|
kern_handle_t object_handle,
|
||||||
off_t object_offset,
|
off_t object_offset,
|
||||||
size_t length,
|
size_t length,
|
||||||
|
vm_flags_t flags,
|
||||||
vm_prot_t prot,
|
vm_prot_t prot,
|
||||||
virt_addr_t *out_base_address)
|
virt_addr_t *out_base_address)
|
||||||
{
|
{
|
||||||
@@ -140,8 +141,8 @@ kern_status_t sys_address_space_map(
|
|||||||
}
|
}
|
||||||
|
|
||||||
kern_status_t status = KERN_OK;
|
kern_status_t status = KERN_OK;
|
||||||
unsigned long flags;
|
unsigned long irq_flags;
|
||||||
task_lock_irqsave(self, &flags);
|
task_lock_irqsave(self, &irq_flags);
|
||||||
|
|
||||||
struct object *region_obj = NULL, *vmo_obj = NULL;
|
struct object *region_obj = NULL, *vmo_obj = NULL;
|
||||||
handle_flags_t region_flags = 0, vmo_flags = 0;
|
handle_flags_t region_flags = 0, vmo_flags = 0;
|
||||||
@@ -151,34 +152,34 @@ kern_status_t sys_address_space_map(
|
|||||||
®ion_obj,
|
®ion_obj,
|
||||||
®ion_flags);
|
®ion_flags);
|
||||||
if (status != KERN_OK) {
|
if (status != KERN_OK) {
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, irq_flags);
|
||||||
put_current_task(self);
|
put_current_task(self);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
status = task_resolve_handle(self, object_handle, &vmo_obj, &vmo_flags);
|
status = task_resolve_handle(self, object_handle, &vmo_obj, &vmo_flags);
|
||||||
if (status != KERN_OK) {
|
if (status != KERN_OK) {
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, irq_flags);
|
||||||
put_current_task(self);
|
put_current_task(self);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct address_space *region = address_space_cast(region_obj);
|
struct address_space *region = address_space_cast(region_obj);
|
||||||
if (!region) {
|
if (!region) {
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, irq_flags);
|
||||||
put_current_task(self);
|
put_current_task(self);
|
||||||
return KERN_INVALID_ARGUMENT;
|
return KERN_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct vm_object *vmo = vm_object_cast(vmo_obj);
|
struct vm_object *vmo = vm_object_cast(vmo_obj);
|
||||||
if (!vmo) {
|
if (!vmo) {
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, irq_flags);
|
||||||
put_current_task(self);
|
put_current_task(self);
|
||||||
return KERN_INVALID_ARGUMENT;
|
return KERN_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, irq_flags);
|
||||||
address_space_lock_irqsave(region, &flags);
|
address_space_lock_irqsave(region, &irq_flags);
|
||||||
/* address_space_map will take care of locking `vmo` */
|
/* address_space_map will take care of locking `vmo` */
|
||||||
status = address_space_map(
|
status = address_space_map(
|
||||||
region,
|
region,
|
||||||
@@ -186,9 +187,10 @@ kern_status_t sys_address_space_map(
|
|||||||
vmo,
|
vmo,
|
||||||
object_offset,
|
object_offset,
|
||||||
length,
|
length,
|
||||||
|
flags,
|
||||||
prot,
|
prot,
|
||||||
out_base_address);
|
out_base_address);
|
||||||
address_space_unlock_irqrestore(region, flags);
|
address_space_unlock_irqrestore(region, irq_flags);
|
||||||
|
|
||||||
object_unref(vmo_obj);
|
object_unref(vmo_obj);
|
||||||
object_unref(region_obj);
|
object_unref(region_obj);
|
||||||
|
|||||||
@@ -148,8 +148,8 @@ kern_status_t sys_vm_controller_create_object(
|
|||||||
}
|
}
|
||||||
|
|
||||||
kern_status_t status = KERN_OK;
|
kern_status_t status = KERN_OK;
|
||||||
unsigned long flags;
|
unsigned long irq_flags;
|
||||||
task_lock_irqsave(self, &flags);
|
task_lock_irqsave(self, &irq_flags);
|
||||||
|
|
||||||
struct object *ctrl_obj = NULL;
|
struct object *ctrl_obj = NULL;
|
||||||
handle_flags_t handle_flags = 0;
|
handle_flags_t handle_flags = 0;
|
||||||
@@ -159,7 +159,7 @@ kern_status_t sys_vm_controller_create_object(
|
|||||||
&ctrl_obj,
|
&ctrl_obj,
|
||||||
&handle_flags);
|
&handle_flags);
|
||||||
if (status != KERN_OK) {
|
if (status != KERN_OK) {
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, irq_flags);
|
||||||
put_current_task(self);
|
put_current_task(self);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
@@ -173,14 +173,14 @@ kern_status_t sys_vm_controller_create_object(
|
|||||||
&out_handle);
|
&out_handle);
|
||||||
|
|
||||||
struct vm_controller *ctrl = vm_controller_cast(ctrl_obj);
|
struct vm_controller *ctrl = vm_controller_cast(ctrl_obj);
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, irq_flags);
|
||||||
if (!ctrl) {
|
if (!ctrl) {
|
||||||
object_unref(ctrl_obj);
|
object_unref(ctrl_obj);
|
||||||
put_current_task(self);
|
put_current_task(self);
|
||||||
return KERN_INVALID_ARGUMENT;
|
return KERN_INVALID_ARGUMENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
vm_controller_lock_irqsave(ctrl, &flags);
|
vm_controller_lock_irqsave(ctrl, &irq_flags);
|
||||||
struct vm_object *out_vmo = NULL;
|
struct vm_object *out_vmo = NULL;
|
||||||
status = vm_controller_create_object(
|
status = vm_controller_create_object(
|
||||||
ctrl,
|
ctrl,
|
||||||
@@ -190,14 +190,14 @@ kern_status_t sys_vm_controller_create_object(
|
|||||||
data_len,
|
data_len,
|
||||||
prot,
|
prot,
|
||||||
&out_vmo);
|
&out_vmo);
|
||||||
vm_controller_unlock_irqrestore(ctrl, flags);
|
vm_controller_unlock_irqrestore(ctrl, irq_flags);
|
||||||
|
|
||||||
object_unref(ctrl_obj);
|
object_unref(ctrl_obj);
|
||||||
|
|
||||||
if (status != KERN_OK) {
|
if (status != KERN_OK) {
|
||||||
task_lock_irqsave(self, &flags);
|
task_lock_irqsave(self, &irq_flags);
|
||||||
handle_table_free_handle(self->t_handles, out_handle);
|
handle_table_free_handle(self->t_handles, out_handle);
|
||||||
task_unlock_irqrestore(self, flags);
|
task_unlock_irqrestore(self, irq_flags);
|
||||||
put_current_task(self);
|
put_current_task(self);
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|||||||
+33
-2
@@ -706,6 +706,7 @@ kern_status_t address_space_map(
|
|||||||
struct vm_object *object,
|
struct vm_object *object,
|
||||||
off_t object_offset,
|
off_t object_offset,
|
||||||
size_t length,
|
size_t length,
|
||||||
|
vm_flags_t flags,
|
||||||
vm_prot_t prot,
|
vm_prot_t prot,
|
||||||
virt_addr_t *out)
|
virt_addr_t *out)
|
||||||
{
|
{
|
||||||
@@ -763,6 +764,7 @@ kern_status_t address_space_map(
|
|||||||
area->vma_space = root;
|
area->vma_space = root;
|
||||||
area->vma_object = object;
|
area->vma_object = object;
|
||||||
area->vma_prot = prot;
|
area->vma_prot = prot;
|
||||||
|
area->vma_flags = flags;
|
||||||
area->vma_object_offset = object_offset;
|
area->vma_object_offset = object_offset;
|
||||||
area->vma_base = map_address;
|
area->vma_base = map_address;
|
||||||
area->vma_limit = map_address + length - 1;
|
area->vma_limit = map_address + length - 1;
|
||||||
@@ -1215,6 +1217,7 @@ static struct vm_area *area_duplicate(struct vm_area *area)
|
|||||||
}
|
}
|
||||||
|
|
||||||
out->vma_prot = area->vma_prot;
|
out->vma_prot = area->vma_prot;
|
||||||
|
out->vma_flags = area->vma_flags;
|
||||||
out->vma_object_offset = area->vma_object_offset;
|
out->vma_object_offset = area->vma_object_offset;
|
||||||
out->vma_base = area->vma_base;
|
out->vma_base = area->vma_base;
|
||||||
out->vma_limit = area->vma_limit;
|
out->vma_limit = area->vma_limit;
|
||||||
@@ -1281,7 +1284,8 @@ static kern_status_t prepare_duplicate_areas(
|
|||||||
struct vm_object *src_vmo = tmp_area->vma_object;
|
struct vm_object *src_vmo = tmp_area->vma_object;
|
||||||
vm_object_lock(src_vmo);
|
vm_object_lock(src_vmo);
|
||||||
|
|
||||||
struct vm_object *dest_vmo = NULL;
|
struct vm_object *dest_vmo_link = NULL;
|
||||||
|
struct vm_object *dest_vmo_cow = NULL;
|
||||||
struct queue_entry *cur_entry
|
struct queue_entry *cur_entry
|
||||||
= queue_first(&src_vmo->vo_mappings);
|
= queue_first(&src_vmo->vo_mappings);
|
||||||
|
|
||||||
@@ -1312,6 +1316,13 @@ static kern_status_t prepare_duplicate_areas(
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct vm_object *dest_vmo = NULL;
|
||||||
|
if (src_area->vma_flags & VM_SHARED) {
|
||||||
|
dest_vmo = dest_vmo_link;
|
||||||
|
} else {
|
||||||
|
dest_vmo = dest_vmo_cow;
|
||||||
|
}
|
||||||
|
|
||||||
if (!dest_vmo) {
|
if (!dest_vmo) {
|
||||||
tracek("[%zx-%zx %x] creating COW duplicate of "
|
tracek("[%zx-%zx %x] creating COW duplicate of "
|
||||||
"vmo %p",
|
"vmo %p",
|
||||||
@@ -1319,7 +1330,18 @@ static kern_status_t prepare_duplicate_areas(
|
|||||||
src_area->vma_limit,
|
src_area->vma_limit,
|
||||||
src_area->vma_prot,
|
src_area->vma_prot,
|
||||||
src_vmo);
|
src_vmo);
|
||||||
dest_vmo = vm_object_duplicate_cow(src_vmo);
|
|
||||||
|
if (src_area->vma_flags & VM_SHARED) {
|
||||||
|
dest_vmo_link = src_vmo;
|
||||||
|
object_ref(&dest_vmo_link->vo_base);
|
||||||
|
|
||||||
|
dest_vmo = dest_vmo_link;
|
||||||
|
} else {
|
||||||
|
dest_vmo_cow = vm_object_duplicate_cow(
|
||||||
|
src_vmo);
|
||||||
|
dest_vmo = dest_vmo_cow;
|
||||||
|
}
|
||||||
|
|
||||||
tracek("[%zx-%zx %x] created COW duplicate of "
|
tracek("[%zx-%zx %x] created COW duplicate of "
|
||||||
"vmo %p -> %p",
|
"vmo %p -> %p",
|
||||||
src_area->vma_base,
|
src_area->vma_base,
|
||||||
@@ -1329,11 +1351,20 @@ static kern_status_t prepare_duplicate_areas(
|
|||||||
dest_vmo);
|
dest_vmo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
object_ref(&dest_vmo->vo_base);
|
||||||
dest_area->vma_object = dest_vmo;
|
dest_area->vma_object = dest_vmo;
|
||||||
update_area_pte_cow(src, dest, src_area);
|
update_area_pte_cow(src, dest, src_area);
|
||||||
cur_entry = queue_next(cur_entry);
|
cur_entry = queue_next(cur_entry);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (dest_vmo_link) {
|
||||||
|
object_unref(&dest_vmo_link->vo_base);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dest_vmo_cow) {
|
||||||
|
object_unref(&dest_vmo_cow->vo_base);
|
||||||
|
}
|
||||||
|
|
||||||
vm_object_unlock(src_vmo);
|
vm_object_unlock(src_vmo);
|
||||||
|
|
||||||
cur_node = btree_next(cur_node);
|
cur_node = btree_next(cur_node);
|
||||||
|
|||||||
+1
-2
@@ -162,7 +162,7 @@ kern_status_t vm_controller_recv(
|
|||||||
out->req_length = req->req_length;
|
out->req_length = req->req_length;
|
||||||
break;
|
break;
|
||||||
case VM_REQUEST_ATTACH:
|
case VM_REQUEST_ATTACH:
|
||||||
out->req_src_vmo = req->req_object->vo_src_key;
|
out->req_src_vmo = req->req_object->vo_key;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
@@ -255,7 +255,6 @@ kern_status_t vm_controller_finish_attach(
|
|||||||
|
|
||||||
vm_object_lock(vmo);
|
vm_object_lock(vmo);
|
||||||
vmo->vo_key = new_key;
|
vmo->vo_key = new_key;
|
||||||
vmo->vo_src_key = 0;
|
|
||||||
vmo->vo_flags &= ~VMO_LAZY_ATTACH;
|
vmo->vo_flags &= ~VMO_LAZY_ATTACH;
|
||||||
vm_object_unlock(vmo);
|
vm_object_unlock(vmo);
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -290,8 +290,7 @@ struct vm_object *vm_object_duplicate_cow(struct vm_object *vmo)
|
|||||||
memcpy(out->vo_name, vmo->vo_name, sizeof out->vo_name);
|
memcpy(out->vo_name, vmo->vo_name, sizeof out->vo_name);
|
||||||
out->vo_flags = vmo->vo_flags | VMO_LAZY_ATTACH;
|
out->vo_flags = vmo->vo_flags | VMO_LAZY_ATTACH;
|
||||||
out->vo_ctrl = vmo->vo_ctrl;
|
out->vo_ctrl = vmo->vo_ctrl;
|
||||||
out->vo_key = 0;
|
out->vo_key = vmo->vo_key;
|
||||||
out->vo_src_key = vmo->vo_key;
|
|
||||||
out->vo_prot = vmo->vo_prot;
|
out->vo_prot = vmo->vo_prot;
|
||||||
out->vo_size = vmo->vo_size;
|
out->vo_size = vmo->vo_size;
|
||||||
memcpy(out->vo_name, vmo->vo_name, sizeof vmo->vo_name);
|
memcpy(out->vo_name, vmo->vo_name, sizeof vmo->vo_name);
|
||||||
|
|||||||
Reference in New Issue
Block a user