Рис. 4.8. Метаданные файла виртуальной файловой системы
Монтирование файловой системы
Прежде чем может состояться работа с файлами, соответствующая файловая система должна быть встроена в существующее иерархическое дерево.
Только после этого ядро сможет выполнять файловые операции, такие как создание, открытие, чтение или запись в файл. Эта операция встраивания получила название подключения или монтирования файловой системы.
Каждая подключенная файловая система представлена на независимом уровне в виде структуры
vfs
, аналоге записи таблицы монтирования дисковой файловой системы. Структуры
vfs
всех подключенных файловых систем организованы в виде односвязного списка, в совокупности обеспечивая информацию, необходимую для обслуживания всего иерархического дерева, а также информацию о реальной файловой системе, которые не изменяются на протяжении работы. Первой записью списка всегда является корневая файловая система. В дальнейшем, список
vfs
мы будем называть устоявшимся термином — таблица монтирования. Поля структуры
vfs
приведены в табл. 4.3.
Таблица 4.3. Поля структуры vfs
struct vfs *vfs_next
| Следующая файловая система в списке монтирования. |
struct vfsops *vfs_op
| Операции файловой системы. |
struct vnode *vfs_vnodecovered
| vnode, перекрываемый файловой системой. |
int vfs_flag
| Флаги: только для чтения, запрещен бит SUID и т.д. |
int vfs_bsize
| Размер блока файловой системы. |
caddr_t vfs_data
| Указатель на специфические данные, относящиеся к реальной файловой системе. |
Поле
vfs_data
содержит указатель на данные реальной файловой системы. Например, для дисковой файловой системы s5fs, это поле указывает на суперблок, размещенный в памяти.
Поле
vfs_op
указывает на операции файловой системы, которые в терминах объектно-ориентированного подхода могут быть названы виртуальными методами объекта
vfs
. Возможные операции файловой системы приведены в табл. 4.4. Поскольку они существенным образом зависят от архитектуры и конкретной реализации, поля
vfs_op
заполняются указателями на соответствующие функции реальной файловой системы при ее монтировании.
Таблица 4.4. Операции файловой системы
int (*vfs_mount)()
| Подключает файловую систему. Обычно операция включает размещение суперблока в памяти и инициализацию записи в таблице монтирования. |
int (*vfs_unmount)()
| Отключает файловую систему. Операция включает актуализацию данных файловой системы на накопителе (например, синхронизацию дискового суперблока и его образа в памяти). |
int (*vfs_root)()
| Возвращает корневой vnode файловой системы. |
int (*vfs_statfs)()
| Возвращает общую информацию о файловой системе, в частности: размер блока хранения данных, число блоков, число свободных блоков, число inode. |
int (*vfs_sync)()
| Актуализирует все кэшированные данные файловой системы. |
int (*vfs_fid)()
| Возвращает файловый идентификатор (fid — file Identifier), однозначно адресующий файл в данной файловой системе. В качестве fid может, например, выступать номер inode реальной файловой системы. |
int (*vfs_vget)()
| Возвращает указатель на vnode для файла данной файловой системы, адресованного fid. |
Для инициализации и монтирования реальной файловой системы UNIX хранит коммутатор файловых систем (File System Switch), адресующий процедурный интерфейс для каждого типа файловой системы, поддерживаемой ядром. UNIX System V для этого использует глобальную таблицу, каждый элемент которой соответствует определенному типу реальной файловой системы, например s5fs, ufs или nfs. Элемент этой таблицы vfssw имеет поля, указанные в табл. 4.5.
Таблица 4.5. Коммутатор файловых систем
char *vsw_name
| Имя типа файловой системы |
int (*vsw_init)()
| Адрес процедуры инициализации |
struct vfsops *vsw_vfsops
| Указатель на вектор операций файловой системы |
long vsw_flag
| Флаги |
Взаимодействие структур виртуальной файловой системы показано на рис. 4.9.
Рис. 4.9. Структуры данных виртуальной файловой системы
Монтирование файловой системы производится системным вызовом mount(2). В качестве аргументов передаются тип монтируемой файловой системы, имя каталога, к которому подключается файловая система (точка монтирования), флаги (например, доступ к файловой системе только для чтения) и дополнительные данные, конкретный вид и содержимое которых зависят от реализации реальной файловой системы. При этом производится поиск vnode, соответствующего файлу — точке монтирования (операция
lookup()
или
namei()
трансляции имени), и проверяется, что файл является каталогом и не используется в настоящее время для монтирования других файловых систем.
Затем происходит поиск элемента коммутатора файловых систем
vfssw[]
, соответствующего типу монтируемой файловой системы. Если такой элемент найден, вызывается операция инициализации, адресованная полем
vsw_init()
. При этом выполняется размещение специфических для данного типа файловой системы данных, после чего ядро размещает структуру
vfs
и помещает ее в связанный список, подключенных файловых систем, как это показано на рис. 4.11. Поле
vfs_vnodecovered
указывает на vnode точки монтирования. Это поле устанавливается нулевым для корневой (root) файловой системы, элемент
vfs
которой всегда расположен первым в списке подключенных файловых систем. Поле
vfs_op
адресует вектор операций, определенный для данного типа файловой системы. Наконец, указатель на данный элемент
vfs
сохраняется в поле
v_vfsmountedhere
виртуального индексного дескриптора каталога — точки монтирования.