Все, что вы когда-либо хотели знать об индексных дескрипторах в Linux

Файловая система Linux полагается на inodes. Эти важные части внутренней работы файловой системы часто неправильно понимаются. Давайте посмотрим, что именно они и чем занимаются.

Элементы файловой системы

По определению файловая система должна хранить файлы, и они также содержат каталоги. Файлы хранятся в каталогах, и эти каталоги могут иметь подкаталоги. Что-то где-то должно записывать, где все файлы находятся в файловой системе, как они называются, каким учетным записям они принадлежат, какие разрешения у них есть и многое другое. Эта информация называется метаданными, потому что это данные, описывающие другие данные.

В файловой системе Linux ext4 структуры inode и каталогов работают вместе, обеспечивая основу, в которой хранятся все метаданные для каждого файла и каталога. Они делают метаданные доступны для тех , кто требует его, будь то ядро, пользовательские приложения или утилиты Linux, такие как ls, stat, и df.

Inodes и размер файловой системы

Хотя это правда, что есть пара структур, файловая система требует гораздо большего. Есть тысячи и тысячи каждой структуры. Каждому файлу и каталогу требуется индексный дескриптор, и поскольку каждый файл находится в каталоге, каждый файл также требует структуры каталогов. Структуры каталогов также называются записями каталогов или «dentries».

У каждого inode есть номер inode, который уникален в пределах файловой системы. Один и тот же номер inode может появляться в нескольких файловых системах. Однако идентификатор файловой системы и номер inode вместе составляют уникальный идентификатор, независимо от того, сколько файловых систем смонтировано в вашей системе Linux.

Помните, что в Linux вы не монтируете жесткий диск или раздел. Вы монтируете файловую систему, которая находится в разделе, поэтому легко иметь несколько файловых систем, даже не осознавая этого. Если у вас есть несколько жестких дисков или разделов на одном диске, у вас есть несколько файловых систем. Они могут быть одного типа - например, все ext4 - но все равно будут разными файловыми системами.

Все иноды хранятся в одной таблице. Используя номер inode, файловая система легко вычисляет смещение в таблице inode, в которой находится этот индекс. Вы можете понять, почему «i» в inode означает index.

Переменная, содержащая номер inode, объявлена ​​в исходном коде как 32-битное длинное целое число без знака. Это означает, что номер inode - это целое число с максимальным размером 2 ^ 32, что дает 4 294 967 295 - более 4 миллиардов inode.

Это теоретический максимум. На практике количество индексных дескрипторов в файловой системе ext4 определяется, когда файловая система создается с соотношением по умолчанию один индекс на 16 КБ емкости файловой системы. Структуры каталогов создаются «на лету», когда файловая система используется, поскольку файлы и каталоги создаются в файловой системе.

Есть команда, которую вы можете использовать, чтобы узнать, сколько inodes находится в файловой системе на вашем компьютере. Параметр -i(inodes) dfкоманды указывает ей отображать вывод в количестве inodes.

Мы собираемся взглянуть на файловую систему на первом разделе на первом жестком диске, поэтому мы набираем следующее:

df -i / dev / sda1

Результат дает нам:

  • Файловая система : файловая система, о которой сообщается.
  • Inodes : общее количество inodes в этой файловой системе.
  • IUsed : количество используемых inodes.
  • IFree : количество оставшихся inodes, доступных для использования.
  • IUse% : процент используемых inodes.
  • Установлено : точка монтирования для этой файловой системы.

Мы использовали 10 процентов inode в этой файловой системе. Файлы хранятся на жестком диске в дисковых блоках. Каждый индексный дескриптор указывает на блоки диска, в которых хранится содержимое файла, который они представляют. Если у вас есть миллионы крошечных файлов, у вас могут закончиться inode до того, как закончится место на жестком диске. Однако это очень сложная проблема.

В прошлом эта проблема возникала на некоторых почтовых серверах, на которых сообщения электронной почты хранились в виде отдельных файлов (что быстро приводило к большим коллекциям небольших файлов). Однако, когда эти приложения изменили свои серверные части на базы данных, это решило проблему. В средней домашней системе не закончатся inodes, что также хорошо, потому что с файловой системой ext4 вы не можете добавить больше inodes без переустановки файловой системы.

