Как Linux управляет удалением временных файлов? - PullRequest
1 голос
/ 15 января 2020

Я изучал некоторую реализацию Linux, и у меня возник вопрос:

Насколько я знаю, есть бит, который помечает файл как временный файл. Когда процесс, который сгенерировал этот файл, умирает, как ядро ​​удаляет его? Я подумал, что это может быть связано с таблицей файловых дескрипторов, но я не уверен в этом.

Если кто-то может дать объяснение шаг за шагом, это пригодится!

Ответы [ 2 ]

4 голосов
/ 15 января 2020

Нет бита, который помечает файл как временный файл.

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

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

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

  1. Создает файл. Количество ссылок inode на диске = 1.
  2. Открывает файл. Количество ссылок на inode ядра = 2.
  3. Удаляет имя файла. Количество ссылок на inode ядра = 1.

На этом этапе процесс может продолжать использовать временный файл, но он не может быть открыт другим процессом, поскольку у него нет имени.

Когда процесс закрывает дескриптор файла, счетчик ссылок становится равным 0, и файл удаляется.

Последние версии Linux имеют флаг O_TMPFILE для open(2), который автоматизирует это. Вместо указания имени файла вы просто указываете каталог, который просто используется для поиска файловой системы для хранения данных файла. Когда это используется, он фактически делает все 3 шага выше в одном вызове, но фактически никогда нигде не создает имя файла (таким образом, избегаются условия гонки и конфликты имен).

0 голосов
/ 18 января 2020

Я провел некоторое исследование топи c и обнаружил дополнительную информацию, дополняющую ответ, который дал Бармар.

Я читал о системном вызове tmpfile (). Этот системный вызов создает временный файл и возвращает дескриптор потока.

Дело в том, что tmpfile выполняет внутренний вызов для отмены связи. Таким образом уменьшается количество ссылок. Хотя эта ссылка была последней, если файл был открыт каким-либо процессом, он существует до тех пор, пока не будет закрыт. Я не уверен на 100% в том, как эта процедура работает внутри, но я думаю, что это связано с порядком, в котором алгоритм iPut проверяет как количество ссылок, так и количество ссылок. Я видел несколько реализаций iPut и, прежде всего, он проверяет, равен ли счетчик ссылок нулю, и если да, то он переходит на счетчик ссылок, освобождая все блоки, присвоенные файлу, если он равен нулю.

Так что в этой ситуации у нас будет счетчик ссылок == 1, потому что у нас все равно будет процесс с открытым файлом, но счетчик ссылок будет нулевым. Поэтому iput не освобождает i-узел, пока процесс не закроет файл.

...