<<
>>

Реализация файловой системы NFS

Хотя реализация кода клиента и сервера не зависит от протоколов NFS, в большинстве систем Linux используется трехуровневая реализация, сходная с изображенной на рис. 10.21. Верхний уровень — это уровень системных вызовов.
Он обрабатывает такие системные вызовы, как open, read и close. После анализа системного вызова и проверки его параметров он вызывает второй уровень — уровень VFS (Virtual File System — виртуальная файловая система).

Задача уровня VFS заключается в обслуживании таблицы, содержащей по одной записи для каждого открытого файла. Уровень VFS содержит для каждого открытого файла записи, называемые v-узлами (virtual i-node — виртуальный i-узел). V-узлы используются, чтобы отличать локальные файлы от удаленных. Для удаленных файлов предоставляется информация, достаточная для доступа к ним. Для локальных файлов записываются сведения о файловой системе и i-узле, так как современные системы Linux могут поддерживать несколько файловых систем (например, ext2fs, /proc, FAT и т. д.).

Хотя уровень VFS был создан для поддержки файловой системы NFS, сегодня он поддерживается большинством современных систем Linux как составная часть операционной системы (даже если NFS не используется).

Рис. 10.21. Структура уровней файловой системы NFS

Чтобы понять, как используются v-узлы, рассмотрим выполнение последовательности системных вызовов mount, open и read. Чтобы смонтировать удаленную файловую систему, системный администратор (или сценарий /etc/rc) вызывает программу mount, указывая ей удаленный каталог, локальный каталог (в котором следует смонтировать удаленный каталог) и прочую информацию. Программа mount анализирует имя удаленного каталога и обнаруживает имя сервера NFS, на котором располагается удаленный каталог.

Затем она соединяется с этой машиной, запрашивая у нее описатель файла для удаленного каталога. Если этот каталог существует и доступен для удаленного монтирования, то сервер возвращает его описатель файла. Наконец, программа делает системный вызов mount, передавая ядру полученный от сервера описатель.

Затем ядро формирует для удаленного каталога v-узел и просит клиента NFS (см. рис. 10.21) создать в своих внутренних таблицах r-узел (удаленный i-узел) для хранения описателя файла. V-узел указывает на r-узел. Каждый v-узел на уровне VFS будет в конечном итоге содержать либо указатель на r-узел в клиенте NFS, либо указатель на i-узел в одной из локальных файловых систем (показанный на рис. 10.21 в виде пунктирной линии). Таким образом, по содержимому v-узла можно понять, является ли файл (или каталог) локальным или удаленным. Если он локальный, то могут быть найдены соответствующая файловая система и i-узел. Если файл удаленный, то могут быть найдены удаленный хост и описатель файла.

Когда на клиенте открывается удаленный файл, то в какой-то момент (при анализе пути файла) ядро обнаруживает каталог, в котором смонтирована удаленная файловая система. Оно видит, что этот каталог удаленный, и в v-узле каталога находит указатель на r-узел. Затем оно просит клиента NFS открыть файл. Клиент NFS просматривает оставшуюся часть пути на удаленном сервере (ассоциированном со смонтированным каталогом) и получает обратно описатель файла для него. Он создает в своих таблицах r-узел для удаленного файла и докладывает об этом уровню VFS, который помещает в свои таблицы v-узел для файла, указывающий на r-узел. Мы видим, что и в этом случае у каждого открытого файла (или каталога) есть v-узел, указывающий на r-узел или i-узел.

Вызывающей стороне выдается дескриптор удаленного файла. Этот дескриптор файла отображается на v-узел при помощи таблиц уровня VFS. Обратите внимание на то, что на сервере не создается никаких записей в таблицах. Хотя сервер готов предоставить описатели файлов по запросу, он не следит за состоянием описателей файлов.

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

Когда дескриптор файла используется в последующем системном вызове (например, read), то уровень VFS находит соответствующий v-узел и по нему определяет, является он локальным или удаленным, а также какой i-узел или r-узел его описывает. Затем он посылает серверу сообщение, содержащее описатель, смещение в файле (хранящееся на стороне клиента, а не сервера) и количество байтов. Для повышения эффективности обмен информацией между клиентом и сервером выполняется большими порциями — как правило, по 8192 байта (даже если запрашивается меньшее количество байтов).

Когда сообщение с запросом прибывает на сервер, оно передается там уровню VFS, который определяет локальную файловую систему, содержащую запрошенный файл. Затем уровень VFS обращается к этой файловой системе, чтобы прочитать и вернуть байты. Эти данные затем передаются клиенту. После того как уровень VFS клиента получил запрошенную им порцию данных размером 8 Кбайт, он автоматически посылает запрос на следующую порцию, чтобы она была под рукой, если понадобится. Эта функция, называемая опережающим чтением (read ahead), позволяет значительно увеличить производительность.

При записи проходится аналогичный путь от клиента к серверу. Данные также передаются порциями по 8 Кбайт. Если системный вызов write подает менее 8 Кбайт данных, то данные просто накапливаются локально. Только когда вся порция в 8 Кбайт готова, она посылается серверу. Однако если файл закрывается, то все его данные немедленно посылаются серверу.

Кроме того, для увеличения производительности применяется кэширование, как в обычной системе UNIX. Серверы кэшируют данные, чтобы уменьшить количество обращений к дискам, но это происходит незаметно для клиентов.

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

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

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

ется на 3 с, а для блоков каталога — на 30 с. Таким образом, риск несколько снижается. Кроме того, при каждом открытии кэшированного файла серверу посылается сообщение, чтобы определить, когда в последний раз был модифицирован этот файл. Если последняя модификация произошла после того, как была сохранена в кэше локальная копия файла, то эта копия из кэша удаляется, а с сервера доставляется новая копия. Наконец, каждые 30 с истекает таймер кэша и все «грязные» (модифицированные) блоки кэша посылаются на сервер. Хотя такая схема и далека от совершенства, подобные «заплатки» позволяют использовать эту систему для большинства практических случаев.

<< | >>
Источник: Э. ТАНЕНБАУМ Х. БОС. СОВРЕМЕННЫЕ ОПЕРАЦИОННЫЕ СИСТЕМ Ы 4-е ИЗДАНИЕ. 2015

Еще по теме Реализация файловой системы NFS:

  1. Э. ТАНЕНБАУМ, А. ВУДХАЛЛ. ОПЕРАЦИОННЫЕ СИСТЕМЫ Разработка и реализация 3-е издание, 2007
  2. Глава 6. Реализация права
  3. 4.2. Реализация
  4. 4. Реализация прав по ипотеке
  5. 3.3. Дальнейшая реализация проекта
  6. РЕАЛИЗАЦИЯ МЫСЛЕННОГО ПРЕДСТАВЛЕНИЯ
  7. 10. Реализация заложенного имущества
  8. § 39 Классификация договоров в отдельных видах. – Римская классификация. – Система прусского закона, французского и австрийского кодекса. – Система русского свода. – Система настоящего изложения.
  9. Механизм реализации личности
  10. Тема 15 Правова система і система права. Система законодавства та систематизація нормативно-правових актів