Чтобы увидеть размер дисковых блоков в вашей файловой системе, вы можете использовать blockdevкоманду с параметром --getbsz(получить размер блока):

sudo blockdev --getbsz / dev / sda

Размер блока 4096 байт.

Давайте воспользуемся -Bопцией (размер блока), чтобы указать размер блока 4096 байт и проверить регулярное использование диска:

df -B 4096 / dev / sda1

Этот вывод показывает нам:

  • Файловая система : файловая система, по которой мы составляем отчет.
  • Блоки по 4 КБ: общее количество блоков по 4 КБ в этой файловой системе.
  • Используется : сколько блоков 4K используется.
  • Доступно : количество оставшихся блоков по 4 КБ, доступных для использования.
  • Использовать% : процент использованных блоков по 4 КБ.
  • Установлено : точка монтирования для этой файловой системы.

В нашем примере файловое хранилище (и хранилище индексных дескрипторов и структур каталогов) заняло 28 процентов пространства в этой файловой системе за счет 10 процентов индексов, так что мы в хорошей форме.

Метаданные Inode

Чтобы увидеть номер inode файла, мы можем использовать lsс -iопцией (inode):

ls -i geek.txt

Номер inode для этого файла - 1441801, поэтому этот inode содержит метаданные для этого файла и, традиционно, указатели на блоки диска, в которых файл находится на жестком диске. Если файл фрагментирован, очень велик или и то, и другое, некоторые из блоков, на которые указывает индексный дескриптор, могут содержать дополнительные указатели на другие блоки диска. И некоторые из этих других дисковых блоков могут также содержать указатели на другой набор дисковых блоков. Это решает проблему того, что индексный дескриптор имеет фиксированный размер и может содержать конечное количество указателей на блоки диска.

Этот метод был заменен новой схемой, в которой используются «экстенты». Они записывают начальный и конечный блоки каждого набора смежных блоков, используемых для хранения файла. Если файл нефрагментирован, вам нужно сохранить только первый блок и длину файла. Если файл фрагментирован, вы должны сохранить первый и последний блок каждой части файла. Этот метод (очевидно) более эффективен.

Если вы хотите узнать, использует ли ваша файловая система указатели или экстенты дисковых блоков, вы можете заглянуть внутрь inode. Для этого мы воспользуемся debugfsкомандой с параметром -R(request) и передадим ей индексный дескриптор интересующего файла. Он просит  debugfs использовать его внутреннюю команду «stat» для отображения содержимого inode. Поскольку номера inode уникальны только в пределах файловой системы, мы также должны указать debugfs файловую систему, в которой находится inode.

Вот как будет выглядеть этот пример команды:

sudo debugfs -R "stat" / dev / sda1

Как показано ниже, debugfsкоманда извлекает информацию из inode и представляет ее нам в less:

Нам показана следующая информация:

  • Inode : номер рассматриваемого inode.
  • Тип : это обычный файл, а не каталог или символическая ссылка.
  • Режим : права доступа к файлу в восьмеричном формате.
  • Флаги : индикаторы, которые представляют различные функции или функции. 0x80000 - это флаг «экстентов» (подробнее об этом ниже).
  • Генерация : сетевая файловая система (NFS) использует это, когда кто-то обращается к удаленным файловым системам через сетевое соединение, как если бы они были смонтированы на локальном компьютере. Номера inode и генерации используются как форма дескриптора файла.
  • Версия : версия inode.
  • Пользователь : владелец файла.
  • Группа : владелец группы файла.
  • Проект : всегда должен быть равен нулю.
  • Размер : размер файла.
  • Файл ACL : список управления доступом к файлам. Они были разработаны, чтобы позволить вам предоставлять контролируемый доступ людям, не входящим в группу владельцев.
  • Ссылки : количество жестких ссылок на файл.
  • Blockcount : объем места на жестком диске, выделенный для этого файла, выраженный фрагментами по 512 байт. Нашему файлу было выделено восемь из них, что составляет 4096 байт. Итак, наш 98-байтовый файл находится в одном блоке диска размером 4096 байт.
  • Фрагмент : этот файл не фрагментирован. (Это устаревший флаг.)
  • Ctime : время создания файла.
  • Atime : время последнего доступа к этому файлу.
  • Mtime : время последнего изменения этого файла.
  • Crtime : время создания файла.
  • Размер дополнительных полей inode : файловая система ext4 представила возможность выделять больший inode на диске во время форматирования. Это значение представляет собой количество дополнительных байтов, которые использует индексный дескриптор. Это дополнительное пространство также можно использовать для удовлетворения будущих требований к новым ядрам или для хранения расширенных атрибутов.
  • Дескриптор контрольная сумма : Контрольная сумма для этого дескриптора, который позволяет обнаружить , если индексный дескриптор поврежден.
  • Экстенты : если используются экстенты (в ext4 они используются по умолчанию), метаданные, касающиеся использования файлового блока на диске, имеют два числа, которые указывают начальный и конечный блоки каждой части фрагментированного файла. Это более эффективно, чем хранение каждого блока диска, занимаемого каждой частью файла. У нас есть один экстент, потому что наш небольшой файл находится в одном блоке диска при этом смещении блока.

