Добавлен: 29.10.2018
Просмотров: 48102
Скачиваний: 190
316
Глава 4. Файловые системы
Рис. 4.4. Иерархическая система каталогов
4.2.3. Имена файлов
Когда файловая система организована в виде дерева каталогов, нужен какой-нибудь
способ указания имен файлов. Чаще всего для этого используются два метода. В первом
методе каждому файлу дается абсолютное имя (полное имя), состоящее из пути от
корневого каталога к файлу. Например, имя
/usr/ast/mailbox
означает, что корневой
каталог содержит подкаталог
usr
, который, в свою очередь, содержит подкаталог
ast
,
в котором содержится файл
mailbox
. Абсолютные имена файлов всегда начинаются
с названия корневого каталога и являются уникальными именами. В системе UNIX
компоненты пути разделяются символом «слеш» —
/
. В системе Windows разделите-
лем служит символ «обратный слеш» —
\
. В системе MULTICS этим разделителем
служила угловая скобка —
>
. В этих трех системах одно и то же имя будет выглядеть
следующим образом:
Windows \usr\ast\mailbox
UNIX /usr/ast/mailbox
MULTICS >usr>ast>mailbox
Если в качестве первого символа в имени файла используется разделитель, то неза-
висимо от символа, используемого в этом качестве, путь будет абсолютным.
Другой разновидностью имени является относительное имя. Оно используется со-
вместно с понятием рабочего каталога (называемого также текущим каталогом).
Пользователь может определить один каталог в качестве текущего, и тогда все имена
файлов станут рассматриваться относительно рабочего каталога и не будут начинаться
с корневого каталога. К примеру, если текущим рабочим каталогом будет
/usr/ast
, то
к файлу, имеющему абсолютное имя
/usr/ast/mailbox
, можно будет обращаться, просто
указывая
mailbox
. Иначе говоря, команда UNIX
cp /usr/ast/mailbox /usr/ast/mailbox.bak
и команда
cp mailbox mailbox.bak
делают одно и то же, если рабочим каталогом является
/usr/ast
. Относительная форма
указания имен зачастую более удобна, но при этом делает то же самое, что и абсолют-
ная форма.
4.2. Каталоги
317
Некоторым программам нужен доступ к конкретному файлу безотносительно того,
какой каталог является рабочим. В таком случае им всегда нужно использовать абсо-
лютные имена. К примеру, программе проверки правописания в процессе работы может
понадобиться чтение файла
/usr/lib/dictionary
. В таком случае ей следует использовать
полное, абсолютное имя, поскольку она не знает, какой каталог будет при ее вызове
рабочим. Абсолютное имя файла будет работать всегда, независимо от того, какой
именно каталог будет рабочим.
Разумеется, если программа проверки правописания нуждается в большом коли-
честве файлов из каталога
/usr/lib
, то альтернативным подходом будет следующий:
использовать системный вызов для смены рабочего каталога на
/usr/lib
, а затем в ка-
честве первого параметра системного вызова open можно будет использовать лишь
имя
dictionary
. За счет явного изменения рабочего каталога программа точно знает,
в каком месте дерева каталогов она работает, поэтому она может использовать от-
носительные пути к файлам.
У каждого процесса есть свой рабочий каталог, поэтому, когда процесс меняет свой ра-
бочий каталог и потом завершает работу, это не влияет на работу других процессов и в
файловой системе от подобных изменений не остается никаких следов. Таким образом,
процесс может когда угодно изменить свой рабочий каталог, абсолютно не беспокоясь
о последствиях. В то же время, если библиотечная процедура поменяет свой рабочий
каталог и при возврате управления не восстановит прежний рабочий каталог, то вы-
звавшая ее программа может оказаться не в состоянии продолжить работу, так как ее
предположения о текущем каталоге окажутся неверными. Из-за этого библиотечные
процедуры редко меняют свои рабочие каталоги, а когда им все-таки приходится это
делать, они обязательно восстанавливают прежний рабочий каталог перед возвратом
управления.
Большинство операционных систем, поддерживающих иерархическую систему ката-
логов, имеют в каждом каталоге специальные элементы «.» и «..», которые обычно про-
износятся как «точка» и «точка-точка». Точка является ссылкой на текущий каталог,
а двойная точка — на родительский каталог (за исключением корневого каталога, где
этот элемент является ссылкой на сам корневой каталог). Чтобы увидеть, как они исполь-
зуются, обратимся к дереву каталогов системы UNIX (рис. 4.5). Пусть у нас есть некий
процесс, для которого каталог
/usr/ast
является рабочим. Чтобы переместиться вверх по
дереву, он может использовать обозначение «
..
.». К примеру, он может копировать файл
/usr/lib/dictionary
в собственный каталог при помощи команды
cp ../lib/dictionary .
Первый указанный путь предписывает системе подняться вверх по дереву (к каталогу
usr
), затем опуститься вниз к каталогу
lib
и найти в нем файл
dictionary
.
Второй аргумент (точка) заменяет имя текущего каталога. Когда в качестве последнего
аргумента команда cp получает имя каталога (включая точку), она копирует все файлы
в этот каталог. Разумеется, куда более привычным способом копирования будет ис-
пользование полного абсолютного имени пути к файлу-источнику:
cp /usr/lib/dictionary .
Здесь использование точки избавляет пользователя от необходимости второй раз на-
бирать имя
dictionary
. Тем не менее, если набрать
cp /usr/lib/dictionary dictionary
318
Глава 4. Файловые системы
Рис. 4.5. Дерево каталогов UNIX
команда будет работать так же, как и при наборе
cp /usr/lib/dictionary /usr/ast/dictionary
Все эти команды приводят к одному и тому же результату.
4.2.4. Операции с каталогами
Допустимые системные вызовы для управления каталогами имеют большее количество
вариантов от системы к системе, чем системные вызовы, управляющие файлами. Рас-
смотрим примеры, дающие представление об этих системных вызовах и характере их
работы (взяты из системы UNIX).
Create (Создать каталог). Каталог создается пустым, за исключением точки и двой-
ной точки, которые система помещает в него автоматически (или в некоторых
случаях при помощи программы mkdir).
Delete (Удалить каталог). Удалить можно только пустой каталог. Каталог, содержа-
щий только точку и двойную точку, рассматривается как пустой, поскольку они не
могут быть удалены.
Opendir (Открыть каталог). Каталоги могут быть прочитаны. К примеру, для вы-
вода имен всех файлов, содержащихся в каталоге, программа ls открывает каталог
4.3. Реализация файловой системы
319
для чтения имен всех содержащихся в нем файлов. Перед тем как каталог может
быть прочитан, он должен быть открыт по аналогии с открытием и чтением файла.
Closedir (Закрыть каталог). Когда каталог прочитан, он должен быть закрыт, чтобы
освободить пространство во внутренних таблицах системы.
Readdir (Прочитать каталог). Этот вызов возвращает следующую запись из от-
крытого каталога. Раньше каталоги можно было читать с помощью обычного
системного вызова read, но недостаток такого подхода заключался в том, что про-
граммист вынужден был работать с внутренней структурой каталогов, о которой
он должен был знать заранее. В отличие от этого, readdir всегда возвращает одну
запись в стандартном формате независимо от того, какая из возможных структур
каталогов используется.
Rename (Переименовать каталог). Во многих отношениях каталоги подобны файлам
и могут быть переименованы точно так же, как и файлы.
Link (Привязать). Привязка представляет собой технологию, позволяющую файлу
появляться более чем в одном каталоге. В этом системном вызове указываются
существующий файл и новое имя файла в некотором существующем каталоге
и создается привязка существующего файла к указанному каталогу с указанным
новым именем. Таким образом, один и тот же файл может появиться в нескольких
каталогах, возможно, под разными именами. Подобная привязка, увеличивающая
показания файлового счетчика i-узла (предназначенного для отслеживания коли-
чества записей каталогов, в которых фигурирует файл), иногда называется жесткой
связью
, или жесткой ссылкой (hard link).
Unlink (Отвязать). Удалить запись каталога. Если отвязываемый файл присутству-
ет только в одном каталоге (что чаще всего и бывает), то этот вызов удалит его из
файловой системы. Если он фигурирует в нескольких каталогах, то он будет уда-
лен из каталога, который указан в имени файла. Все остальные записи останутся.
Фактически системным вызовом для удаления файлов в UNIX (как ранее уже было
рассмотрено) является unlink.
В приведенном списке перечислены наиболее важные вызовы, но существуют и другие
вызовы, к примеру для управления защитой информации, связанной с каталогами.
Еще одним вариантом идеи привязки файлов является символическая ссылка (symbolic
link). Вместо двух имен, указывающих на одну и ту же внутреннюю структуру данных,
представляющую файл, может быть создано имя, указывающее на очень маленький файл,
в котором содержится имя другого файла. Когда используется первый файл, например
он открывается, файловая система идет по указанному пути и в итоге находит имя. Затем
она начинает процесс поиска всех мест, где используется это новое имя. Преимуществом
символических ссылок является то, что они могут пересекать границы дисков и даже
указывать на имена файлов, находящихся на удаленных компьютерах. И тем не менее
их реализация несколько уступает в эффективности жестким связям.
4.3. Реализация файловой системы
Настала пора перейти от пользовательского взгляда на файловую систему к взгляду
специалистов на ее реализацию. Пользователей волнует, как можно назвать файлы, ка-
кие операции над ними допустимы, как выглядит дерево каталогов и другие подобные
320
Глава 4. Файловые системы
вопросы, касающиеся взаимодействия с файловой системой. Разработчиков интересует,
как хранятся файлы и каталоги, как осуществляется управление дисковым простран-
ством и как добиться от всего этого эффективной и надежной работы. В следующих
разделах будет рассмотрен ряд перечисленных вопросов, чтобы можно было понять,
какие проблемы и компромиссы встречаются на этом пути.
4.3.1. Структура файловой системы
Файловые системы хранятся на дисках. Большинство дисков может быть разбито на
один или несколько разделов, на каждом из которых будет независимая файловая
система. Сектор 0 на диске называется главной загрузочной записью (Master Boot
Record (MBR)) и используется для загрузки компьютера. В конце MBR содержится
таблица разделов. Из этой таблицы берутся начальные и конечные адреса каждого
раздела. Один из разделов в этой таблице помечается как активный. При загрузке ком-
пьютера BIOS (базовая система ввода-вывода) считывает и выполняет MBR. Первое,
что делает программа MBR, — находит расположение активного раздела, считывает
его первый блок, который называется загрузочным, и выполняет его. Программа в за-
грузочном блоке загружает операционную систему, содержащуюся в этом разделе. Для
достижения единообразия каждый раздел начинается с загрузочного блока, даже если
он не содержит загружаемой операционной системы. Кроме того, в будущем он может
содержать какую-нибудь операционную систему.
Во всем остальном, кроме того, что раздел начинается с загрузочного блока, строение
дискового раздела значительно различается от системы к системе. Зачастую файло-
вая система будет содержать некоторые элементы, показанные на рис. 4.6. Первым
элементом является суперблок. В нем содержатся все ключевые параметры файловой
системы, которые считываются в память при загрузке компьютера или при первом
обращении к файловой системе. Обычно в информацию суперблока включаются «ма-
гическое» число, позволяющее идентифицировать тип файловой системы, количество
блоков в файловой системе, а также другая важная административная информация.
Далее может находиться информация о свободных блоках файловой системы, к при-
меру в виде битового массива или списка указателей. За ней могут следовать i-узлы,
массив структур данных — на каждый файл по одной структуре, в которой содержится
Рис. 4.6. Возможная структура файловой системы