Литмир - Электронная Библиотека
Содержание  
A
A

алгоритм namei /* превращение имени пути поиска в индекс */

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

выходная информация: заблокированный индекс

{

 if (путь поиска берет начало с корня)
 рабочий индекс = индексу корня (алгоритм iget);

 else
 рабочий индекс = индексу текущего каталога (алгоритм iget);

 do (пока путь поиска не кончился)
 {

  считать следующую компоненту имени пути поиска;

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

  if (рабочий индекс соответствует корню и компонента имени «..»)
 continue; /* цикл с условием продолжения */

поиск компоненты:

  считать каталог (рабочий индекс), повторяя алгоритмы bmap, bread и brelse;

  if (компонента соответствует записи в каталоге (рабочем индексе)) 
{

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

   if (найденный индекс является индексом корня и рабочий индекс является индексом корня и имя компоненты «..») 
{

    /* пересечение точки монтирования */

    получить запись в таблице монтирования для рабочего индекса;

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

    рабочий индекс = индексу точки монтирования;

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

    увеличить значение счетчика ссылок на рабочий индекс;

    перейти к поиску компоненты (для «..»);

   }

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

   рабочий индекс = индексу с новым номером (алгоритм iget);

  }

  else /* компонента отсутствует в каталоге */
 return (нет индекса);

 }

 return (рабочий индекс);

}

Рисунок 5.26. Модификация алгоритма синтаксического анализа имени файла

В вышеприведенном примере (cd «../../..») предполагается, что в начале процесс имеет текущий каталог с именем «/usr/src/uts». Когда имя пути поиска подвергается анализу в алгоритме namei, начальным рабочим индексом является индекс текущего каталога. Ядро меняет текущий рабочий индекс на индекс каталога с именем «/usr/src» в результате расшифровки первой компоненты «..» в имени пути поиска. Затем ядро анализирует вторую компоненту «..» в имени пути поиска, находит корневой индекс смонтированной (перед этим) файловой системы — индекс каталога «usr» — и делает его рабочим индексом при анализе имени с помощью алгоритма namei. Наконец, оно расшифровывает третью компоненту «..» в имени пути поиска. Ядро обнаруживает, что номер индекса для «..» совпадает с номером корневого индекса, рабочим индексом является корневой индекс, а «..» является текущей компонентой имени пути поиска. Ядро находит запись в таблице монтирования, соответствующую точке монтирования «usr», освобождает текущий рабочий индекс (корень файловой системы, смонтированной в каталоге «usr») и назначает индекс точки монтирования (каталога «usr» в корневой файловой системе) в качестве нового рабочего индекса. Затем оно просматривает записи в каталоге точки монтирования «/usr» в поисках имени «..» и находит номер индекса для корня файловой системы («/»). После этого системная функция chdir завершается как обычно, вызывающий процесс не обращает внимания на тот факт, что он пересек точку монтирования.

5.14.2 Демонтирование файловой системы

Синтаксис вызова системной функции umount:

umount(special filename);

где special filename указывает демонтируемую файловую систему. При демонтировании файловой системы (Рисунок 5.27) ядро обращается к индексу демонтируемого устройства, восстанавливает номер устройства для специального файла, освобождает индекс (алгоритм iput) и находит в таблице монтирования запись с номером устройства, равным номеру устройства для специального файла. Прежде чем ядро действительно демонтирует файловую систему, оно должно удостовериться в том, что в системе не осталось используемых файлов, для этого ядро просматривает таблицу индексов в поисках всех файлов, чей номер устройства совпадает с номером демонтируемой системы. Активным файлам соответствует положительное значение счетчика ссылок и в их число входят текущий каталог процесса, файлы с разделяемым текстом, которые исполняются в текущий момент (глава 7), и открытые когда-то файлы, которые потом не были закрыты. Если какие-нибудь файлы из файловой системы активны, функция umount завершается неудачно: если бы она прошла успешно, активные файлы сделались бы недоступными.

Буферный пул все еще содержит блоки с «отложенной записью», не переписанные на диск, поэтому ядро «вымывает» их из буферного пула. Ядро удаляет записи с разделяемым текстом, которые находятся в таблице областей, но не являются действующими (подробности в главе 7), записывает на диск все недавно скорректированные суперблоки и корректирует дисковые копии всех индексов, которые требуют этого. Казалось, было бы достаточно откорректировать дисковые блоки, суперблок и индексы только для демонтируемой файловой системы, однако в целях сохранения преемственности изменений ядро выполняет аналогичные действия для всей системы в целом. Затем ядро освобождает корневой индекс монтированной файловой системы, удерживаемый с момента первого обращения к нему во время выполнения функции mount, и запускает из драйвера процедуру закрытия устройства, содержащего файловую систему. Впоследствии ядро просматривает буферы в буферном кеше и делает недействительными те из них, в которых находятся блоки демонтируемой файловой системы; в хранении информации из этих блоков в кеше больше нет необходимости. Делая буферы недействительными, ядро вставляет их в начало списка свободных буферов, в то время как блоки с актуальной информацией остаются в буферном кеше. Ядро сбрасывает в индексе системы, где производилось монтирование, флаг «точки монтирования», установленный функцией mount, и освобождает индекс. Пометив запись в таблице монтирования свободной для общего использования, функция umount завершает работу.

алгоритм umount

входная информация: имя специального файла, соответствующего демонтируемой файловой системе

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

{

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

41
{"b":"96903","o":1}