Главная страница Межпроцессное взаимодействие (состязание) Фронт списка Тыл списка -> NULL NULL фронт списка NULL Тыл списка NULL NULL Тыл списка фронт списка NULL Рис. 5.30. Инициализация кэша блоков: а - начальное состояние; б - после запроса одного блока; а - после того как блок освобожден Если значение параметра ramsize меньше объема корневой файловой системы, RAM-диск увеличивается, чтобы вместить ее. Если же RAM-диск вмещает всю корневую файловую систему и на нем еще остается место, производится подстройка с целью подогнать размер диска под объем файловой системы. Чтобы записать новую информацию в суперблок, вызывается функция put.bLock. Это единственный случай, когда суперблок модифицируется. Функция load ram выделяет память для RAM-диска, когда параметр ramsize равен нулю. При этом на диск не копируется никаких структур файловой системы, и прежде чем работать с диском, их нужно создать при помощи команды mkfs. Пустой же RAM-диск можно использовать в качестве вторичного кэща, если поддержка такового включена при компиляции системы. Последняя функция в main.c - load super - выполняет инициализацию таблицы суперблоков и считывает суперблок корневого устройства. 5.7.4. Работа с отдельными файлами в этом разделе мы рассмотрим системные вызовы по отношению к отдельным файлам (в противоположность тем, которые оперируют, скажем, каталогами). Начнем же с того, как файлы создаются, открываются и закрываются. Затем мы более подробно изучим механизм записи и чтения файлов. И на десерт у нас будут процедуры, работающие с каналами, и понимание того, чем их работа отличается от работы с файлами. Создание, открытие и закрытие файлов Файл open.с содержит код шести системных вызовов: creat, open, mknod, mkdir, close и Iseek. Вызовы creat и open мы рассмотрим вместе, а затем перейдем к остальным. В более старых версиях UNIX вызовы creat и open служили для разных целей. При попытке открыть несуществующий файл возникала ошибка, а новый файл должен был создаваться при помощи creat, другой задачей которого является установка размера файла в нулевое значение. Но в современной POSIX-системе два отдельных вызова не требуются. По POSIX, созданием файла или обнулением старого должен заниматься вызов open, поэтому возможности creat теперь составляют лишь часть потенциала open, и нужен он только для совместимости со старыми программами. Процедуры, выполняющие действия creat и open, называются соответственно do creat и do open (как и в случае с менеджером памяти, здесь соблюдается соглашение именовать обработчик системного вызова ххх как do xxx). Открытие или создание файла включает три шага. 1. Поиск г-узла (или выделение и инициализация нового г-узла, если файл создается). 2. Поиск или создание записи в каталоге. 3. Настройка дескриптора файла и его возврат. Оба вызова, creat и open, делают лишь то, что принимают имя файла и перекладывают задачи, общие для обоих вызовов, на плечи common open. Процедура common open начинает с того, что проверяет наличие свободных файловых дескрипторов и ячеек в таблице filp. Затем, если при вызове было ука- зано создать новый файл (то есть установлен бит 0 CREAT), вызывается функция new node. Если запись в каталоге уже присутствует, эта функция возвращает указатель на существующий г-узел, в противном случае она создает новую запись и г-узел. Если г-узел не может быть создан, функция записывает код ошибки в глобальную переменную err code. Наличие кода ошибки не обязательно означает сбой. Когда new node обнаруживает одноименный файл, она сигнализирует об этом через код ошибки, но в действительности здесь нет ничего противоправного. При неустановленном бите 0 CREAT поиск г-узла осуществляется альтернативным методом, через посредство функции eat pat из состава файла path.с, которую мы обсудим позже. На данном этапе важно лишь знать, что если г-узел не удалось ни найти, ни создать, работа common open завершается с ошибкой прежде, чем начинается выделение файлового дескриптора. Иначе функция продолжает работу, назначая файлу дескриптор и запрашивая запись в таблице filp. Следующий блок кода пропускается, если файл создается именно сейчас. Если же файл существовал ранее, файловая система должна определить, что это за файл, какие разрешения выставлены у него и т. д., чтобы выяснить, может ли он быть открыт. Проверку битов rwx (то есть битов, управляющих доступом) выполняет вызов forbidden. Если файл представляет собой обычный файл и при вызове был установлен бит 0 TRUNC, длина файла приравнивается нулю и снова вызывается forbidden, на этот раз чтобы проверить доступность файла на запись. Когда запись разрешена, вызываются функции wipejnode и rwjnode, очищающие г-узел и сохраняющие его на диске. Для других типов файлов (каталогов, специальных файлов и каналов ввода/вывода) делаются соответствующие проверки. Так, в случае устройства, при помощи структуры dmap выполняется вызов нужной процедуры, которая открывает его. За открытие именованного канала отвечает функция pipe open, для него выполняются различные проверки, имеющие отношение к каналам. В коде функции common open, как и в тексте других процедур файловой системы, есть большое количество проверок различных ошибок и недопустимых комбинаций параметров. Хотя этот код и не изящен, он важен для получения устойчивой, свободной от врожденных дефектов файловой системы. Если произошла какая-либо ошибка, ранее выделенные файловый дескриптор и ячейка в таблице filp освобождаются. Функция common open в этом случае возвращает отрицательное значение, говорящее об ошибке. Если проблем с файловым дескриптором не было, код возврата является положительным числом. Отложим в сторону файлы и займемся каталогами. И для начала поглядим на работу функции new node, что занимается выделением г-узла для вызовов creat и open. Обратившись к ней, мы вводим в рассмотрение путь к файлу. Она также используется системными вызовами mknod и mkdir, которые еще будут обсуждаться. Сначала эта функция разбирает путь к файлу, то есть просматривает его компонент за компонентом, пока не достигает конечного каталога. При помощи функции advance проверяется, может ли быть открыт последний компонент. Например, если сделан вызов fd = create /usr/ast/foobar . 0755):
|
© 2000 - 2024 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования. |