On Fri, Oct 07, 2022 at 08:16:11PM +0100, Al Viro wrote: > array of pointers (from first kvmalloc() in alloc_fdtable()): contains file pointers > array of unsigned long (from the second kmvalloc() there): hosts the bitmaps > fdtable (allocated in alloc_fdtable()): > open_fds points to the beginning of bitmap-hosting array > close_on_exec points to the middle third of the same array > full_fd_bits points to the last third of the same array Rereading that... a bit of clarification: the wording would seem to imply that these 3 bitmaps are of equal size; they are not - the third one is smaller. If fdt->max_fds (table capacity) is equal to N, we have * N struct file pointers in fdt->fd[] * N bits in fdt->open_fds[] (i.e. N/BITS_PER_LONG unsigned long) * N bits in fdt->close_on_exec[] (ditto) * N/BITS_PER_LONG bits in fdt->full_fd_bits[] The meaning of bitmaps: bit k set in open_fds[] - descriptor k is in use bit k set in close_on_exec[] - descriptor k is to be closed on exec() bit k set in full_fd_bits[] - all descriptors covered by open_fds[k] (i.e. BITS_PER_LONG of them,, starting from k * BITS_PER_LONG) are in use. In other words, "don't even bother looking for clear bits in open_fds[k]; there won't be any". ->full_fd_bits[] is there purely as a way to speed finding unused descriptors, along with ->next_fd. Some processes have an obscene amount of opened descriptors and linear search through the mostly full bitmap can get painful. E.g. 4 millions of descriptors would mean half megabyte worth of bitmap (in ->open_fds[]). Cheaper to search through 8Kb of ->full_fd_bits, then check one 64bit word in ->open_fds[]; kinder on the cache as well...