Описание VFS Виртуальной Файловой Системы Linux

Мой неполный вольный перевод [Overview of the Linux Virtual File System](https://www.kernel.org/doc/html/latest/filesystems/vfs.html). Некоторые моменты, по различным причинам, я пока не понимаю, поэтому кое-что привожу в оригинале, как повод для дальнейших размышлений. Другие же моменты, как мне кажется, я понимаю, поэтому дополнил их некоторой информацией.

2019-10-18

Введение

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

Системные вызовы VFS open(2), stat(2), read(2), write(2), chmod(2) и так далее, вызываются из контекста работающего процесса. Filesystem locking описана в Documentation/filesystems/locking.rst. (VFS system calls open(2), stat(2), read(2), write(2), chmod(2) and so on are called from a process context. Filesystem locking is described in the document Documentation/filesystems/locking.rst.)

Кэш записей каталога / Directory Entry Cache (dcache)

VFS обеспечивает системные вызовы open(2), stat(2), chmod(2) и другие похожие. Аргумент pathname, который передаётся на вход этим системным вызовам, используется VFS-системой для поиска вхождений в кэше записей каталога (называемым также dentry cache, или ещё короче dcache). Это обеспечивает сверхбыстрый механизм трансляции pathname (filename) в определённый dentry. Кэш записей каталога необходим только для увеличения производительности, поэтому он хранится в оперативной памяти и никогда не записывается на диск.

Dentry-кэш предназначен для обзора всего файлового пространства. А так как большинство компьютеров не могут вместить все записи dentry в оперативную память, то некоторое количество записей в dentry-кэше может отсутствовать. Поэтому, иногда в процессе сопоставления частей 'pathname' с соответствующими dentry, VFS-коммутатору, возможно, придётся заодно создать некоторое количество dentry, и только после этого загрузить требуемый inode.

Объект Inode / The Inode Object

Отдельный dentry обычно указывает на inode, который является специальной структурой файловой системы, описывающей её файлы-объекты. Inode предоставляет различные сведения о файле (man 2 stat). В частности:

  • st_devid устройства, содержащего файл;
  • st_ino – номер этой inode в таблице inodes;
  • st_mode – тип объекта (man 7 inode):
    • обычный файл с данными;
    • directory;
    • block device;
    • ...
  • st_nlink – количество жёстких ссылок (имён файлов) на этот inode.

    Inode не содержит имени файла! Так как в пределах одной файловой системы (POSIX) на один файл может ссылаться больше одной именованной жёсткой ссылки, то имя файла не сохраняется в inode. Вместо этого, в файлах-каталогах (тип directory), в списке содержимого данного каталога, создаётся запись: имя файла (то есть имя жёсткой ссылки) — номер inode. Отсюда следует, что при обнулении поля st_nlink в структуре какого-либо inode, соответствующие блоки файловой системы будут помечены свободными и файл можно считать удалённым.

Inodes могут находиться на дисках (на файловых системах блочных устройств), либо в оперативной памяти (на псевдо-файловых системах). Inodes, находящиеся на дисках, при необходимости копируются в оперативную память, а при каких-либо в них изменениях, обновлённая копия записывается обратно на диск. Несколько dentry могут указывать на один inode (в случае жёстких ссылок и тому подобное).

Для поиска какого-либо inode необходимо, чтобы для его родительского inode-каталога, VFS вызвала метод lookup(). Этот метод установлен конкретной реализацией ФС, к которой относится требуемый inode. (This method is installed by the specific filesystem implementation that the inode lives in.) С момента получения VFS-коммутатором dentry (а следовательно и соответствующего inode), мы можем делать с ним всякие скучные вещи, типа открыть файл посредством системного вызова open(2), или получить данные inode через stat(2). Из пользовательского пространства системный вызов stat(2) работает довольно просто: как только VFS заимел соответствующий dentry, он передаёт данные из inode обратно в userspace (The stat(2) operation is fairly simple: once the VFS has the dentry, it peeks at the inode data and passes some of it back to userspace.).

Объект File / The File Object

Открытие какого-либо файла требует ещё одной операции: выделение файловой структуры (это реализация файловых дескрипторов на стороне ядра). Свеже выделенная файловая структура инициализируется с указателем на соответствующий dentry и на набор файловых операций функций-членов. (The freshly allocated file structure is initialized with a pointer to the dentry and a set of file operation member functions.) Они берутся из сведений, содержащихся в соответствующей inode. Применяемый к файлу метод open() вызывается тогда, как только конкретная реализация файловой системы сможет сделать это. Вы можете видеть, что это ещё одна функция выполняемая VFS-коммутатором. Файловая структура помещается в таблицу дескрипторов файлов для вызывающего процесса.

Чтение, запись и закрытие файла (и другие подобные операции VFS) осуществляются с помощью соответствующих методов, перечисленных в подходящей к требуемому файлу файловой структуре, каковая структура становится доступной из пространства пользователя через использование конкретного файлового дескриптора. Dentry остаётся в использовании, пока файл открыт, что, в свою очередь, означает, что VFS inode остаётся в использовании.