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.
This commit is contained in:
2026-02-19 19:11:11 +00:00
parent c6e1ba21dd
commit f2e128c57e

View File

@@ -7,6 +7,7 @@
/* depth=3 gives a maximum of ~66.6 million handles */ /* 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 = { static struct vm_cache handle_table_cache = {
.c_name = "handle_table", .c_name = "handle_table",
@@ -38,7 +39,6 @@ static kern_status_t decode_handle_indices(
kern_handle_t handle, kern_handle_t handle,
unsigned int indices[MAX_TABLE_DEPTH]) unsigned int indices[MAX_TABLE_DEPTH])
{ {
handle >>= 2;
for (int i = 0; i < MAX_TABLE_DEPTH; i++) { for (int i = 0; i < MAX_TABLE_DEPTH; i++) {
unsigned int div = (i > 0 ? REFS_PER_TABLE : HANDLES_PER_TABLE); 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; mul *= REFS_PER_TABLE;
} }
handle <<= 2;
*out_handle = handle; *out_handle = handle;
return KERN_OK; return KERN_OK;
} }
@@ -76,6 +74,7 @@ kern_status_t handle_table_alloc_handle(
{ {
int i; int i;
unsigned int indices[MAX_TABLE_DEPTH] = {0}; 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++) { for (i = 0; i < MAX_TABLE_DEPTH - 1; i++) {
unsigned int next_index = bitmap_lowest_clear( unsigned int next_index = bitmap_lowest_clear(
@@ -101,6 +100,10 @@ kern_status_t handle_table_alloc_handle(
tab = next; 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( unsigned int handle_index = bitmap_lowest_clear(
tab->t_handles.t_handle_map, tab->t_handles.t_handle_map,
HANDLES_PER_TABLE); HANDLES_PER_TABLE);
@@ -119,11 +122,13 @@ kern_status_t handle_table_alloc_handle(
return encode_handle_indices(indices, out_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]; unsigned int indices[MAX_TABLE_DEPTH];
if (decode_handle_indices(handle, indices) != KERN_OK) { if (decode_handle_indices(handle, indices) != KERN_OK) {
return; return KERN_NO_ENTRY;
} }
int i; int i;
@@ -131,7 +136,7 @@ void handle_table_free_handle(struct handle_table *tab, kern_handle_t handle)
struct handle_table *next struct handle_table *next
= tab->t_subtables.t_subtable_list[indices[i]]; = tab->t_subtables.t_subtable_list[indices[i]];
if (!next) { if (!next) {
return; return KERN_NO_ENTRY;
} }
bitmap_clear(tab->t_subtables.t_subtable_map, indices[i]); 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]; 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); bitmap_clear(tab->t_handles.t_handle_map, handle_index);
struct handle *handle_entry struct handle *handle_entry
= &tab->t_handles.t_handle_list[handle_index]; = &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); memset(handle_entry, 0x0, sizeof *handle_entry);
return KERN_OK;
} }
struct handle *handle_table_get_handle( struct handle *handle_table_get_handle(