Где имя файла?

Теперь у нас есть много информации о файле, но, как вы могли заметить, мы не получили имя файла. Здесь вступает в игру структура каталогов. В Linux, как и файл, каталог имеет индексный дескриптор. Однако вместо того, чтобы указывать на блоки диска, содержащие данные файлов, индексный дескриптор каталога указывает на блоки диска, содержащие структуры каталогов.

По сравнению с индексным дескриптором, структура каталогов содержит ограниченный объем информации о файле. Он содержит только номер inode файла, имя и длину имени.

Inode и структура каталогов содержат все, что вам (или приложению) нужно знать о файле или каталоге. Структура каталогов находится в блоке каталога на диске, поэтому мы знаем каталог, в котором находится файл. Структура каталогов дает нам имя файла и номер inode. Inode сообщает нам все остальное о файле, включая временные метки, разрешения и где найти данные файла в файловой системе.

Каталог Inodes

Вы можете увидеть номер inode каталога так же легко, как и для файлов.

В следующем примере мы будем использовать ls параметры -l(длинный формат), -i(индексный дескриптор) и -d(каталог) и посмотрим на workкаталог:

ls -lid work /

Поскольку мы использовали параметр -d(каталог), он  lsсообщает о самом каталоге, а не о его содержимом. Индекс этого каталога - 1443016.

Чтобы повторить это для homeкаталога, мы набираем следующее:

ls -lid ~

homeInode для каталога 1447510, и workкаталог находится в домашнем каталоге. Теперь посмотрим на содержимое workкаталога. Вместо параметра  -d(каталог) мы будем использовать параметр -a(все). Это покажет нам записи каталога, которые обычно скрыты.

Набираем следующее:

ls -lia work /

Поскольку мы использовали параметр -a(все), отображаются записи с одинарной (.) И двойной точкой (..). Эти записи представляют сам каталог (одинарная точка) и его родительский каталог (двойная точка).

Если вы посмотрите на номер inode для записи с одной точкой, вы увидите, что это 1443016 - тот же номер inode, который мы получили, когда обнаружили номер inode для workкаталога. Кроме того, номер inode для записи с двумя точками совпадает с номером inode для homeкаталога.

Вот почему вы можете использовать cd ..команду для перехода на следующий уровень в дереве каталогов. Точно так же, когда вы ставите перед именем приложения или сценария   ./, вы даете оболочке знать, откуда запускать приложение или сценарий.

Inodes и ссылки

Как мы уже говорили, три компонента должны иметь правильно сформированный и доступный файл в файловой системе: файл, структура каталогов и индексный дескриптор. Файл - это данные, хранящиеся на жестком диске, структура каталогов содержит имя файла и его номер inode, а inode содержит все метаданные для файла.

Символические ссылки - это записи файловой системы, которые выглядят как файлы, но на самом деле они являются ярлыками, указывающими на существующий файл или каталог. Посмотрим, как им это удается и как для этого используются три элемента.

Допустим, у нас есть каталог с двумя файлами: один - это сценарий, а другой - приложение, как показано ниже.

Мы можем использовать команду ln и -s(символическую) опцию для создания мягкой ссылки на файл сценария, например:

ls -s my_script geek.sh

Мы создали ссылку на my_script.shвызов geek.sh. Мы можем ввести следующее и использовать  ls для просмотра двух файлов сценариев:

ls -li * .sh

