Главная страница  Межпроцессное взаимодействие (состязание) 

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 [ 171 ] 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

цию большого кэша. В этом случае можно так настроить файловую систему, чтобы RAM-диск выступал в роли дополнительного кэша, хранящего блоки, изгнанные из основного. Мы не будем обсуждать здесь эту возможность, так как на 32-битных системах Intel такой необходимости нет, большой основной кэш дает наилучшую производительность. Тем не менее вспомогательный кэш, вероятно, окажется полезен на компьютере, где не хватает места для большого основного кэша в виртуальном адресном пространстве файловой системы (например, это может быть 286-я модель). Дополнительный кэш будет работать лучше, чем обычный RAM-диск, в силу того что кэш хранит только данные, которые хотя бы раз действительно потребовались, и достаточно вместительный кэш может значительно увеличить производительность. Какой объем должен иметь достаточно большой кэш, заранее сказать нельзя. Ответ дает экспериментирование с тем, приводит ли дальнейшее наращивание кэша к повышению производительности. Полезным инструментом для оптимизации системы является команда time, которая позволяет измерить время выполнения определенной программы.

Работа с i-узлами

Не только кэшу блоков требуются управляющие подпрофаммы. Для работы с таблицей г-узлов они также необходимы. Многие из этих процедур аналогичны процедурам для работы с блоками. Сами процедуры перечислены в табл. 5.6.

Таблица 5.6. Процедуры для работы с 1-узлами

Процедура Назначение

getjnode Помещает i-узел в память

putjnode Возвращает более не нужный 1-узел

allocjnode Выделяет новый i-узел (для нового файла)

wipejnode Очищает некоторые поля i-узла

freejnode Освобождает i-узел (при удалении файла)

updatejimes Обновляет поля времени в i-узле

rw inode Передает 1-узел между памятью и диском

oldjcopy Преобразует данные i-узла, чтобы записать его на диск в формате VI

newjcopy Преобразует данные i-узла, чтобы записать его на диск в формате V2

dupjnode Указывает, что кто-то еще использует i-узел

Функция getjnode является аналогом get block. Когда какой-либо части системы требуется получить г-узел, она вызывает эту функцию. Сначала getjnode ищет узел в таблице, чтобы узнать, не зафужен ли он уже. Если да, счетчик использования г-узла увеличивается и возвращается указатель на него. Поиск производится большим циклом в коде функции. Если в памяти г-узел не найден, он загружается при помощи вызова rwjnode.

Когда процедура, которой потребовался г-узел, завершает свои действия с ним, то, чтобы возвратить г-узел, она вызывает процедуру putjnode, уменьшающую значение счетчика использования. Нулевое значение счетчика подразумевает,



что файл больше никому не нужен и может быть удален из таблицы. Если при этом f-узел оказался изменен, он перезаписывается на диск.

Если поле i link равно нулю, значит, на файл не ссылается ни один из каталогов, поэтому все его зоны могут быть освобождены. Обратите внимание, что обнуление счетчика ссылок i Hnk и счетчика использования - разные события, они обусловлены разными причинами и приводят к разным следствиям. Если г-узел соответствует каналу ввода/вывода, все его зоны должны быть освобождены, даже если число ссылок не равно нулю. Такое может произойти, когда процесс, читающий из канала, освободит его. Нет никакого смысла поддерживать канал для одного процесса.

Когда создается файл, для него должен быть выделен новый г-узел при помощи процедуры allocjnode. В MINIX устройства можно монтировать в режиме только для чтения, поэтому функция сначала смотрит в суперблоке, разрешена ли запись на устройство. В отличие от зон, которые выбираются в стремлении держать все зоны файла близко друг к другу, здесь подойдет любой г-узел. Чтобы уменьшить время поиска в битовой карте г-узлов, используются поля суперблока, в которых хранится положение первого свободного г-узла.

После того как новый г-узел получен, он загружается в таблицу в памяти при помощи getjnode. Затем, частично прямо на месте, а частично - при помощи процедуры wipejnode, его поля инициализируются. Такое разделение труда выбрано здесь потому, что wipejnode вызывается и в некоторых других частях системы для очистки отдельных полей г-узла.

