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

  • Кэш объектов dentry

  • Операции с элементами каталогов

  • 2 8 2 Глава 12

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


    Скачать 3.09 Mb.
    НазваниеВторое издание
    Дата08.09.2019
    Размер3.09 Mb.
    Формат файлаpdf
    Имя файлаLav_Robert_Razrabotka_yadra_Linux_Litmir.net_264560_original_254.pdf
    ТипДокументы
    #86226
    страница36 из 53
    1   ...   32   33   34   35   36   37   38   39   ...   53
    Состояние элементов каталога
    Действительный объект элемента каталога, может быть в одном из трех состоя- ний: используемый fused), неиспользуемый (unused) и негативный (negative).
    Используемый объект соответствует существующему файловому индексу (т.е. поле d_inode указывает на связанный объект типа mode) и используется один или более раз (т.е. значение поля d_count — положительное число). Используемый элемент ка- талога используется подсистемой VFS, а также указывает на существующие данные,
    поэтому не может быть удален.
    Неиспользуемый объект типа dentry соответствует существующему объекту inode
    (поле d_inode указывает на объект файлового индекса), но подсистема VFS в дан- ный момент не использует этот элемент каталога (поле d_count содержит нулевое значение). Так как элемент каталога указывает на существующий объект, то он сохра- няется на случай, если вдруг окажется нужным. Если объект не ликвидировать преж- девременно, то его и не нужно будет создавать заново, если вдруг он понадобится в будущем, и поиск по имени пути пройдет быстрее. Когда же появляется необхо- димость освободить память, то такой объект элемента каталога может быть удален,
    потому что он никем не используется.
    Негативный объект dentry
    6
    не связан с существующим файловым индексом (поле d_inode равно значению NULL), потому что или файловый индекс был удален, или соответствующий элемент пути никогда не существовал. Такие объекты элементов каталогов сохраняются, чтобы в будущем поиск по имени пути проходил быстрее.
    Хотя такие объекты dentry и полезны, но они при необходимости могут уничтожать- ся, поскольку никто их на самом деле не использует.
    Объект dentry может быть освобожден, оставаясь в слябовом кэше объектов, как обсуждалось в предыдущей главе. В таком случае на этот объект нет ссылок ни в коде
    VFS, ни в коде файловых систем.
    Кэш объектов dentry
    После того как подсистема VFS преодолела все трудности, связанные с переводом всех элементов пути в объекты элементов каталогов, и был достигнут конец пути, то было бы достаточно расточительным выбрасывать на ветер всю проделанную рабо- ту. Ядро кэширует объекты в кэше элементов каталога, который называют dcache.
    Кэш объектов dentry состоит из трех частей.
    • Список "используемых" объектов dentry, которые связаны с определенным файловым индексом (поле i _ d e n t r y объекта inode). Поскольку указанный файловый индекс может иметь несколько ссылок, то ему может соответсвовать несколько объектов dentry, а следовательно используется связанный список.
    • Двухсвязный список неиспользуемых и негативных объектов dentry "с наи- более поздним использованием" (last recently used, LRU). Вставки элементов в этот список отсортированы по времени, поэтому элементы, которые нахо- дятся в начале списка, — самые новые. Когда ядро должно удалить элементы каталогов для освобождения памяти, то эти элементы берутся из конца списка.
    6
    Это название несколько сбивает с толку. В таких объектах нет ничего негативного или отрица- тельного. Более удачным было бы, наверное, название invalid denlry или несуществующий элемент каталога.
    280 Глава 12
    потому что там находятся элементы, которые использовались наиболее давно и для которых меньше шансов, что они понадобятся в ближайшем будущем.
    • Хеш-таблица и хеш-функция, которые позволяют быстро преобразовать задан- ный путь в объект dentry.
    Указанная хеш-таблица представлена с помощью массива d e n t r y _ h a s h t a b l e .
    Каждый элемент массива — это указатель на список тех объектов dentry, которые соответствуют одному ключу. Размер этого массива зависит от объема физической памяти в системе.
    Значение ключа определяется функцией d_hash (), что позволяет для каждой файловой системы реализовать свою хеш-функцию.
    Поиск в хеш-таблице выполняется с помощью функции d_lookup (). Если в кэше dcache найден соответствующий объект, то это значение возвращается. В случае ошибки возвращается значение NULL.
    В качестве примера рассмотрим редактирование файла исходного кода в вашем домашнем каталоге, / h o m e / d r a c u l a / s r c / f о о . с . Каждый раз, когда производится доступ к этому файлу (например, при первом открытии, при последующей записи,
    при компиляции и так далее), подсистема VFS должна пройти через псе элементы каталогов в соответствии с путем к файлу: /, home, dracula, s r e и, наконец, foo.с.
    Для того чтобы каждый раз при доступе к этому (и любому другому) имени пути из- бежать выполнения данной операции, которая требует довольно больших затрат времени, подсистема VFS вначале может попытаться найти это имя пути в dentry- кэше. Если поиск проходит успешно, то необходимый конечный элемент каталога нужного пути получается без особых усилий. Если же данного элемента каталога нет в dentry-кэше, то подсистема VFS должна самостоятельно отследить путь. После за- вершения поиска найденные объекты dentry помещаются в кэш dcache, чтобы уско- рить поиск в будущем.
    Кэш dcache также является интерфейсом к кэшу файлопых индексов icache.
    Объекты inode связаны с объектами dentry, поскольку объект dentry поддерживает положительное значение счетчика использования для связанного с ним индекса.
    Это в свою очередь позволяет объектам dentry удерживать связанные с ними объ- екты mode в памяти. Иными словами, если закэширован элемент каталога, то соот- ветственно оказывается закэшированным и соответствующий ему файловый индекс.
    Следовательно, если поиск в кэше для некоторого имени пути прошел успешно, то соответствующие файловые индексы уже закэшированы в памяти.
    Операции с элементами каталогов
    Структура d e n t r y _ o p e r a t i o n s содержит методы, которые подсистема VFS мо- жет вызывать для элементов каталогов определенной файловой системы. Эта струк- тура определена в файле следующим образом.
    struct dentry_operations {
    int (*d_revalidate) (struct dentry *, int);
    int (*d_hash) (struct dentry *, struct qstr * ) ;
    int (*d_corapare) (struct dentry *, struct qstr *, struct qstr * ) ;
    int (*d_delete) (struct dentry * ) ;
    void (*d_release) (struct dentry * ) ;
    void (*d_iput) (struct dentry *, struct inode * ) ;
    };
    Виртуальная файловая система 281

    Методы служат для следующих целей
    • i n t d _ r e v a l i d a t e ( s t r u c t dentry *dentry, i n t flags)
    Эта функция определяет, является ли указанный объект элемента каталога дей- ствительным. Подсистема VFS вызывает эту функцию, когда она пытается ис- пользовать объект dentry из кэша dcache. Для большинства файловых систем этот метод установлен в значение NULL, потому что объекты denry, которые находятся в кэше, всегда действительны.
    • i n t d_hash(struct dentry *dentry, s t r u c t q s t r *name)
    Эта функция создает значение хеш-ключа на основании указанного объекта dentry. Подсистема VFS вызывает эту функцию всякий раз, когда добавляет объ- ект элемента каталога в хеш-таблицу.
    • i n t d_compare(struct dentry *dentry,
    s t r u c t q s t r *narael,
    s t r u c t q s t r *name2)
    Эта функция вызывается подсистемой VFS для сравнения двух имен файлов namel и name2. Большинство файловых систем используют умолчание VFS,
    которое соответствует простому сравнению двух строк. Для некоторых файло- вых систем, таких как FAT, не достаточно простого сравнения строк. Файловая система FAT не чувствительна к регистру символов в именах файлов, поэтому появляется необходимость в реализации функции, которая при сравнении не учитывает регистр символов. Эта функция вызывается при захваченной блоки- ровке dcache_lock
    7
    • i n t d_delete ( s t r u c t dentry *dentry)
    Эта функция вызывается подсистемой VFS, когда количество ссылок d_count указанного объекта dentry становится равным пулю. Функция вызывается при захваченной блокировке dcache_lock.
    • void d _ r e l e a s e ( s t r u c t dentry *dentry)
    Эта функция вызывается подсистемой VFS, когда она собирается освободить указанный объект dentry. По умолчанию данная функция не выполняет ника- ких действий.
    • void d _ i p u t ( s t r u c t dentry *dentry, s t r u c t inode *inode)
    Эта функция вызывается подсистемой VFS, когда элемент каталога теряет связь со своим файловым индексом (например, когда этот элемент каталога удаляет- ся с диска). По умолчанию подсистема VFS просто вызывает функцию i p u t (),
    чтобы освободить соответствующий объект inode. Если файловая система пе- реопределяет эту функцию, то она также должна вызывать функцию i p u t () в дополнение к специфичной для файловой системы работе.
    7
    А также при захваченной блокировке dentry->d_lock. — Примеч. перев.
    2 8 2 Глава 12

    Объект file
    Последним из основных объектов подсистемы VFS рассмотрим объект файла.
    Объект File используется для представления файлов, которые открыты процессом.
    Когда мы думаем о подсистеме VFS с точки зрения пространства пользователя, то объект файла — это то, что первое приходит в голову. Процессы непосредственно работают с файлами, а не с суперблоками, индексами или элементами каталогов. Не удивительно, что информация, которая содержится в объекте file, наиболее привыч- на (такие данные, как режим доступа или текущее смещение), а файловые операции очень похожи на знакомые системные вызовы, такие как read () и w r i t e ().
    Объект файла — это представление открытого файла, которое хранится в опе- ративной памяти. Объект (а не сам файл) создается в ответ на системный вызов open () и уничтожается в результате системного вызова c l o s e () . Все вызовы, свя- занные с файлом, на самом деле являются методами, которые определены в таблице операций с файлом. Так как несколько процессов могут одновременно открыть и ис- пользовать один и тот же файл, то для одного файла может существовать несколько объектов file. Файловый объект просто представляет открытый файл с точки зрения процесса. Этот объект содержит указатель на соответствующий элемент каталога (ко- торый, в свою очередь, указывает на файловый индекс), представляющий открытый файл. Соответствующие объекты inode и dentry, конечно, являются уникальными.
    Файловый объект представляется с помощью структуры s t r u c t f i l e , которая определена в файле . Рассмотрим поля этой структуры с комментари- ями, которые описывают назначение каждого поля.
    struct file {
    struct list_head f_list; /* список объектов file*/
    struct dentry *f_dentry; /* связанный объект dentry */
    struct vfsmount *f_vfsmnt; /* связанная смонтированная файловая система */
    struct file_operations *f_op; /* таблица файловых операций */
    atomic_t f_count; /* счетчик ссылок на этот объект */
    unsigned int f_flags; /* флаги, указанные при вызове функции open */
    mode_t f_mode; /* режим доступа к файлу */
    loff_t f_pos; /* смещение в файле (file pointer, offset) */
    struct fown_struct f_owner; /* информация о владельце для обработки сигналов */
    unsigned int f_uid; /* идентификатор пользователя владельца, UID */
    unsigned int f_gid; /* идентификатор группы владельца, GID */
    int f_error; /* код ошибки */
    struct file_ra_state f_ra; /* состояние предварительного считывания */
    unsigned long f_version; /* номер версии */
    void *f_security; /* модуль безопасности */
    void *private_data; /* привязка для драйвера терминала */
    struct list_head f_ep_links; /* список ссылок eventpoll (опрос событий) */
    spinlock_t f_ep_lock; /* блокировка eventpoll */
    struct address_space *f_mapping; /* отображение в страничном кэше */
    };
    Виртуальная файловая система
    233

    По аналогии с объектом элемента каталога объект файла на самом деле не соот- ветствует никакой структуре, которая хранится на жестком диске. Поэтому в этой структуре нет никакого флага, который бы указывал, что объект изменен (dirty) и требует обратной записи на диск. Объект file указывает на связанный с ним объект dentry с помощью указателя f_dentry. Объект dentry в свою очередь содержит ука- затель на связанный с ним индекс файла, который содержит информацию о том,
    изменен ли файл.
    Файловые операции
    Как и для других объектоп подсистемы VFS, таблица файловых операций являет- ся важной структурой. Операции, связанные со структурой s t r u c t file, — это зна- комые системные вызовы, составляющие основу системных вызовов ОС Unix.
    Методы работы с файловым объектом хранятся в структуре file_operations и определены в файле следующим образом.
    struct file_operations {
    struct module *owner;
    loff_t (*llseek) (struct file *, loff_t, int);
    ssize_t (*read) (struct file *, char *, size_t, loff_t *);
    ssize_t (*aio_read) (struct kiocb *, char *, size_t, loff_t);
    ssize_t (*write) (struct file *, const char *, size_t, loff_t * ) ;
    ssize_t (*aio_write) (struct kiocb *, const char *, size_t, loff_t);
    int (*readdir) (struct file *, void *, filldir_t);
    unsigned int (*poll) (struct file *, struct poll_table_struct * ) ;
    int (*ioctl) (struct inode *, struct file *,
    unsigned int, unsigned long);
    int (*mmap) (struct file *, struct vm_area_struct * ) ;
    int (*open) (struct inode *, struct file * ) ;
    int (*flush) (struct file * ) ;
    int (*release) (struct inode *, struct file * ) ;
    int (*fsync) (struct file *, struct dentry *, int);
    int (*aio_fsync) (struct kiocb *, int);
    int (*fasync) (int, struct file *, int);
    int (*lock) (struct file *, int, struct file_lock * ) ;
    ssize_t (*readv) (struct file *, const struct iovec *,
    unsigned long, loff_t * ) ;
    ssize_t (*writev) (struct file *, const struct iovec *,
    unsigned long, loff_t * ) ;
    ssize_t (*sendfile) (struct file *, loff_t *, size_t,
    read_actor_t, void * ) ;
    ssize_t (*sendpage) (struct file *, struct page *, int,
    size_t, loff_t *, int);
    unsigned long (*get_unmapped_area) (struct file *, unsigned long,
    unsigned long, unsigned long,
    unsigned long);
    int (*check_flags) (int flags);
    int (*dir_notify) (struct file *filp, unsigned long arg);
    int (*flock) (struct file *filp, int cmd, struct file_lock *fl);
    };
    284 Глава 12

    Файловые системы могут реализовать уникальную функцию для каждой из этих операций или использовать общий существующий метод. Общие методы нормально работают для обычных Unix-подобных файловых систем. Разработчики файловых систем не обязаны реализовать все эти функции, хотя основные методы должны быть реализованы. Если какой-либо метод не представляет интереса, то его можно установить в значение NULL.
    Рассмотрим каждую операцию подробнее.
    • loff_t llseek(struct file *file, loff_t offset, int origin)
    Эта функция устанавливает значения указателя текущей позиции в файле (file pointer) в заданное значение параметра offset. Функция вызывается из си- стемного вызова lseek().
    • ssize_t read(struct f i l e * f i l e ,
    char *buf, size_t count,
    loff_t *offset)
    Эта функция считывает count байт данных из указанного файла, начиная с позиции, заданной параметром offset, в буфер памяти, на который указы- вает параметр buf. После этого значение указателя текущей позиции в файле должно быть обновлено. Данная функция вызывается из системного вызова read().
    • ssize_t aio_read(struct kiocb *iocb,
    char *buf, size_t count,
    loff_t offset)
    Эта функция запускает асинхронную операцию считывания count байт данных из файла, который описывается параметром iocb, в буфер памяти, описанный параметром buf. Эта функция вызывается из системного вызова aio_read ().
    • ssize_t w r i t e ( s t r u c t f i l e * f i l e ,
    const char *buf, size_t count,
    loff_t *offset)
    Эта функция записывает count байт данных в указанный файл, начиная с по- зиции offset. Данная функция вызывается из системного вызова write ().
    • ssize_t aio_write(struct kiocb *iocb,
    const char *buf,
    size_t count, loff_t offset)
    Эта функция запускает асинхронную операцию записи count байт данных в файл, описываемый параметром iocb, из буфера памяти, на который указывает параметр buf. Данная функция вызывается из системного вызова aio_write.
    • i n t r e a d d i r ( s t r u c t f i l e * f i l e , void *dirent, f i l l d i r _ t f i l l d i r )
    Эта функция возвращает следующий элемент из списка содержимого каталога.
    Данная функция вызывается из системного вызова readdir ().
    • unsigned int p o l l ( s t r u c t f i l e * f i l e ,
    struct poll_table_struct *poll_table)
    Эта функция переводит вызывающий процесс в состояние ожидания для ожи- дания действий, которые производятся с указанным файлом. Она вызывается из системного вызова p o l l ( ) .
    Виртуальная файловая система 285

    • int ioctl(struct inode *inode,
    struct file *file,
    unsigned int cmd,
    signed long arg)
    Эта функция используется для того, чтобы отправлять устройствам пары зна- чений команда/аргумент. Функция используется, когда открытый файл— это специальный файл устройства. Данная функция вызывается из системного вы- зова i o c t l ( ) .
    • i n t mmap(struct f i l e * f i l e , s t r u c t vra_area_struct *vma)
    Эта функция отображает указанный файл на область памяти в указанном адрес- ном пространстве и вызывается из системного вызова mmap().
    • i n t open(struct inode *inode, s t r u c t f i l e * f i l e )
    Эта функция создает новый файловый объект и связывает его с указанным файловым индексом. Она вызывается из системного вызова open ().
    • int flush(struct f i l e *file)
    Эта функция вызывается подсистемой VFS, когда уменьшается счетчик ссылок на открытый файл. Назначение данной функции зависит от файловой системы.
    • int r e l e a s e ( s t r u c t inode *inode, s t r u c t f i l e *file)
    Эта функция вызывается подсистемой VFS, когда исчезает последняя ссылка на файл, например, когда последний процесс, который использовал соответству- ющий файловый дескриптор, вызывает функцию c l o s e () или завершается.
    Назначение этой функции также зависит от файловой системы.
    • i n t f s y n c ( s t r u c t f i l e * f i l e ,
    s t r u c t dentry *dentry,
    i n t datasync)
    Эта функция вызывается из системного вызова fsync() для записи на диск всех закэшированных данных файла.
    • i n t aio_fsync(struct kiocb *iocb, i n t datasync)
    Эта функция вызывается из системного вызова a i o f sync () для записи на диск всех закэшированных данных файла, связанного с параметром iocb.
    • i n t fasyn (fint fd, s t r u c t f i l e * f i l e , i n t on)
    Эта функция разрешает или запрещает отправку сигнала для уведомлении о со- бытиях при асинхронном вводе-выводе.
    • i n t l o c k ( s t r u c t f i l e * f i l e , i n t cmd, s t r u c t file_lock *lock)
    Эта функция управляет файловыми блокировками для данного файла.
    • s s i z e _ t r e a d v ( s t r u c t f i l e * f i l e ,
    const s t r u c t iovec *vector,
    unsigned long count,
    loff_t *offset)
    Эта функция вызывается из системного вызова readv () для считывания дан- ных из указанного файла в count буферов, которые описываются параметром vector. После этого указатель текущей позиции файла должен быть соответ- ственным образом увеличен.
    1   ...   32   33   34   35   36   37   38   39   ...   53


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