Книга: Операционная система UNIX
Трансляция имен
Трансляция имен
Прикладные процессы, запрашивая услуги файловой системы, обычно имеют дело с именем файла или файловым дескриптором, полученным в результате определенных системных вызовов. Однако ядро системы для обеспечения работы с файлами использует не имена, а индексные дескрипторы. Таким образом, необходима трансляция имени файла, передаваемого, например, в качестве аргумента системному вызову open(2), в номер соответствующего vnode.
В табл. 4.6 приведены системные вызовы, для выполнения которых требуется трансляция имени файла.
Таблица 4.6. Системные вызовы, требующие трансляции имени
exec(2) | Запустить программу на выполнение |
chown(2) | Изменить владельца-пользователя |
chgrp(2) | Изменить владельца-группу |
chmod (2) | Изменить права доступа |
statfs(2) | Получить метаданные файла |
rmdir(2) | Удалить каталог |
mkdir(2) | Создать каталог |
mknod(2) | Создать специальный файл устройства |
open(2) | Открыть файл |
link(2) | Создать жесткую связь |
Говоря формально, полное имя файла представляет собой последовательность слов, разделенных символом '/'. Каждый компонент имени, кроме последнего, является именем каталога. Последний компонент определяет собственно имя файла. При этом полное имя может быть абсолютным или относительным. Если полное имя начинается с символа '/', представляющего корневой каталог общего логического дерева файловой системы, то оно является абсолютным, однозначно определяющим файл из любого места файловой системы. В противном случае, имя является относительным и адресует файл относительно текущего каталога. Примером относительного имени может служить include/sys/user.h, а абсолютное имя этого файла — /usr/include/sys/user.h. Как следует из этих рассуждений, два каталога играют ключевую роль при трансляции имени: корневой каталог и текущий каталог. Каждый процесс адресует эти каталоги двумя полями структуры u_area:
struct vnode *u_cdir |
Указатель на vnode текущего каталога |
struct vnode *u_rdir |
Указатель на vnode корневого каталога |
В зависимости от имени файла трансляция начинается с vnode, адресованного либо полем u_cdir
, либо u_rdir
. Трансляция имени осуществляется покомпонентно, при этом для vnode текущего каталога вызывается соответствующая ему операция vn_lookup()
, в качестве аргумента которой передается имя следующего компонента. В результате операции возвращается vnode, соответствующий искомому компоненту.
Если для vnode каталога установлен указатель vn_vfsmountedhere
, то данный каталог является точкой монтирования. Если имя файла требует дальнейшего спуска по дереву файловой системы (т.е. пересечения точки монтирования), то операция vn_lookup()
следует указателю vn_vfsmountedhere
для перехода в подключенную файловую систему и вызывает для нее операцию vfs_root
для получения ее корневого vnode. Трансляция имени затем продолжается с этого места.
Пересечение границы файловых систем возможно и при восхождении по дереву, например, если имя файла задано указанием родительского каталога — ../../myfile.txt. Если при движении в этом направлении по пути встречается корневой vnode подключенной файловой системы (установлен флаг VROOT
в поле v_flag
), то операция vn_lookup()
следует указателю vfs_vnodecovered
, расположенному в записи vfs этой файловой системы. При этом происходит пересечение границы файловых систем, и дальнейшая трансляция продолжается с точки монтирования.
Если искомый файл является символической связью, и системный вызов, от имени которого происходит трансляция имени, "следует" символической связи, операция vn_lookup()
вызывает vn_readlink()
для получения имени целевого файла. Если оно является абсолютным (т.е. начинается с "/"), то трансляция начинается с vnode корневого каталога, адресованного полем u_rdir
области u-area.
Процесс трансляции имени продолжается, пока не просмотрены все компоненты имени или не обнаружена ошибка (например, отсутствие прав доступа). В случае удачного завершения возвращается vnode искомого файла.