Главная страница
Навигация по странице:

  • Объекты VFS и их структуры данных

  • Другие объекты подсистемы VFS

  • Второе издание


    Скачать 3.09 Mb.
    НазваниеВторое издание
    Дата08.09.2019
    Размер3.09 Mb.
    Формат файлаpdf
    Имя файлаLav_Robert_Razrabotka_yadra_Linux_Litmir.net_264560_original_254.pdf
    ТипДокументы
    #86226
    страница35 из 53
    1   ...   31   32   33   34   35   36   37   38   ...   53
    12
    Виртуальная
    файловая система
    В
    иртуальная файловая система (Virtual File System), иногда называемая виртуаль- ным файловым коммутатором (Virtual File Switch) или просто VFS, — это подси- стема ядра, которая реализует интерфейс пользовательских программ к файловой системе. Все файловые системы зависят от подсистемы VFS, что позволяет не только сосуществовать разным файловым системам, но и совместно функционировать. Это также дает возможность использовать стандартные системные вызовы для чтения и записи данных на различные файловые системы, которые находятся на различных физических носителях, как показано на рис. 12.1,
    Жесткий диск с файловой системой ext3
    Гибкий диск с файловой системой ext2
    Рис. 12.1. Подсистема VFS в действии: использование команды
    ср (1) для копирования данных с жeсткого диска, на котором
    монтируется файловая система, ext3, на гибкий диск, на котором
    монтируется файловая система ext2
    VFS
    CP(1)

    Общий интерфейс к файловым системам
    Подсистема VFS— это связующее звено, которое позволяет таким системным вы- зовам, как open (), read () и write (), работать независимо от файловой системы и физической среды носителя информации. Сегодня это может не впечатлять, по- скольку такая возможность принимается как должное. Тем не менее сделать так, что- бы общие системные вызовы работали для всех поддерживаемых файловых систем и физических сред хранения данных, — задача не тривиальная. Более того, эти систем- ные вызовы позволяют выполнять операции между различными файловыми система- ми и различными физическими носителями — мы можем копировать и перемещать данные с одной файловой системы на другую с помощью стандартных системных вызовов. В старых операционных системах (например, DOS) таких возможностей не было. Любые операции доступа к "неродным" файловым системам требовали исполь- зования специальных утилит. Сейчас такие возможности существуют, потому что все современные операционные системы, включая Linux, абстрагируют доступ к файло- вым системам с помощью виртуального интерфейса, который дает возможность со- вместной работы с данными и обобщенного доступа к данным. В операционной си- стеме Linux может появиться поддержка новых типов файловых систем или новых физических средств хранения данных, при этом нет необходимости переписывать или перекомпилировать существующие программы.
    Уровень обобщенной файловой системы
    Общий интерфейс для всех типов файловых систем возможен только благодаря тому, что в ядре реализован обобщающий уровень, который скрывает низкоуров- невый интерфейс файловых систем. Данный обобщающий уровень позволяет опе- рационной системе Linux поддерживать различные файловые системы, даже если эти файловые системы существенно отличаются друг от друга своими функциями и особенностями работы. Это в свою очередь становится возможным благодаря тому,
    что подсистема VFS реализует общую файловую модель, которая в состоянии пред- ставить общие функции и особенности работы потенциально возможных файловых систем. Конечно, эта модель имеет уклон в сторону файловых систем в стиле Unix
    (что представляют собой файловые системы в стиле Unix, будет рассказано в сле- дующем разделе). Несмотря на это в ОС Linux поддерживается довольно большой диапазон различных файловых систем.
    Обобщенный уровень работает путем определения базовых интерфейсов и струк- тур данных, которые нужны для поддержки всех файловых систем. Код поддержки каждой файловой системы должен формировать все концепции своей работы в со- ответствии с шаблонными требованиями подсистемы VFS, например "так открываем
    файл" , а "так представляем каталог". Код файловой системы скрывает все детали реа- лизации. По отношению к уровню VFS и остальным частям ядра все файловые систе- мы выглядят одинаково, т.е. все файловые системы начинают поддерживать такие объекты, как файлы и каталоги, и такие операции, как создание и удаление файла.
    В результате получается общий уровень абстракции, который позволяет ядру лег- ко и просто поддерживать множество типов файловых систем. Код файловых си- стем программируется таким образом, чтобы поддерживать общие интерфейсы и структуры данных, которые нужны для работы с виртуальной файловой системой.
    266 Глава 12

    В свою очередь, ядро легко может работать со всеми файловыми системами, и соот- ветственно, экспортируемый ядром интерфейс пользователя также позволяет анало- гично работать со всеми файловыми системами.
    В ядре нет необходимости поддерживать низкоуровневые детали реализации файловых систем нигде, кроме кода самих файловых систем. Например, рассмотрим следующую простую программу, работающую в пространстве пользователя.
    write(f, &buf, len);
    Этот системный вызоп записывает len байт из области памяти по адресу &buf в файл, представленный с помощью дескриптора f, начиная с текущей позиции файла.
    Этот системный вызов вначале обрабатывается общей функцией ядра sys_write (),
    которая определяет функцию записи в файл для той файловой системы, на которой находится файл, представленный дескриптором f. Далее общий системный вызов вызывает найденную функцию, которая является частью реализации файловой си- стемы и служит для записи данных на физический носитель (или для других дей- ствий, которые файловая система выполняет при записи файла). На рис. 12.2 показа- на диаграмма выполнения операции записи, начиная от пользовательской функции write () и заканчивая поступлением данных на физический носитель. Далее в этой главе будет показано, как подсистема VFS позволяет достичь необходимой абстрак- ции и какие для этого обеспечиваются интерфейсы.
    Файловые системы Unix
    Исторически так сложилось, что ОС Unix обеспечивает четыре абстракции, свя- занные с файловыми системами: файлы, элементы каталогов (directory entry), индек- сы (inode) и точки монтирования (mount point).
    Файловая система — это иерархическое хранилище данных определенной струк- туры. Файловые системы содержат файлы, каталоги и соответствующую управляю- щую информацию. Обычные операции, которые выполняются с файловыми систе- мами, — это создание (create), удаление (delete) и монтирование (mount). В ОС Unix файловые системы монтируются на определенную точку монтирования в общей ие- рархии
    1
    , которая называется пространством имен (namespace). Это позволяет все фай- ловые системы сделать элементами одной древовидной структуры
    2
    Файл (file) — это упорядоченный поток байтов. Первый байт соответствует нача- лу файла, а последний байт - концу файла. Каждому файлу присваивается удобочита- емое имя, по которому файл идентифицируется как пользователями, так и системой.
    Обычные файловые операции— это чтение (read), запись (write), создание (create)
    и удаление (delete).
    1
    Сейчас в операционной системе Linux эта иерархическая структура является уникальной для каж- дого процесса, т.е. каждый процесс имеет свое пространство имен. По умолчанию каждый процесс наследует пространство имен своего родительского процесса,. поэтому кажется, что существует одно глобальное пространство имен.
    2
    В отличие от указания буквы, которая соответствует определенному диску, например С:. В послед- нем случае пространство имен разбивается на части, которые соответствуют различным устрой- ствам или разделам устройств. Поскольку такое разделение выполняется случайным образом, в качестве представления для пользователя его можно считать не самым идеальным вариантом.
    Виртуальная файловая система 267

    Файлы помещаются в каталогах (directory). Каталог — это аналог папки, которая обычно содержит связанные между собой файлы. Каталоги могут содержать подката- логи. В этой связи каталоги могут быть вложены друг в друга и образуют пути (path).
    Каждый компонент пути называется элементом каталога (directory entry). Пример пути— "/home/wolfman/foo". Корневой каталог "/", каталоги home и wolfman, a также файл f оо — это элементы каталогов, которые называются dentry. В операци- онной системе Unix каталоги представляют собой обычные файлы, которые про- сто содержат список файлов каталога. Так как каталог по отношению к виртуальной файловой системе — это файл, то с каталогами можно выполнять те же операции,
    что и с файлами.
    Unix-подобные операционные системы отличают концепцию файла от любой ин- формации об этом файле (права доступа, размер, владелец, время создания и т.д.).
    Последняя информация иногда называется метаданными файла (file, metadata), т.е. дан- ные о данных, и хранится отдельно от файлов в специальных структурах, которые называются индексами (inode). Это сокращенное название от index node (индексный узел), хотя в наши дни термин "inode" используется значительно чаще.
    Вся указанная информация, а также связанная с ней информация о самой файло- вой системе хранится в суперблоке (superblock). Суперблок— это структура данных,
    которая содержит информацию о файловой системе в целом. Иногда эти общие дан- ные называются метаданными файловой системы. Метаданные файловой системы со- держат информацию об индивидуальных файлах и о файловой системе в целом.
    Традиционно файловые системы ОС Unix реализуют эти понятия как структу- ры данных, которые определенным образом расположены на физических дисках.
    Например, информация о файлах хранится в индексе, в отдельном блоке диска,
    каталоги являются файлами, информация по управлению файловой системой хра- нится централизованно в суперблоке и т.д. Подсистема VFS операционной системы
    Linux рассчитана на работу с файловыми системами, в которых поддерживаются аналогичные концепции. Не Unix-подобные файловые системы, такие как FAT или
    NTFS, также работают в ОС Linux, однако их программный код должен обеспечить наличие аналогичных концепций. Например, если файловая система не поддержи- вает отдельные индексы файлов, то код должен построить в оперативной памяти структуры данных таким образом, чтобы казалось, что такая поддержка работает.
    Если файловая система рассматривает каталоги как объекты специальных типов, для
    VFS каталоги должны представляться как обычные файлы. Часто код не файловых систем не в стиле Unix требует выполнять некоторую дополнительную обработку чтобы уложиться в парадигму Unix и требования VFS. Такие файловые системы так- же поддерживаются, и обычно качество не особенно страдает.
    268 Глава 12
    write()
    Пространство пользователя sys_write()
    Метод записи файловой системы
    VFS
    Файловая система
    Рис, 12.2. Схема прохождения данных из пространства пользователя, где вызывается
    функция wri te (), через общий системный вызов VFS, к специфическому методу за-
    писи файловой системы и, наконец, поступление па физический носитель
    Объекты VFS и их структуры данных
    Виртуальная файловая система (VFS) объектно-ориентированна
    3
    . Общая файло- вая модель представлена набором структур данных. Эти структуры данных очень похожи на объекты. Так как ядро программируется строго на языке С, то, при от- сутствии возможностей прямой поддержки парадигм ООП в языке программирова- ния, структуры данных представляются структурами языка С. Структуры содержат как указатели на элементы данных, так и указатели на функции, которые работают с этими данными.
    Существуют следующие четыре основных типа объектов VFS.
    • Объект суперблок (superblock), который представляет определенную смонтирован- ную файловую систему.
    • Объект файловый индекс (inode), который представляет определенный файл.
    • Объект элемент каталога (denlry), который представляет определенный элемент каталога.
    • Объект файл (file), который представляет открытый файл, связанный с процес- сом.
    Следует обратить внимание, что поскольку подсистема VFS рассматривает катало- ги как обычные файлы, то не существует специальных объектов для каталогов. Как рассказывалось ранее, объект dentry представляет компонент пути, который может содержать обычный файл. Другими словами, deniry — это не то же самое, что ката- лог, а каталог — это то же, что и файл. Все понятно?
    Каждый из рассмотренных основных объектов содержит объект operations (опера-
    ции). Эти объекты описывают методы, которые ядро может применять для основ- ных объектов.
    3
    Часто многие этого не замечают и даже отрицают, но тем не менее в ядре много примеров объ- ектно-ориентированного программирования. Хотя разработчики ядра и сторонятся языка C++ и других явно объектно-ориентированных языков программировании (ООП), иногда очень полезно мыслить в терминах объектов. Подсистема VFS— это хороший пример того, как просто и эффек- тивно объектно-ориентированное программирование реализуется на языке С, в котором нет объ- ектно-ориентированных конструкций.
    Виртуальная файловая система
    269
    Физический носитель

    В частности, существуют следующие объекты операций.
    • Объект super_operations (операции с суперблоком файловой системы) со- держит методы, которые ядро может вызывать для определенной файловой системы, как, например, read_inode () или sync_fs ().
    • Объект i n o d e o p e r a t i o n s (операции с файловыми индексами) содержит ме- тоды, которые ядро может вызывать для определенного файла, как, например,
    c r e a t e d или link ().
    • Объект d e n t r y _ o p e r a t i o n s (операции с элементами каталогов) содержит методы, которые ядро может вызывать для определенного элемента каталога,
    как, например, d_compare () или d_delete ().
    • Объект f ile_operations (операции с файлами) содержит методы, которые про- цесс может вызывать для открытого файла, как например, read () и wri te ().
    Объекты операций реализованы в виде структур, содержащих указатели на функ- ции. Эти функции оперируют объектом, которому принадлежит объект операций.
    Для многих методов объект может унаследовать общую функцию, если для работы достаточно базовой функциональности. В противном случае каждая файловая систе- ма присваивает указателям адреса своих специальных методов.
    И еще раз повторимся, что под объектами мы будем понимать структуры, которые явно не являются объектными типами (в отличие от языков программирования C++
    и Java). Однако эти структуры представляют определенные экземпляры объектов,
    данные связанные с объектами, и методы, которые ими оперируют. Это практиче- ски то же, что и объектные типы.
    Другие объекты подсистемы VFS
    Структуры для VFS — это самая "любимая" вещь, и в этой подсистеме существуют не только рассмотренные структуры, но и еще некоторые. Каждая зарегистрирован- ная файловая система представлена структурой file_system_type, Объекты этого типа описывают файловую систему и ее свойства. Более того, каждая точка монти- рования предстаплена в виде структуры vfsmount. Эта структура содержит инфор- мацию о точке монтирования, такую как ее положение и флаги, с которыми выпол- нена операция монтирования.
    И наконец, каждый процесс имеет три структуры, которые описывают файловую систему и файлы, связанные с процессом. Это структуры f i l e _ s t r u c t , fs_struct и namespace.
    Далее в этой главе будут рассматриваться эти объекты и их роль в функциониро- вании уровня VFS.
    Объект superblock
    Объект суперблок должен быть реализован для каждой файловой системы. Он ис- пользуется для хранения информации, которая описывает определенную файловую систему. Этот объект обычно соответствует суперблоку (superblock) или управляющему
    блоку (control block) файловой системы, который хранится в специальном секторе дис- ка (отсюда и имя объекта). Файловые системы, которые не располагаются на дисках
    270 Глава 12

    (например, файловые системы в виртуальной памяти, как sysfs), генерируют инфор- мацию суперблока "на лету" и хранят в памяти.
    Объект суперблак представляется с помощью структуры s t r u c t super_block, ко- торая определена в файле . Она выглядит следующим образом (ком- ментарии описывают назначение каждого поля).
    Код для создания, управления и ликвидации объектов суперблок находится в фай- ле fs/super.с. Объект суперблок создается и инициализируется в функции alloc_
    super (). Эта функция вызывается при монтировании файловой системы, которая считывает суперблок файловой системы с диска и заполняет поля объекта суперблок.
    Виртуальная файловая система
    271
    struct super_block {
    struct list_head s_list; /* список всех суперблоков */
    dev_t s_dev; /* идентификатор */
    unsigned long s_blocksize; /* размер блока в байтах */
    unsigned long s_old_blocksize; /*старый размер блока в байтах*/
    unsigned char s_blocksize_bits; /* размер блока в битах */
    unsigned char s_dirt; /*флаг того, что суперблок изменен*/
    unsigned long long s_maxbytes; /* максимальный размер файла */
    struct file_system_type *s_type; /* тип файловой системы */
    struct super_operations *s_op; /* операции суперблока */
    struct dquot_operations *dq_op; /* операции с квотами */
    struct quotactl_ops *s_qcop; /* операции управления квотами */
    struct export_operations *s_export_op; /* операции экспортирования */
    unsigned long s_flags; /* флаги монтирования */
    unsigned long s_magic; /* магический номер файловой системы*/
    struct dentry *s_root; /* каталог, точка монтирования */
    struct rw_semaphore s_umount; /* семафор размонтирования */
    struct semaphore s_lock; /* семафор суперблока */
    int s_count; /* счетчик ссылок на суперблок */
    int s_syncing; /*флаг синхронизации файловой системы*/
    int s_nesd_sync_fs; /*флаг того, что файловая система еще не синхронизирована*/
    atomic_t s_active; /* счетчик активных ссыпок */
    void *s_security; /* модуль безопасности */
    struct list_head s_dirty; /* список измененных индексов */
    struct list_head s_io; /*список обратной записи */
    struct hlist_head s_anon; /* анонимные элементы каталога для экспортирования */
    struct list_head s_files; /* список связанных файлов */
    struct block_device *s_bdev; " /* соответствующий драйвер блочного устройства */
    struct list_head s_instances; /* список файловых систем данного типа */
    struct quota_info s_dquot; /* параметры квот */
    char s_id[32]; /* текстовое имя */
    void *s_fs_info; /* специфическая информация файловой системы */
    struct semaphore s_vfs_rename_sem; /* семафор переименования */
    };

    Операции суперблока
    Наиболее важный элемент суперблока — это поле s_op, которое является указа- телем на таблицу операций суперблока. Таблица операций суперблока представле- на с помощью структуры s t r u c t super_operations, которая определена в файле
    . Она выглядит следующим образом.
    struct super_operations {
    struct inode *(*alloc_inode) (struct super_block *sb);
    void (*destroy_inode) (struct inode * ) ;
    void (*read_inode) (struct inode * ) ;
    void (*dirty_inode) (struct inode * ) ;
    void (*write_inode) (struct inode *, int);
    void (*put inode) (struct inode * ) ;
    void (*drop_inode) (struct inode *) ;
    void (*delete_inode) (struct inode * ) ;
    void (*put_super) (struct super_block * ) ;
    void (*write_super) (struct super block * ) ;
    int (*sync_fs) (struct super_block *, int};
    void (*write_super_lockfs) (struct super_block * ) ;
    void (*unlockfs) (struct super_block * ) ;
    int (*statfs) (struct super_block *, struct statfs * } ;
    int (*remount_fs) (struct super_block *, int *, char * ) ;
    void (*clear_inode) (struct inode * ) ;
    void (*umount_begin) (struct super block * ) ;
    int (*show_options) (struct seq_file *, struct vfsmount * ) ;
    };
    Каждое поле этой структуры представляет собой указатель на функцию, которая работает с объектом суперблок. Операции суперблока выполняют низкоуровневые действия с файловой системой и ее файловыми индексами.
    Когда для файловой системы необходимо выполнить операции с суперблоком, то выполняется разыменование указателя на суперблок, и далее получается указатель на необходимый метод. Например, если файловой системе необходимо записать су- перблок, то вызывается следующая функция.
    sb->s_op->write_super(sb);
    где параметр sb — это указатель на суперблок файловой системы. Следуя по указате- лю s_op, получаем таблицу операций суперблока и, наконец, необходимую функцию write_super (), которая вызывается непосредственно. Следует обратить внимание на то, что вызову функции write_super () необходимо передать указатель на супер- блок в качестве параметра, несмотря на то что метод связан с суперблоком. Это про- исходит от того, что язык программирования С не объектно-ориентирован. В C++
    аналогичный вызов может быть выполнен следующим образом.
    sb.write_super();
    В языке С нет простого способа получить указатель на объект, для которого вы- зван метод, поэтому его необходимо передавать явно.
    Рассмотрим операции суперблока, которые описаны в структуре super_opera- tions.
    272 Глава 12

    • s t r u c t inode * a l l o c _ i n o d e ( s t r u c t super_block *sb) — эта функция создает и инициализирует новый объект файлового индекса, связанного с дан- ным суперблоком.
    • void d e s t r o y _ i n o d e ( s t r u c t inode *inode) — эта функция уничтожает дан- ный объект индекса файла.
    • void read_inode ( s t r u c t inode *inode) — эта функция считывает с диска файловый индекс с номером inode->i_ino и заполняет все остальные поля структуры данных индекса.
    • void d i r t y _ i n o d e ( s t r u c t inode *inode) — эта функция вызывается под- системой VFS, когда в индекс вносятся изменения (dirty). Журналируемые фай- ловые системы (как, например, ext3) используют эту функцию для обновления журнала.
    • void w r i t e _ i n o d e ( s t r u c t inode inode*, i n t wait) — эта функция запи- сывает указанный индекс на диск. Параметр wait указывает, должна ли данная операция выполняться синхронно.
    • void put_inode ( s t r u c t inode *inode) — эта функция освобождает указан- ный индекс.
    • void drop_inode ( s t r u c t inode *inode) — эта функция вызывается подси- стемой VFS, когда исчезает последняя ссылка на индекс. Обычные файловые системы Unix никогда не определяют эту функцию, в таком случае подсистема
    VFS просто удаляет индекс. Вызывающий код должен удержипать блокировку inode_lock.
    • void d e l e t e _ i n o d e ( s t r u c t inode *inode) — эта функция удаляет индекс файла с диска.
    • void put_super ( s t r u c t super_block *sb) — эта функция вызывается под- системой VFS при раэмонтировании файловой системы, чтобы освободить ука- занный суперблок.
    • void write_super ( s t r u c t super_block *sb) — эта функция обновляет су- перблок на диске данными из указанного суперблока. Подсистема VFS вызыва- ет эту функцию для синхронизации измененного суперблока в памяти с данны- ми суперблока на диске.
    • i n t sync_fs ( s t r u c t super_block *sb, i n t wait) — эта функция синхро- низирует метаданные файловой системы с данными на диске. Параметр wait указывает, должна ли операция быть синхронной или асинхронной.
    • void write_super_lockfs ( s t r u c t super_block *sb) — эта функция пре- дотвращает изменения файловой системы и затем обновляет данные супербло- ка на диске данными из указанного суперблока. Сейчас она используется дис- петчером логических томов (LVM, Logical Volume Manager).
    • void unlockfs ( s t r u c t super_block *sb) — эта функция разблокирует фай- ловую систему после выполнения функции write_super_lockf s ().
    • int s t a t f s ( s t r u c t super_block *sb, struct s t a t f s *statfs) — эта функ- ция вызывается подсистемой VFS для получения статистики файловой системы,
    Статистика указанной файловой системы записывается в структуру s t a t f s .
    Виртуальная файловая система 273

    • int remount_fs (struct super_block *sb, int *flags, char *data) —эта функция вызывается подсистемой VFS, когда файловая система монтируется с другими параметрами монтирования.
    • void clear_inode (struct inode *) — эта функция вызывается подсистемой
    VFS для освобождения индекса и очистки всех страниц памяти, связанных с индексом.
    • void umount_begin ( s t r u c t super_block *sb) — эта функция вызывается подсистемой VFS для прерывания операции монтирования. Она используется сетевыми файловыми системами, такими как NFS.
    Все рассмотренные функции вызываются подсистемой VFS в контексте процесса.
    Все они при необходимости могут блокироваться.
    Некоторые из этих функций являются необязательными. Файловая система мо- жет установить их значения в структуре операций суперблока равными NULL. Если соответствующий указатель равен NULL, то подсистема VFS или вызывает общий ва- риант функции, или не происходит ничего, в зависимости от операции.
    Объект inode
    Объект inode содержит всю информацию, которая необходима ядру для манипу- ляций с файлами и каталогами. В файловых системах в стиле Unix вся информация просто считывается из дисковых индексов и помещается в объект inode подсисте- мы VFS. Если файловые системы не имеют индексов, то эту информацию необходи- мо получить из других дисковых структур
    4
    Объект индекса файла представляется с помощью структуры s t r u c t inode, ко- торая определена в файле . Эта структура с комментариями, описыва- ющими назначение каждого поля, имеет следующий вид.
    struct inode {
    struct hlist_node i_hash;
    struct list_head i_list;
    struct list_head i_dentry;
    unsigned long i_ino;
    atomic_t i_count;
    umode_t i_mode;
    unsigned int i_nlink;
    uid_t i_uid;
    gid_t i_gid;
    kdev_t i_rdev;
    loff_t i_size;
    struct timespec i_atime;
    struct timespec i_mtime;
    struct timespec i_ctime;
    unsigned int i_blkbits;
    /* хешированный список */
    /* связанный список индексов */
    /* связанный список объектов dentry */
    /* номер индекса */
    /* счетчик ссылок */
    /* права доступа */
    /* количество жестких ссылок */
    /* идентификатор пользователя-владельца */
    /* идентификатор группы-владельца */
    /* связанное устройство */
    /* размер файла в байтах */
    /* время последнего доступа к файлу */
    /* время последнего изменения файла */
    /* время изменения индекса */
    /* размер блока в битах */
    4
    Файловые системы, которые не имеют индексов, обычно хранят необходимую информацию как часть файла. Некоторые современные файловые системы также применяют базы данных для хра- нения метаданных файла. В любом случае объект индекса создается тем способом, который под- ходит для файловой системы.
    274
    Глава 12
    unsigned long i_blksize; /* размер блока в байтах */
    unsigned long i_version; /* номер версии */
    unsigned long i_blocks; /* размер файла в блоках */
    unsigned short i_bytes; /* количество использованных байтов*/
    spinlock_t i_lock; /* блокировка для защиты полей */
    struct rw_semaphore i_alloc_sem /* вложенные блокировки при захваченной i_sem */
    struct semaphore i_sem; /* семафор индекса */
    struct inode_operations *i_op; /* таблица операций с индексом */
    struct file_operations *i_fop; /* файловые операции */
    struct super_block *i_sb; /* связанный суперблок */
    struct file_lock *i_flock; /* список блокировок файлов */
    struct address_space *i_mapping; /* соответствующее адресное пространство */
    struct address_space i_data; /* адресное пространство устройства*/
    struct dquot *i_dquot[MAXQUOTAS]; /* дисковые квоты для индекса*/
    struct list_head i_devices; /* список блочных устройств */
    struct pipe_inode_info *i_pipe; /* информация конвейера */
    struct block_device *i_bdev; /* драйвер блочного устройства */
    unsigned long i_dnotify_mask; /* события каталога */
    struct dnotify_struct *i_dnotify; /* информация о событиях каталога */
    unsigned long i_state; /* флаги состояния */
    unsigned long dirtied_when /* время первого изменения */
    unsigned int i_flags; /* флаги файловой системы */
    unsigned char i_sock; /* сокет или нет? */
    atomic_t i_writecount; /* счетчик использования для записи*/
    void *i_security; /* модуль безопасности */
    __u32 i_generation; /* номер версии индекса */
    union {
    void *generic_ip; /* специфическая информация файловой системы */
    } u;
    };
    Для каждого файла в системе существует представляющий его индекс (хотя объ- ект файлового индекса создается в памяти только тогда, когда к файлу осуществляет- ся доступ). Это справедливо и для специальных файлов, таких как файлы устройств или конвейеры. Следовательно, некоторые из полей структуры s t r u c t inode отно- сятся к этим специальным файлам. Например, поле i_pipe указывает на структуру данных именованного конвейера. Если индекс не относится к именованному конвей- еру, то это поле просто содержит значение NULL. Другие поля, связанные со специ- альными файлами, — это i_devices, i_bdev, i_cdev.
    Может оказаться, что та или иная файловая система не поддерживает тех свойств,
    которые присутствуют в объекте inode. Например, некоторые файловые системы не поддерживают такого атрибута, как время создания файла. В этом случае файло- вая система может реализовать это свойство как угодно. Например, поле i_ctime можно сделать нулевым или равным значению поля i_mtime.
    Виртуальная файловая система
    275

    Операции с файловыми индексами
    Так же как и в случае операций суперблока, важным является поле i n o d e _ o p e - r a t i o n s , в котором описаны функции файловой системы, которые могут быть вы- званы подсистемой VFS для объекта файлового индекса. Как и для суперблока, опе- рации с файловыми индексами могут быть вызваны следующим образом.
    i->i_op->truncate(i
    )
    где переменная i содержит указатель на определенный объект файлового индекса.
    В данном случае для индекса I выполняется операция t r a n c a t e (), которая опреде- лена для файловой системы, в которой находится указанный файловый индекс i.
    Структура i n o d e _ o p e r a t i o n s определена в файле < l i n u x / f s . h > , как показано ниже.
    struct inode_operations {
    int (*create) (struct inode *, struct dentry *,int);
    struct dentry * (*lookup) (struct inode *, struct dentry * ) ;
    int (*link) (struct dentry *, struct inode *, struct dentry * ) ;
    int (*unlink) (struct inode *, struct dentry * ) ;
    int (*symlink) (struct inode *, struct dentry *, const char * ) ;
    int (*mkdir) (struct inode *, struct dentry *, int);
    int (*rmdir) (struct inode *, struct dentry *);
    int (*mknod) (struct inode *, struct dentry *, int, dev_t);
    int (*rename) (struct inode *, struct dentry *,
    struct inode *, struct dentry * ) ;
    int (*readlink) (struct dentry *, char *, int);
    int (*follow_link) (struct dentry *, struct nameidata * ) ;
    int (*put_link) (struct dentry *, struct nameidata * ) ;
    void (*truncate) (struct inode * ) ;
    int (*permission) (struct inode *, int);
    int (*setattr) (struct dentry *, struct iattr * ) ;
    int (*getattr) (struct vfsmount *, struct dentry *, struct kstat * ) ;
    int (*setxattr) (struct dentry *, const char *,
    const void *, size_t, int);
    ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
    ssize_t (*listxattr) (struct dentry *, char *, size_t);
    int (*removexattr) (struct dentry *, const char * ) ;
    };
    Рассмотрим указанные операции более подробно.
    • i n t c r e a t e ( s t r u c t inode * d i r , s t r u c t dentry *dentry, i n t mode)
    Эта функция вызывается подсистемой VFS из системных вызовов c r e a t () и open () для создания нового файлового индекса, который имеет указанный ре- жим доступа (mode) и связан с указанным элементом каталога (dentry).
    • s t r u c t dentry * lookup(struct inode *dir, s t r u c t dentry *dentry)
    Эта функция производит поиск файлового индекса в указанном каталоге.
    Файловый индекс должен соответствовать имени файла, хранящемуся в указан- ном объекте элемента каталога.
    276 Глава 12

    • i n t l i n k ( s t r u c t ctentry *old_dentry, s t r u c t inode * d i r ,
    s t r u c t dentry *dentry)
    Эта функция вызывается из системного вызова l i n k () для создания жесткой ссылки (hard link) на файл, соответствующий элементу каталога old_dentry в каталоге d i r . Новая ссылка должна иметь имя, которое хранится в указанном элементе каталога dentry.
    • i n t u n l i n k ( s t r u c t inode * d i r , s t r u c t dentry *dentry)
    Эта функция вызывается из системного вызова unlink () для удаления файло- вого индекса, соответствующего элементу каталога dentry в каталоге dir.
    • int symlink(struct inode *dir, struct dentry *dentry, const char *symname)
    Эта функция вызывается из системного вызова symlink() для создания сим- вольной ссылки с именем symnarne на файл, которому соответствует элемент каталога dentry в каталоге d i r .
    • i n t m k d i r ( s t r u c t inode * d i r , s t r u c t dentry *dentry, i n t mode)
    Эта функция вызывается из системного вызова mkdir () для создания нового каталога с указанным режимом доступа (mode).
    • i n t r m d i r ( s t r u c t inode * d i r , s t r u c t dentry *dentry)
    Эта функция вызывается из системного вызова rmdir () для удаления каталога на который указывает элемент каталога dentry из каталога dir.
    • int mknod (struct inode *dir, struct dentry *dentry, int mode, dev_t rdev)
    Эта функция вызывается из системного вызова mknod () для создания специаль- ного файла (файла устройства, именованного конвейера или сокета), информа- ция о котором хранится в параметре rdev. Файл должен быть создан в каталоге d i r с именем, указанным в параметре dentry, и режимом доступа mode.
    • i n t rename(struct inode *old_dir, s t r u c t dentry *old_dentry,
    s t r u c t inode *new_dir, s t r u c t dentry *new_dentry)
    Эта функция вызывается подсистемой VFS для перемещения указанного эле- мента каталога old_dentry из каталога old_dir в каталог new_dir с новым именем, указанным в параметре new_dentry.
    • i n t r e a d l i n k ( s t r u c t dentry *dentry, char *buffer, i n t buflen)
    Эта функция вызывается из системного вызова r e a d l i n k () для копирования не более buflen байт полного пути, связанного с символьной ссылкой, соот- ветствующей указанному элементу каталога, в указанный буфер.
    • i n t f o l l o w _ l i n k ( s t r u c t dentry *dentry, s t r u c t nameidata *nd)
    Эта функция вызывается подсистемой VFS для трансляции символьной ссылки в индекс файла, на который эта ссылка указывает. На ссылку указывает указа- тель dentry, а результат сохраняется в структуру nameidata, на которую ука- зывает параметр nd.
    • i n t p u t _ l i n k ( s t r u c t dentry *dentry, s t r u c t nameidata* nd)
    Эта функция вызывается подсистемой VFS после вызова функции followlink ().
    • void truncate (struct inode *inode). Эта функция вызывается подсистемой
    VFS для изменения размера заданного файла. Перед вызовом поле i_size ука- занного индекса файла должно быть установлено в желаемое значение размера.
    Виртуальная файловая система 277

    • i n t permission(struct inode *inode, i n t mask)
    Эта функция проверяет, разрешен ли указанный режим доступа к файлу, на который ссылается объект inode. Функция должна возвращать нулевое значе- ние, если доступ разрешен, и отрицательное значение кода ошибки в против- ном случае. Для большинства файловых систем данное поле устанавливается
    в значение NULL, и при этом используется общий метод VFS, который просто сравнивает биты поля режима доступа файлового индекса с указанной маской.
    Более сложные файловые системы, которые поддерживают списки контроля доступа (ACL), реализуют свой метод permission ().
    • i n t s e t a t t r ( s t r u c t dentry *dentry, s t r u c t i a t t r * a t t r )
    Эта функция вызывается функцией notify_change () для уведомления о том,
    что произошло "событие изменения" ("change event") после модификации ин- декса.
    • i n t g e t a t t r ( s t r u c t vfsmount *mnt, s t r u c t dentry *dentry,
    s t r u c t k s t a t * s t a t )
    Эта функция вызывается подсистемой VFS при уведомлении, что индекс дол- жен быть обновлен с диска.
    • i n t s e t x a t t r ( s t r u c t dentry *dentry, const char *name,
    const void *value, size_t s i z e , i n t flags)
    Эта функция вызывается подсистемой VFS для установки одного из расширен- ных атрибутов (extended attributes)
    5
    с именем name в значение value для фай- ла, соответствующего элементу каталога dentry.
    • i n t g e t x a t t r (struct dentry *dentry, const char *name,
    void *value, size_t size)
    Эта функция вызывается подсистемой VFS для копирования значения одного из расширенных атрибутов (extended attributes) с именем name в область памя- ти с указателем value.
    • ssize_t l i s t x a t t r ( s t r u c t dentry *dentry, char * l i s t , size_t size)
    Эта функция должна копировать список всех атрибутов для указанного файла в буфер, соответствующий параметру l i s t .
    • i n t removexattr(struct dentry *dentry, const char *name)
    Эта функция удаляет указанный атрибут для указанного файла.
    Объект dentry
    Как уже рассказывалось, подсистема VFS представляет каталоги так же, как и файлы. В имени пути / b i n / v i , и элемент b i n , и элемент vi — это файлы, только b i n — это специальный файл, который является каталогом, a vi — это обычный файл. Объекты файловых индексов служат для представления обоих этих компонен- тов. Несмотря на такую полезную унификацию, подсистеме VFS также необходимо
    5
    Расширенные атрибуты — это новая функциональность, которая появилась в ядре 2.6 для того,
    чтобы создавать параметры файлов в виде пар имя/значение по аналогии с базой данных. Эти па- раметры поддерживаются не многими файловыми системами, и к тому же они еще используются не достаточно широко.
    278 Глава 12
    выполнять операции, специфичные для каталогов, такие как поиск компонента пути по его имени, проверка того, что указанный элемент пути сущестпует, и переход на следующий компонент пути.
    Для решения этой задачи в подсистеме VFS реализована концепция элемента ката- лога (directory entry или dentry). Объект dentry — это определенный компонент пути.
    В предыдущем примере компоненты /, bin и vi — это объекты элементов каталога.
    Первые два— это каталоги, а последний— обычный файл. Важным моментом являет- ся то, что все объекты dentry— это компоненты пути, включая и обычные файлы.
    Элементы пути также могут включать в себя точки монтирования. В имени пути
    /mnt/cdrom/foo, компоненты /, mnt, cdrom и foo — это все объекты типа dentry.
    Подсистема VFS при выполнении операций с каталогами по необходимости констру- ирует объекты элементов каталога на лету.
    Объекты типа dentry представлены с помощью структуры s t r u c t d e n t r y и определены в файле . Эта структура с комментариями, которые определяют назначение каждого поля, имеет следующий вид.
    struct dentry {
    atomic_t d_count; /* счетчик использования */
    unsigned long d_vfs_flags; /* флаги кэша объектов dentry */
    spinlock_t d_lock; /* блокировка данного объекта dentry */
    struct inode *d_inode; /* соответствующий файловый индекс */
    struct list_head d_lru; /* список неиспользованных объектов */
    struct list_head d_child; /* список объектов у родительского экземпляра */
    struct list_head d_subdirs; /* подкаталоги */
    struct list_head d_alias; /* список альтернативных (alias)
    индексов */
    unsigned long d_time; /* время проверки правильности */
    struct dentry_operations *d_op; /* таблица операций с элементом каталога */
    struct super_block *d_sb; /* связанный суперблок */
    unsigned int d_flags; /* флаги элемента каталога */
    int d_mounted; /* является ли объект точкой монтирования */
    void *d_fsdata; /* специфические данные файловой системы */
    struct rcu_head d_rcu; /* блокировки RCU (read-copy update) */
    struct dcookie_struct *d_cookie; /* cookie-идентификатор */
    struct dentry *d_parent; /* объект dentry родительского каталога */
    struct qstr d_name; /* имя dentry */
    struct hlist_node d_hash; /* список хеширования */
    struct hlist_head *d_bucket; /* сегмент хеш-таблицы */
    unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /*короткое имя файла */
    };
    В отличие от предыдущих двух объектов, объект dentry не соответствует какой бы то ни было структуре данных на жестком диске. Подсистема VSF создает эти объек- ты на лету на основании строкового представления имени пути. Поскольку объекты элементов каталога не хранятся физически на дисках, то в структуре s t r u c t dentry нет никаких флагов, которые указывают на то, изменен ли объект (т.е. должен ли он быть записан назад на диск).
    Виртуальная файловая система
    279

    1   ...   31   32   33   34   35   36   37   38   ...   53


    написать администратору сайта