При удалении файла его г-узел освобождается посредством процедуры free inode. Эта подпрограмма просто сбрасывает соответствующий бит в карте г-узлов и обновляет ссылку на первый свободный г-узел в суперблоке.

Следующая функция, update times, вызывается, чтобы получить от системных часов время и изменить нуждающиеся в обновлении значения полей времени. Она также вызывается из stat и fstat, поэтому объявлена как PUBLIC.

Процедура rwjnode аналогична процедуре rw block. Ее назначение в том, чтобы считать г-узел с диска. Это действие она выполняет в четыре следующих этапа:

1. Определение блока, в котором находится необходимый г-узел.

2. Считывание блока при помощи get block.

3. Извлечение г-узла и копирование его в таблицу inode.

4. Возврат блока посредством put block.

Код rwjnode несколько сложнее, чем приведенная выше схема, так как от него требуются некоторые дополнительные действия. Во-первых, поскольку определение текущего времени является весьма дорогостоящей операцией, все поля г-узла, подлежащие обновлению значения времени, только помечаются путем установки соответствующих битов в поле г-узла в памяти i update. Если это поле будет иметь ненулевое значение, при записи будет вызвана функция update times.

Во-вторых, дополнительную сложность вносит история MINIX. В старой версии файловой системы VI г-узлы на диске имели структуру, отличную от структуры в новой версии V2. Поэтому о преобразовании заботятся две функции.



old copy и new copy. Первая из них преобразует представление г-узла в памяти в формат старой версии VI. Вторая делает то же самое для новой версии V2. Обе функции используются только в пределах этого файла, поэтому они объявлены как PRIVATE. Обе они выполняют преобразование в двух направлениях, как из памяти на диск, так и обратно. ОС MINIX работает и на системах, где расположение байтов в слове отличается от такового в процессорах Intel. В каждой реализации информация на диске хранится в том порядке, какой принят в системе. А что это за порядок, система узнает из поля sp->native в суперблоке. Поэтому old copy и new copy при необходимости вызывают conv2 и conv4, с целью изменить порядок байтов.

Процедура dupjnode просто увеличивает на единицу счетчик использования г-узла. Она вызывается при повторном открытии файла, при этом г-узел не нужно еще раз считывать с диска.

Работа с суперблоками

в файле super.c находятся процедуры для работы с суперблоками и битовыми картами. Эти пять процедур перечислены в табл. 5.7.

Таблица 5.7. Процедуры для работы с суперблоками и битовыми картами Процедура Назначение

alloc bit Выделяет бит в битовой карте i-узлов или зон

free bit Освобождает бит в битовой карте i-узлов или зон

get super Ищет устройство в таблице суперблоков

mounted Сообщает, принадлежит ли i-узел монтированной или корневой

файловой системе

read super Считывает суперблок

Как мы видели выше, когда требуется г-узел или зона, вызывается функция allocjnode или alloc zone. Каждая из них, в свою очередь, вызывают alloc bit, чтобы найти неустановленный бит в битовой карте. Поиск включает в себя три вложенных цикла, работающих следующим образом:

1. Внешний цикл перебирает все блоки битовой карты.

2. Промежуточный цикл перебирает все слова блока.

3. Внутренний цикл проверяет все биты в слове.

В промежуточном цикле выясняется, является ли текущее слово дополнением нуля, то есть состоит ли оно целиком из единиц. Если да, значит, в этом слове нет свободных битов, и проверяется следующее слово. Когда обнаруживается другое значение, где по крайней мере один бит равен О, запускается внутренний цикл, который определяет его позицию в слове. Если оказалось, что проверены все блоки, но нулевых битов не нашлось, значит, свободных г-узлов или зон на диске нет, и возвращается код NO BIT (0). Подобный поиск может потребовать много процессорного времени, но благодаря указателям на первый свободный



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 [ 171 ] 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187

© 2000 - 2018 ULTRASONEX-AMFODENT.RU.
Копирование материалов разрешено исключительно при условии цититирования.