From f2e128c57e872a0f5d97df57b4014a5d160a33b5 Mon Sep 17 00:00:00 2001 From: Max Wash Date: Thu, 19 Feb 2026 19:11:11 +0000 Subject: [PATCH] handle: re-arrange handle space layout the lowest 2 bits of handle values are no longer unused, and 0 is now a valid handle value. the first 64 handles are now reserved, and will not be automatically allocated by the kernel. however, they are still valid handles, and other handles can be moved to this area using an as-yet-unwritten function. this is to allow support for standard POSIX file descriptors, which require the values 0, 1, and 2. --- kernel/handle.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/kernel/handle.c b/kernel/handle.c index d92f025..464b28c 100644 --- a/kernel/handle.c +++ b/kernel/handle.c @@ -6,7 +6,8 @@ #include /* depth=3 gives a maximum of ~66.6 million handles */ -#define MAX_TABLE_DEPTH 3 +#define MAX_TABLE_DEPTH 3 +#define RESERVED_HANDLES 64 static struct vm_cache handle_table_cache = { .c_name = "handle_table", @@ -38,7 +39,6 @@ static kern_status_t decode_handle_indices( kern_handle_t handle, unsigned int indices[MAX_TABLE_DEPTH]) { - handle >>= 2; for (int i = 0; i < MAX_TABLE_DEPTH; i++) { unsigned int div = (i > 0 ? REFS_PER_TABLE : HANDLES_PER_TABLE); @@ -63,8 +63,6 @@ static kern_status_t encode_handle_indices( mul *= REFS_PER_TABLE; } - handle <<= 2; - *out_handle = handle; return KERN_OK; } @@ -76,6 +74,7 @@ kern_status_t handle_table_alloc_handle( { int i; unsigned int indices[MAX_TABLE_DEPTH] = {0}; + static const unsigned int reserved_indices[MAX_TABLE_DEPTH] = {0}; for (i = 0; i < MAX_TABLE_DEPTH - 1; i++) { unsigned int next_index = bitmap_lowest_clear( @@ -101,6 +100,10 @@ kern_status_t handle_table_alloc_handle( tab = next; } + if (memcmp(indices, reserved_indices, sizeof indices) == 0) { + bitmap_fill(tab->t_handles.t_handle_map, RESERVED_HANDLES); + } + unsigned int handle_index = bitmap_lowest_clear( tab->t_handles.t_handle_map, HANDLES_PER_TABLE); @@ -119,11 +122,13 @@ kern_status_t handle_table_alloc_handle( return encode_handle_indices(indices, out_handle); } -void handle_table_free_handle(struct handle_table *tab, kern_handle_t handle) +kern_status_t handle_table_free_handle( + struct handle_table *tab, + kern_handle_t handle) { unsigned int indices[MAX_TABLE_DEPTH]; if (decode_handle_indices(handle, indices) != KERN_OK) { - return; + return KERN_NO_ENTRY; } int i; @@ -131,7 +136,7 @@ void handle_table_free_handle(struct handle_table *tab, kern_handle_t handle) struct handle_table *next = tab->t_subtables.t_subtable_list[indices[i]]; if (!next) { - return; + return KERN_NO_ENTRY; } bitmap_clear(tab->t_subtables.t_subtable_map, indices[i]); @@ -139,6 +144,10 @@ void handle_table_free_handle(struct handle_table *tab, kern_handle_t handle) } unsigned int handle_index = indices[i]; + if (!bitmap_check(tab->t_handles.t_handle_map, handle_index)) { + return KERN_NO_ENTRY; + } + bitmap_clear(tab->t_handles.t_handle_map, handle_index); struct handle *handle_entry = &tab->t_handles.t_handle_list[handle_index]; @@ -148,6 +157,7 @@ void handle_table_free_handle(struct handle_table *tab, kern_handle_t handle) } memset(handle_entry, 0x0, sizeof *handle_entry); + return KERN_OK; } struct handle *handle_table_get_handle(