2015-06-28 4 views
1

я наткнулся this и this вопросов по стиранию открытых файлов в LinuxЧто происходит внутри при удалении открытого файла в Linux

Однако, я до сих пор путает, что произошло в памяти, когда процесс (назовет его A) удаляет открытый файл другим процессом B.

Что меня расстраивает это (мой анализ может быть не так, пожалуйста, поправьте меня, если это так):

  • Когда процесс открывает файл, новая запись для этого файла в UFDT создается.
  • Когда процесс удаляет файл, все ссылки на файл ушли особенно, у нас нет никаких ссылок на его inode, таким образом, он получает удаляется из GFDT
  • Однако, при изменении файла (скажем, записи в он), он должен быть обновлен на диске (поскольку его страницы становятся модифицированными/грязными), но он не получил ссылки в GFDT из-за более раннего удаления, поэтому мы не знаем его inode.

Вопрос является почему «удален» файл все еще доступен на процессе, который открыл его? И как это было сделано операционной системой?

EDIT По UFDT я имею в виду таблицу дескрипторов файла процесс, который держит дескрипторы файлов, которые открыты в процессе (каждый процесс имеет свой собственный UFDT) и GFDT является глобальным файлом таблицы дескрипторов, в системе есть только один GFDT (RAM в нашем случае).

ответ

0

Когда процесс открывает файл, новая запись для этого файла в UFDT создается .

Что это за странный акроним? Полагаю, вы имеете в виду, что рассматриваемый процесс имеет файловый дескриптор.

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

Что на земле это GFDT?

Однако, при изменении файла (скажем, запись на него) он должен быть обновлен в диске (так как ее страница модифицируется/грязным), но не получили ссылки в GFDT из-за ранее удаление , поэтому мы не знаем inode.

Я угадываю, что этот GFDT имеет какое-то отношение к тому, чтобы быть «глобальным» и «файловым дескрипторами».

Итак, все это показывает серьезные заблуждения.

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

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

Возможно, они не будут уничтожены, если нет имен, и ядро ​​больше не использует его.

+0

Я отредактировал вопрос о том, что я имел в виду под GFDT и UFDT. Чтобы объект структурного файла был чем-то уникальным только для одного процесса? я имею в виду, когда процесс закрывает файл структуры, он удаляется из его (процесса) пространства памяти, независимо от того, был ли файл удален или нет? и аналогичным образом, если файл будет удален, файл структуры не будет выполнен? – ThunderWiring

3

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

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

  • Каждый процесс имеет таблицу дескрипторов файлов. Каждая запись в этой таблице хранит дескриптор файла и флаги состояния дескриптора файла (на данный момент единственным флагом является O_CLOEXEC). Дескриптор файла - это всего лишь указатель на запись в записи таблицы файлов, которую я описываю далее. Целое число, возвращаемое open(2), и семейство обычно является индексом в эту файловую дескрипторную таблицу - каждый процесс имеет свою таблицу, поэтому open(2) и семейство могут возвращать одинаковое значение для разных процессов, открывающих разные файлы.
  • Существует одна открытая таблица файлов во всей системе. Каждая запись таблицы дескриптора файла каждого процесса ссылается на одну из этих записей в таблице открытых файлов. В каждой таблице есть одна запись для каждого открытого файла: если два процесса открывают один и тот же файл, создаются две записи в этой глобальной таблице, хотя это один и тот же файл. Каждая запись в таблице файлов хранит флаги состояния файла (открытые для чтения, записи, добавления и т. Д.) И текущее смещение файла. Вот почему разные процессы могут считывать и записывать в разные смещения в одном файле одновременно, пока каждый из них открывает файл.
  • Каждая запись в записи таблицы файлов также ссылается на запись в таблице vnode. Таблица vnode - это глобальная таблица, которая имеет одну запись для каждого уникального файла. Если процессы A, B и C открывают файл D, будет существовать только одна запись в таблице vnode, на которую ссылаются все 3 записи таблицы файлов (в Linux нет действительно vnode, скорее, есть индексный дескриптор, но давайте сохраним это описание общего и концептуального). Запись vnode содержит почти ту же информацию, что и традиционный индекс (размер файла, другие атрибуты и т. Д.), Но также содержит другую информацию, полезную для открытых файлов, таких как блокировки файлов, которые являются активными, кто их владеет, какие части файл, который они блокируют, и т. д. Эта запись vnode также хранит указатели на блоки данных файла на диске.

Удаление файла состоит из вызова unlink(2). Эта функция отключает файл из каталога. Каждый файл inode на диске имеет количество ссылок, указывающих на него; файл действительно удаляется, если счетчик ссылок достигает 0 и он не открывается (или 2 в случае каталогов, поскольку каталог ссылается на себя и на который также ссылается его родитель).На самом деле, страница руководства для unlink(2) очень специфична об этом поведении:

Unlink - удалить имя и, возможно, файл, он относится к

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

Когда unlink(2) обнаруживает, что имеется активная запись таблицы vnode, ссылающаяся на этот файл, она не удаляет файл из файловой системы. Ничего не произошло. Да, вы больше не можете найти файл в своей файловой системе. find(1) не найдет его. Вы не можете открыть его в новых процессах.

Но файл все еще существует. Он просто не отображается ни в одной записи каталога.

Например, если это огромный файл, и если вы запустите df или du, вы увидите, что использование пространства - это то же самое. Файл все еще есть на диске, вы просто не можете его достичь.

Таким образом, любые чтения или записи происходят, как обычно, - блоки данных файла доступны через запись в таблице vnode. Вы все еще можете узнать размер файла. И хозяин. И разрешения. Все это. Все там.

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

Смежные вопросы