Выбрать главу

Если данный файл уже существовал до вызова функции creat, ядро обнаруживает его индекс во время поиска имени файла. Старый файл должен позволять процессу производить запись в него, чтобы можно было создать «новый» файл с тем же самым именем, так как ядро изменяет содержимое файла при выполнении функции creat: оно усекает файл, освобождая все информационные блоки по алгоритму free, так что файл будет выглядеть как вновь созданный. Тем не менее, владелец и права доступа к файлу остаются прежними: ядро не передает право собственности на файл владельцу процесса и игнорирует права доступа, указанные процессом в вызове функции. Наконец, ядро не проверяет наличие разрешения на запись в каталог, являющийся родительским для существующего файла, поскольку оно не меняет содержимого каталога.

Функция creat продолжает работу, выполняя тот же алгоритм, что и функция open. Ядро выделяет созданному файлу запись в таблице файлов, чтобы процесс мог читать из файла, а также запись в таблице пользовательских дескрипторов файла, и в конце концов возвращает указатель на последнюю запись в виде пользовательского дескриптора файла.)

5.8 СОЗДАНИЕ СПЕЦИАЛЬНЫХ ФАЙЛОВ

Системная функция mknod создает в системе специальные файлы, в число которых включаются поименованные каналы, файлы устройств и каталоги. Она похожа на функцию creat в том, что ядро выделяет для файла индекс. Синтаксис вызова системной функции mknod:

mknod(pathname, type and permissions, dev)

где pathname — имя создаваемой вершины в иерархической структуре файловой системы, type and permissions — тип вершины (например, каталог) и права доступа к создаваемому файлу, а dev указывает старший и младший номера устройства для блочных и символьных специальных файлов (глава 10). На Рисунке 5.13 приведен алгоритм, реализуемый функцией mknod при создании новой вершины.

алгоритм создания новой вершины

входная информация:

 вершина (имя файла)

 тип файла

 права доступа

 старший, младший номера устройства (для блочных и символьных специальных файлов)

выходная информация: отсутствует

{

 if (новая вершина не является поименованным каналом и пользователь не является суперпользователем)

  return (ошибку);

 получить индекс вершины, являющейся родительской для новой вершины (алгоритм namei);

 if (новая вершина уже существует) {

  освободить родительский индекс (алгоритм iput);

  return (ошибку);

 }

 назначить для новой вершины свободный индекс из файловой системы (алгоритм ialloc);

 создать новую запись в родительском каталоге;

 включить имя новой вершины и номер вновь назначенного индекса;

 освободить индекс родительского каталога (алгоритм iput);

 if (новая вершина является блочным или символьным специальным файлом)

  записать старший и младший номера в структуру индекса;

 освободить индекс новой вершины (алгоритм iput);

}

Рисунок 5.13. Алгоритм создания новой вершины

Ядро просматривает файловую систему в поисках имени файла, который оно собирается создать. Если файл еще пока не существует, ядро назначает ему новый индекс на диске и записывает имя нового файла и номер индекса в родительский каталог. Оно устанавливает значение поля типа файла в индексе, указывая, что файл является каналом, каталогом или специальным файлом. Наконец, если файл является специальным файлом устройства блочного или символьного типа, ядро записывает в индекс старший и младший номера устройства. Если функция mknod создает каталог, он будет существовать по завершении выполнения функции, но его содержимое будет иметь неверный формат (в каталоге будут отсутствовать записи с именами «.» и «..»). В упражнении 5.33 рассматриваются шаги, необходимые для преобразования содержимого каталога в правильный формат.

5.9 СМЕНА ТЕКУЩЕГО И КОРНЕВОГО КАТАЛОГА

Когда система загружается впервые, нулевой процесс делает корневой каталог файловой системы текущим на время инициализации. Для индекса корневого каталога нулевой процесс выполняет алгоритм iget, сохраняет этот индекс в пространстве процесса в качестве индекса текущего каталога и снимает с индекса блокировку. Когда с помощью функции fork создается новый процесс, он наследует текущий каталог старого процесса в своем адресном пространстве, а ядро, соответственно, увеличивает значение счетчика ссылок в индексе.

алгоритм смены каталога

входная информация: имя нового каталога

выходная информация: отсутствует

{

 получить индекс для каталога с новым именем (алгоритм namei);

 if (индекс не является индексом каталога или же процессу не разрешен доступ к файлу)  {

  освободить индекс (алгоритм iput);

  return (ошибку);

 }

 снять блокировку с индекса;

 освободить индекс прежнего текущего каталога (алгоритм iput);

 поместить новый индекс в позицию для текущего каталога в пространстве процесса;

}

Рисунок 5.14. Алгоритм смены текущего каталога