Ю. Вахалия - UNIX изнутри (2003) (1114670), страница 92
Текст из файла (страница 92)
9.5). Тогда процедура копирует список из этого блока в суперблок и дополнительный блок становится свободным. Такой подход дает определенные преимущества, поскольку пространство, необходимое для хранения списков свободных блоков, напрямую зависит от общего количества свободного места в разделе диска. Следовательно, для гаполненных дисков место на хранение списка свободных блоков не тратится. 9.3.
Организация ядра системы 8518 Индексный дескриптор является фундаментальным объектом файловой системы з56. Он представляет собой закрытую структуру данных, ассоциированную с объектом уводе системы з5Ь. Как это уже упоминалось ранее, дескрипторы 392 Глава 9.
Реализации файловых систем в памяти отличаются по составу от дескрипторов, размещенных па диске. В этом разделе будет рассказано об индексных дескрипторах, находящихся в оперативной памяти, а также о том, как в системе збтз реализованы различные операции на основе этих объектов. 9.3.1. Индексные дескрипторы в памяти Индексный дескриптор в памяти представлен структурой 1поде, включающей в себя не только все поля дисковой структуры дескриптора, но и некоторые дополнительные поля, такие как: + стаде (поле 1 чподе индексного дескриптора, содержашсс т поде файла); + идентификатор устройства, относящийся к разделу диска местонахо- ждения файла; + номер индексного дескриптора файла; + флаги, используемые для синхронизации и работы с кэшем; + указатели на дескрипторы, содержащиеся в списке свободных индекс- ных дескрипторов; + указатели на дескрипторы, содсржашиеся в таблице хэшировапия.
Ядро хэширует дескрипторы по номерам, что позволяет их при необходимости быстро найти; + номер последнего прочитанного блока. На рис. 9.б продемонстрирован простой пример организации индексных дескрипторов в з56 для случая четырех таблиц хэширования. Рис. 9.6. Организация индексных дескрипторов, размещаемых в памяти 9.3. Организация ядра системы э51з 393 Массивы дисковых блоков также обрабатывается по-разному. Массив 81 аоогЦ дескриптора на диске использует для номера каждого блока элемент размером в три байта, дескрипторы в памяти для той же цели применяют четырехбайтовые переменные.
Эти различия исходят из необходимости балансировки между занимаемым местом и производительностью работы. Экономия места более важна для дескриптора на диске, в то время как скорость обработки критична прежде всего для дескриптора в памяти.
9.3.2. Получение индексных дескрипторов Просмотр на независимом от файловой системы уровне выполняется при помощи функции (ооМиррпО. Как это уже описывалось ранее в разделе 8.10.1, функция просматривает за один проход только один компонент, вызывая для этой цели операцию л'ОР ЕООКБР. При осуществлении поиска в каталоге з56 происходит вызов функции з5(оскар(), которая начинает свою работу с проверки каша подстановки имен (см. раздел 8.10.2).
Если функция не находит искомый элемент в каше, то поиск заданного имени файла будет осуществляться путем считывания каталога (по одному блоку за один прием). Если каталог содержит необходимый элемент, функция з51оо1врЦ запросит для него номер индексного дескриптора. Затем она вызовет 1йетЦ для обнаружения дескриптора. Для этого функция произведет поиск индексного дескриптора по его номеру в таблице хэширования. Если дескриптор не будет найден, функция 19е1() запросит новый индексный дескриптор и инициализирует его путем чтения дискового дескриптора. При копировании его полей в дескриптор, размещаемый в памяти, функция расширяет элементы массива й а68гЦ до границы, кратной четырем байтам.
Затем индексный дескриптор помещается в соответствучошую таблицу хэширования. Функция также осуществляет инициализацию обьекта тпог)е и устанавливает значение его поля ч ор на вектор з5чподеорз, поле ч да1а — на сам индексный дескриптор и поле ч ч(зр — на указатель чтз к которой относится файл. На последнем этапе работы функции 1ве1() происходит возврат указателя на дескриптор операции з5(оскар(), которая в свою очередь возвращает указатель на л пот(е функции 1оойвррп(). Следует отметить, что 1ветЦ является функцией файловой системы з5Б, используемой только для размещения и инициализации индексных дескрипторов и гпог)е.
Например, нри создании ново~о файла операция з5стеа1е() производит размещение незадействованного номера индексного дескриптора (из списка свободных индексных дескрипторов суперблока) и далее вызывает 1вет() для копирования этого дескриптора в намаюсь. 9.3.3. Файловый ввод-вывод Входным аргументом системных вызовов геев и ттпте является дескриптор файла (индекс, возвращаемый при его открытии), а также адрес пользовательского буфера, являющийся источником (для чтения) или приемником 394 Глава 9. Реализации файловых систем (для записи) данных, и счетчик количества передаваемых байтов.
Смешение в файле контролируется функциями для объекта открытого файла, ассоциированного с его индексным дескриптором. По завершении операции ввода- вывода значение смешения изменяется на количество переданных байтов данных. Это означает, что последуюшие вызовы гезу или ьчпге начнут свою работу с той позиции в файле, где был завершен ввод-вывод предыдущего по счету вызова. В случае использования произвольного ввода-вывода пользователю необходимо перед чтением или записью вызвать 1эеек() для перемещения указателя в нужную позицию файла.
Независимый от файловой системы код (см. раздел 8.6) использует файловый дескриптор как индекс в таблице индексных дескрипторов для получения указателя на объект открытого файла (структуры В(е), после чего проверяет корректность режима открытия данного файла. Если режим совпадает, ядро запрашивает указатель на упог1е их структуры В(е. Перед началом ввода-вывода ядро вызывает операцию ЧОР КЧ1ЕОЕК для запрещения одновременного доступа к файлу. В системе зб(з защита файла реализована при помощи объекта эксклюзивной блокировки по отношению к дескриптору файла'.
Применение блокировки гарантирует неизменность данных при чтении или записи (в рамках одного системного вызова), а также то, что все вызовы тчпге будут исходить от одной нити. Затем ядро производит запуск ЧОР КЕАО или ЧОР 1йГКПЕ, указанных в объекте упог(е. Это приведет к последующему вызову зависимых от файловой системы функций збгеабО или з5ьчг11еО соответственно.
В более ранних реализациях системы процедуры ввода-вывода использовали буферный кэш, специальную область памяти, зарезервированную для блоков файловой системы. В ЗЪ'гт4 была произведена унификация ввода-вывода файлов с операциями управления виртуальной памятью, в этой системе буферный кэш применяется только для хранения блоков метаданных. Ранняя версия буферного кэша будет рассмотрена в разделе 9.12. В этом разделе мы вкратце опишем операции, реализованные в ЗЧК4.
Подробную информацию о виртуальной памяти можно получить из раздела 14.8. Рассмотрим ввод-вывод на примере операции геаг(. Функция з5геаг(О преобразует первоначальное смешение в номер логического блока файла и смещение от начала этого блока. Затем функция производит чтение данных постранично', отображая блоки в виртуальное адресное пространство ядра. Для копирования данных в пользовательское адресное пространство вызывается функция ц(оглоче(), которая, в свою очередь, запускает процедуру соруоцг() для передачи текущих данных. Если страница не находится в физической памяти, либо ядро системы не обладает корректным адресом для ее преобра- ' Во многих системах 111Ч!Х для атой цели используется объект блокировки одного пишущепг и множества читающих процессов, что дает возможность более гибко реализовать параллелизм работы ОС.
Страница — это понятие, относящееся к обработке памяти. Страница может содержать один блок, часть блока ияи несколько блоков. 9.3. Организация ядра системы абта 395 зования, функция соруоцЦ) сгенернрует ошибку страничной памяти. Обработчик ошибок идентифицирует файл, к которому относится эта страница, и выполнит операцию ЧОР ОЕТРАОЕ по отношению к его чпот(е.
В файловой системе з5Ь такая операция реализована при помощи функции з5ае~рапеО. Эта функция начинает работу с вызова (ппарО для преобразования номера логического блока в физический номер блока на диске. Затем она производит проверку нахождения страницы объекта чподе (на который указывает поле ч ра9е) в памяти. Если страница не будет обнаружена в памяти, функция з5йе1райеО запросит свободную страницу и вызовет дисковый драйвер для осушествления операции чтения данных с диска.
Вызывающий процесс будет находиться в режиме ожидания до тех пор, пока операция чтения не завершится. После прочтения блока дисковый драйвер произведет пробуждение процесса, который, в свою очередь, продолжит копирование данных соруоцС(). Перед копированием данных в пользовательское пространство операция ссруоиЦ) убедится в наличии прав пользователя на запись в буфер, в который необходимо передать данные. Если не производить такой проверки, то при случайном или преднамеренном указании неверного адреса можно столкнуться с крупными проблемами.