Ю. Вахалия - UNIX изнутри (2003) (1114670), страница 84
Текст из файла (страница 84)
...) где многоточие обозначает другие входные аргументы процедуры с(озе. Приведенный макрос гарантирует, что после соответствующей инициализации чпо((е применение операции ЧОР СЕ05Е приведет к вызову процедуры пЬ с!охе() для файла иЬ, пЬ с(озер для файла ХгЯ и т. д. Базовый класс чЬ также обладает двумя полями, чЬ ((а1а и чЬ ор, позволяющими осуществлять взаимосвязь с данными и функциями, реализующими определенные файловые системы. Компоненты чтя показаны на рис. 8.9. 8.7.
краткий обзор реализации 357 Рис. 8.9. Организация Фз В языке С базовый класс реализуется как структура, а также набор глобальных функций (и макросов) ядра, определяющих публичные невиртуальные функции. Базовый класс содержит указатель на другую структуру, состоящую из набора указателей на функции, по одному для каждой виртуальной функции. Указатели ч ор и ч бра (для класса чгз указатели чгз ор и чгз да~а) позволяют соединить подклассы, предоставляя таким образом доступ к функциям и данным, зависящим от конкретной файловой системы.
8.7. Краткий обзор реализации Следующие разделы посвящены более подробному анализу интерфейса чподе/ чЬ, а также описанию реализации различных файловых операций. 8.7.1. Цели, стоящие перед разработчиками Для создания гибкого интерфейса, который можно было бы эффективно использовать для работы с различными типами файловых систем, перед разработчиками были поставлены следующие цели: + каждая операция должна выполняться в зависимости от состояния текущего процесса, который может быть переведен в режим сна, если функции необходимо приостановить работу в ожидании ресурса или события; + многие операции должны использовать последовательный доступ к файлам.
Следовательно, они могут блокировать структуры данных на уровне, зависимом от конкретной файловой системы. Операции обязаны производить освобождение ресурсов перед завершением своей работы; + интерфейс не.должен задействовать информацию о состоянии (зГасе1езз). Он не должен использовать глобальные переменные, такие как поля области и, для передачи информации о состоянии между процессами; 358 Глава 8. Базовые элементы и интерфейс файловой системы + реентерабельность интерфейса.
Это требование позволяет не привлекать глобальные переменные, такие как ц еиог или ц ша11, для хранения кодов ошибок или возвращаемых значений. Фактически все операции передают коды ошибок как возвращаемые значения; + реализации файловых систем должны уметь задействовать общие ресурсы системы, такие как буферный кэш (но не в принудительном порядке); + пригодность интерфейса для использования серверной частью удаленной файловой системы с целью обработки клиентских запросов; + не рекомендуется применение статических таблиц фиксированных размеров. Вместо этого должно применяться динамическое размещение (везде, где это возможно).
8.7.2. Открытые файлы и объекты чпобе Понятие члене обозначает фундаментальную абстракцию, представляющую используемый файл в ядре системы. Обьект чпоое определяет интерфейс доступа к файлам и заменяет все операции с ними на функции, специфичные для определенной файловой системы. Существует два способа доступа ядра к чподе. Системный вызов, относящийся к вводу-выводу, может вызвать объект вводе при помощи дескриптора файла (более подробно читайте об этом ниже).
Вторьи способом является преобразование процедурами полных имен файлов для обнаружения чпосе-структур данных, зависящих от конкретной файловой системы. Более подробно о преобразовании полных имен вы узнаете из раздела 8.10.1, Для того чтобы прочесть файл или произвести запись в него, процесс должен сначала его открыть.
Системный вызов орел возвращает файловый дескриптор. Такой дескриптор, являющийся обычно целым числом, применяется как идентификатор файла и соответствует независимому сеансу, или потоку, для этого файла. В дальнейшем процесс передает полученный дескриптор вызовам геад или апре. На рис. 8.10 показаны основные структуры данных. Файловый дескриптор является объектом процесса, содержащим указатель на обьекгл открытого фабвь ла (зтшст В(е), а также набор флагов. Поддерживаемыми флагами являются: ЕЕЕ05ЕХЕС (для указания ядру на необходимость использования дескриптора при вызове процессом ехес) и 0 ЕРЕОСК (применяется для блокировки файла).
Объект открытого файла хранит контекст, управляющий сеансом работы с файлом. Если файл открыт несколькими пользователями (либо один пользователь открыл файл несколько раз), то каждый экземпляр будет обладать собственным объектом открытого файла. Поля такого объекта содержат: + смешение, от которого начнется следующая операция чтения или записи; + счетчик ссылок, содержащий количество файловых дескрипторов, указывающих на файл. Счетчик обычно равен единице, но значение может быть и вьппе, если дескрипторы дублированы при помощи дцр или Еог1; 8.7.
Краткий обзор реализации 359 Двокрилтор файла объекты, зввиоомыв от файловой оиетвмы Рис. 8.10. Структуры данных, независимые от файловой системы + указатель на чпог(е файла; + режим, в котором был открыт файл. Ядро проверяет режим при каждой операции ввода-вывода. Таким образом, если пользователь открыл файл только для чтения, он не сможет произвести запись в него, используя дескриптор, даже если пользователь обладает необходимыми полномочиями. В традиционных системах 1)(т(1Х применяется статическая таблица дескрипторов фиксированного размера, располагаемая в области ц. Размер таблицы (обычно это 64 элемента) ограничивает количество файлов, открытых одним пользователем.
В современных вариантах 1)Х1Х таблица дескрипторов ве имеет ограничений по размеру и может вырасти до огромных размеров'. В некоторых реализациях ОС, например в оЧК4 или БцпОБ, дескрипторы размещаются в блоках (обычно) по 32 элемента. Блоки хранятся в связанном списке, первый блок находится в области ц процесса. Это усложняет задачу удержания дескриптора. Вместо использования его в качества индекса к таблице ядру приходится сначала находить нужный блок и затем производить к нему запрос.
При незначительном увеличении сложности кода такая схема позволяет снять ограничение на количество файлов, открываемых одним процессом. В современных операционных системах, основанных на этгК4, таблица дескрипторов размещается динамически и расширяется по мере необходимости при помощи вызова Ьпегп айос(), производящего либо расширение существующей таблицы, либо копирование ее в новое место, имеющее свободное пространство для увеличения объема таблицы.
Этот способ позволяет увеличивать таблицу дескрипторов динамически и производить их быстрое преобразование, что достигается путем копирования таблицы при ее размещении. 8.7.3. Структура чиойе Объект чпог(е представлен структурой данных, приведенной ниже; аггссг чпоое ( и зпогт ч 11афсп I* флаги У кООТ и т. д. */ ' Размер таблнпы ограыичеы аг1М11 НОВЕЕ. 360 Глава 8. Базовые элементы и интерфейс файловой системы ц злогс ч соцпт; /* счетчик ссылок */ зтгцст ттз *ттзщоцптеолеге: /* для точек ионтирования */ зтгцст чпооеорз *ч ор; /* вектор операций тпоое */ зтгцст ттз *итар: !* файловая систеиа, к которой относится структура */ звгцст зтоата *т зтгеащ; l* указатель на ассоциированный поток, если таковой существует */ зтгцст раде *ч раде; /* резидентный список страниц */ епцщ ттуре ч "уре; /* тип файла */ оет С и гоеи: /* идентификатор устройства для файлов устройств *! сапог т т пата: /* указатель на закрытую структуру данных */ Отдельные поля структуры более подробно будут разобраны в следующих разделах главы.
8.7.4. Счетчик ссылок мпобе Поле ы соцпт структуры чпоое содержит счетчик ссылок, при помощи которо. го определяется, как долю структура будет поддерживаться ядром. Структура чпоое размещается и ассоциируется с файлом при первом доступе к нему. Позже указатели (или ссылки) на ыпотте могут поддерживать и другие объекты, желающие получить доступ к этому файлу при помощи таких указателей.
Это означает, что ядро будет поддерживать структуру чпотте и не сможет произвести ассоциацию ее с другим файлом до тех пор, пока существуют такие ссылки. Счетчик ссылок является одним из общих свойств структуры чпоое. Манипуляции с ним производятся фрагментом кода, независящим.от конкретной файловой системы. Для инкремента и декремента счетчика используются макросы ЧМ НОЕР и ЧМ йЕЕЕ. Если значение счетчика станет равным нулю, это будет означать, что файл неактивен и его структура ыпоое может быть освобождена или передана другому файлу.