Вопрос или проблема
В Linux, а точнее в EXT4, начальный размер файла каталога составляет 4 кБ. Но если в каталоге хранится достаточное количество файлов, размер файла каталога увеличится из-за роста внутреннего “списка файлов”. Однако сколько файлов нужно, чтобы это произошло? Мне не удалось найти ресурс, который мог бы ответить на этот вопрос.
Формат записей каталога ext4 документирован в ядре. Существует две возможности.
- Для линейных каталогов каждая запись занимает восемь байт, плюс имя файла (с нулевым завершением), округленное до четырех байт. Таким образом, n записей файла занимает 8 × n байт плюс длины всех имен файлов, округленные до четырех (включая завершающий ноль). Каталоги всегда включают
.
и..
, которые занимают по двенадцать байт каждый. Каждый линейный каталог также может иметь двенадцатибайтовую контрольную сумму. Последняя запись в блоке имеет увеличенную длину записи, чтобы покрыть оставшееся место в текущем блоке, так что записи каталогов никогда не пересекают два блока файловой системы. - Для каталога с хеш-деревом первый блок данных в каждом каталоге имеет корневую запись длиной 40 байт (включающую записи для
.
и..
), а каждый последующий блок данных имеет узел длиной 18 байт. Узлы в индексных блоках занимают по восемь байт, а записи файлов в листовых блоках используют ту же структуру данных, что и в линейном каталоге, в конечном итоге в виде линейного массива. Таким образом, объем памяти, занимаемой каталогом, труднее вычислить: каждый файл занимает восемь байт плюс длина его имени, округленная до четырех байт, а структура дерева потребляет 40 байт для первого блока плюс 18 байт за каждый дополнительный блок и восемь байт за узел. Когда листовой блок заполняется и новая запись хешируется в этот блок, он разделит записи на два полуфиловых листовых блока (по хеш-значению), так что в среднем каждый листовой блок заполнен между 1/2 и 2/2 = 3/4.
В обоих случаях, если записи с разной длиной имен удаляются и добавляются из каталога, в листовых блоках могут остаться неиспользуемые записи.
Если вы хотите быстро увидеть увеличение размера каталога, заполните его файлами с длинными именами — имена файлов могут быть длиной до 254 байт плюс завершающий нулевой байт, занимая в общей сложности 264 байта, так что 16 таких записей в любом типе каталога потребует более 4096 байт.
Чтобы определить, является ли каталог линейным или хешированным, проверьте его индексный номер, например, с помощью debugfs
:
debugfs: show_inode_info /path/to/directory
Индексный номер: 7329 Тип: каталог Режим: 0755 Флаги: 0x1000
Генерация: 2283115506 Версия: 0x00000001
...
Флаги покажут установленный 0x1000, если каталог хеширован, и не установленный в противном случае.
Ответ или решение
Вопрос о том, сколько файлов в каталоге приведет к увеличению размера файла каталога в файловой системе Linux, в частности EXT4, является довольно сложным и требует учёта нескольких факторов, включая особенности самой файловой системы и формата записи каталогов.
Файловая система EXT4 изначально создает файл каталога размером 4 КБ. Однако по мере добавления файлов размер каталога может увеличиваться, что связано с внутренним "списком файлов". Давайте рассмотрим, как именно рассчитывается количество файлов, которое может быть помещено в каталог, прежде чем его размер увеличится.
Формат записи каталогов в EXT4
В EXT4 существуют два основных формата записи каталогов: линейный (linear) и хеш-дерево (hash tree).
-
Линейные каталоги:
- Каждая запись в линейном каталоге занимает 8 байт, плюс длина имени файла (с нулевым терминатором), округленная до ближайших 4 байт.
- Каталоги всегда содержат записи
.
и..
, каждая из которых занимает 12 байт. В дополнение к этому может добавляться 12-байтовая контрольная сумма. - Таким образом, если в каталоге содержится
n
записей файлов, тогда размер будет рассчитан по формуле:
[
\text{Size} = 8n + \text{Sum of rounded filename lengths} + 12 + 12 + \text{Checksum}
] - При этом в каждом файле каталога может храниться до 1024 файлов (с учетом наличия записи
.
и..
), прежде чем изменится размер блока и размер каталога увеличится.
-
Хеш-деревья:
- У первого блока в каталоге размером 40 байт хранится корневая запись.
- Каждое дополнительное блокировку займет 18 байт, и записи файлов будут иметь такую же структуру, как и в линейном каталоге.
- В среднем, каждый листовой блок будет заполняться на от 1/2 до 3/4, что усложняет вычисления.
Ответ на вопрос
Итак, для линейного каталога, если предположить, что вы используете 254-байтовые имена файлов, то получение 16 таких файлов приведет к превышению 4096 байт (плюс дополнительные 12 байт на записи .
и ..
и возможные контрольные суммы). Таким образом, в этом случае размер каталога увеличится.
Для хеш-деревьев количество записей может варьироваться, но процесс роста также зависит от заполнения блоков.
Заключение
Количество файлов в каталоге, после которого размер файла каталога начнет увеличиваться, зависит от используемого формата записи (линейный или хеш-дерево) и длины имен файлов. Для линейного каталога, заполнение 16 файлов с длинными именами является достаточным для увеличения размера, в то время как для хеш-деревьев это требует более сложных вычислений, но обычно также подразумевает значительное количество файлов.
Эти факторы необходимо учитывать при проектировании структуры каталогов и управлении данными в файловой системе EXT4.