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:
@@ -7,6 +7,7 @@
|
||||
|
||||
/* depth=3 gives a maximum of ~66.6 million handles */
|
||||
#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(
|
||||
|
||||
Reference in New Issue
Block a user