Запись для geek.sh отображается синим цветом. Первый символ флагов разрешений - это «l» для ссылки, а  ->указывает на my_script.sh. Все это указывает на то, что geek.shэто ссылка.

Как и следовало ожидать, два файла сценария имеют разные номера inode. Что может быть более удивительным, так это то, что программная ссылка geek.shне имеет тех же прав пользователя, что и исходный файл сценария. Фактически, разрешения для  geek.shгораздо более либеральны - все пользователи имеют полные разрешения.

Структура каталогов для geek.shсодержит имя ссылки и ее индексный дескриптор. Когда вы пытаетесь использовать ссылку, на ее индексный дескриптор ссылается, как на обычный файл. Inode ссылки будет указывать на блок диска, но вместо данных содержимого файла блок диска содержит имя исходного файла. Файловая система перенаправляет на исходный файл.

Мы удалим исходный файл и посмотрим, что произойдет, когда мы введем следующее для просмотра содержимого  geek.sh:

rm my_script.sh
кошка geek.sh

Символьная ссылка не работает, и перенаправление не выполняется.

Теперь мы вводим следующее, чтобы создать жесткую ссылку на файл приложения:

в специальном приложении компьютерное приложение

Чтобы посмотреть inodes для этих двух файлов, мы вводим следующее:

ls -li

Оба выглядят как обычные файлы. Ничто не geek-appуказывает на то, что это ссылка, как в lsлистинге geek.sh. Кроме того,  geek-app имеет те же права пользователя, что и исходный файл. Однако может показаться удивительным то, что оба приложения имеют одинаковый номер inode: 1441797.

Запись в каталоге для geek-appсодержит имя «geek-app» и номер inode, но он совпадает с номером inode исходного файла. Итак, у нас есть две записи файловой системы с разными именами, каждая из которых указывает на один и тот же индексный дескриптор. Фактически, любое количество элементов может указывать на один и тот же индексный дескриптор.

Мы введем следующее и воспользуемся statпрограммой для просмотра целевого файла:

специальное приложение stat

Мы видим, что на этот файл указывают две жесткие ссылки. Он хранится в inode.

В следующем примере мы удаляем исходный файл и пытаемся использовать ссылку с секретным безопасным паролем:

rm special-app
./geek-app righthorsebatterystaple

Удивительно, но приложение работает как положено, но как? Это работает, потому что, когда вы удаляете файл, индексный дескриптор можно использовать повторно. Структура каталогов помечается как имеющая нулевой индексный дескриптор, после чего блоки диска становятся доступными для хранения в этом пространстве другого файла.

Однако, если количество жестких ссылок на индексный дескриптор больше единицы, количество жестких ссылок уменьшается на единицу, а номер индексного дескриптора в структуре каталогов удаленного файла устанавливается равным нулю. Содержимое файла на жестком диске и индексный дескриптор по-прежнему доступны для существующих жестких ссылок.

Мы введем следующее и снова воспользуемся stat - на этот раз geek-app:

stat geek-app

Эти данные берутся из того же inode (1441797), что и предыдущая statкоманда. Количество ссылок уменьшилось на одну.

Поскольку у нас есть одна жесткая ссылка на этот индекс, если мы удалим  geek-app, он действительно удалит файл. Файловая система освободит индексный дескриптор и пометит структуру каталогов нулевым индексом. Затем новый файл может перезаписать хранилище данных на жестком диске.

СВЯЗАННЫЕ: Как использовать команду stat в Linux

Накладные расходы Inode

это изящная система, но есть накладные расходы. Чтобы прочитать файл, файловая система должна сделать все следующее:

  • Найдите правильную структуру каталогов
  • Прочтите номер inode
  • Найдите правильный индекс
  • Прочтите информацию об индексе
  • Следуйте либо по ссылкам inode, либо по экстентам к соответствующим дисковым блокам.
  • Прочитать данные файла

Если данные не являются смежными, необходимо еще немного прыгнуть.

Представьте себе работу, которую необходимо проделать,  ls чтобы выполнить длинный список файлов в формате, состоящий из множества файлов. Существует много способов lsполучить информацию, необходимую для создания вывода.

Конечно, ускорение доступа к файловой системе - вот почему Linux старается максимально упреждающе кэшировать файлы. Это очень помогает, но иногда, как и в случае с любой файловой системой, накладные расходы могут стать очевидными.

Теперь вы знаете почему.