kernel/fs: Allocate FD tables separately instead of in one malloc().

This way, we significantly increase the FD table sizes that can
be allocated without needing a "raw" allocation: previously
an FD table size of 512 would've been too large (on x86_64),
while now, tables of up to size 1024 will fit (so long as the
largest block allocator size is 8192, anyway.)
This commit is contained in:
Augustin Cavalier 2025-01-03 12:40:13 -05:00
parent 5911165316
commit 12d6ecf0df

View File

@ -5046,17 +5046,22 @@ vfs_resize_fd_table(struct io_context* context, uint32 newSize)
select_info** oldSelectInfos = context->select_infos; select_info** oldSelectInfos = context->select_infos;
uint8* oldCloseOnExecTable = context->fds_close_on_exec; uint8* oldCloseOnExecTable = context->fds_close_on_exec;
// allocate new tables // allocate new tables (separately to reduce the chances of needing a raw allocation)
file_descriptor** newFDs = (file_descriptor**)malloc( file_descriptor** newFDs = (file_descriptor**)malloc(
sizeof(struct file_descriptor*) * newSize sizeof(struct file_descriptor*) * newSize);
+ sizeof(struct select_infos**) * newSize select_info** newSelectInfos = (select_info**)malloc(
+ newCloseOnExitBitmapSize); + sizeof(select_info**) * newSize);
if (newFDs == NULL) uint8* newCloseOnExecTable = (uint8*)malloc(newCloseOnExitBitmapSize);
if (newFDs == NULL || newSelectInfos == NULL || newCloseOnExecTable == NULL) {
free(newFDs);
free(newSelectInfos);
free(newCloseOnExecTable);
return B_NO_MEMORY; return B_NO_MEMORY;
}
context->fds = newFDs; context->fds = newFDs;
context->select_infos = (select_info**)(context->fds + newSize); context->select_infos = newSelectInfos;
context->fds_close_on_exec = (uint8*)(context->select_infos + newSize); context->fds_close_on_exec = newCloseOnExecTable;
context->table_size = newSize; context->table_size = newSize;
if (oldSize != 0) { if (oldSize != 0) {
@ -5079,6 +5084,8 @@ vfs_resize_fd_table(struct io_context* context, uint32 newSize)
} }
free(oldFDs); free(oldFDs);
free(oldSelectInfos);
free(oldCloseOnExecTable);
return B_OK; return B_OK;
} }