kernel: handle: init handle table duplication
This commit is contained in:
@@ -77,6 +77,81 @@ void handle_table_destroy(struct handle_table *tab)
|
||||
do_handle_table_destroy(tab, 0);
|
||||
}
|
||||
|
||||
static kern_status_t do_handle_table_duplicate_leaf(
|
||||
struct handle_table *src,
|
||||
struct handle_table **dest)
|
||||
{
|
||||
struct handle_table *out
|
||||
= vm_cache_alloc(&handle_table_cache, VM_NORMAL);
|
||||
if (!out) {
|
||||
return KERN_NO_MEMORY;
|
||||
}
|
||||
|
||||
memcpy(out, src, sizeof *out);
|
||||
|
||||
for (size_t i = 0; i < HANDLES_PER_TABLE; i++) {
|
||||
struct object *obj = src->t_handles.t_handle_list[i].h_object;
|
||||
if (obj) {
|
||||
object_ref(obj);
|
||||
}
|
||||
}
|
||||
|
||||
*dest = out;
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
static kern_status_t do_handle_table_duplicate(
|
||||
struct handle_table *src,
|
||||
struct handle_table **dest,
|
||||
unsigned int depth)
|
||||
{
|
||||
if (depth == MAX_TABLE_DEPTH - 1) {
|
||||
return do_handle_table_duplicate_leaf(src, dest);
|
||||
}
|
||||
|
||||
struct handle_table *out
|
||||
= vm_cache_alloc(&handle_table_cache, VM_NORMAL);
|
||||
if (!out) {
|
||||
return KERN_NO_MEMORY;
|
||||
}
|
||||
|
||||
memcpy(out->t_subtables.t_subtable_map,
|
||||
src->t_subtables.t_subtable_map,
|
||||
sizeof out->t_subtables.t_subtable_map);
|
||||
memset(out->t_subtables.t_subtable_list,
|
||||
0x0,
|
||||
sizeof out->t_subtables.t_subtable_list);
|
||||
|
||||
for (size_t i = 0; i < REFS_PER_TABLE; i++) {
|
||||
struct handle_table *child
|
||||
= src->t_subtables.t_subtable_list[i];
|
||||
struct handle_table *dup = NULL;
|
||||
kern_status_t status = KERN_OK;
|
||||
if (child) {
|
||||
status = do_handle_table_duplicate(
|
||||
child,
|
||||
&dup,
|
||||
depth + 1);
|
||||
}
|
||||
|
||||
if (status == KERN_OK) {
|
||||
out->t_subtables.t_subtable_list[i] = dup;
|
||||
} else {
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
*dest = out;
|
||||
return KERN_OK;
|
||||
}
|
||||
|
||||
kern_status_t handle_table_duplicate(
|
||||
struct handle_table *src,
|
||||
struct handle_table **dest)
|
||||
{
|
||||
return do_handle_table_duplicate(src, dest, 0);
|
||||
}
|
||||
|
||||
static kern_status_t decode_handle_indices(
|
||||
kern_handle_t handle,
|
||||
unsigned int indices[MAX_TABLE_DEPTH])
|
||||
|
||||
Reference in New Issue
Block a user