Состояние элементов каталога
Действительный объект элемента каталога, может быть в одном из трех состояний: используемый (used), неиспользуемый (unused) и негативный (negative).
Используемый объект соответствует существующему файловому индексу (т.е. поле d_inodeуказывает на связанный объект типа mode) и используется один или более раз (т.е. значение поля d_count— положительное число). Используемый элемент каталога используется подсистемой VFS, а также указывает на существующие данные, поэтому не может быть удален.
Неиспользуемый объект типа dentry соответствует существующему объекту inode (поле d_inodeуказывает на объект файлового индекса), но подсистема VFS в данный момент не использует этот элемент каталога (поле d_countсодержит нулевое значение). Так как элемент каталога указывает на существующий объект, то он сохраняется на случай, если вдруг окажется нужным. Если объект не ликвидировать преждевременно, то его и не нужно будет создавать заново, если вдруг он понадобится в будущем, и поиск по имени пути пройдет быстрее. Когда же появляется необходимость освободить память, то такой объект элемента каталога может быть удален, потому что он никем не используется.
Негативный объект dentry [72] Это название несколько сбивает с толку. В таких объектах нет ничего негативного или отрицательного. Более удачным было бы, наверное, название invalid dentry или несуществующий элемент каталога.
не связан с существующим файловым индексом (поле d_inodeравно значению NULL), потому что или файловый индекс был удален, или соответствующий элемент пути никогда не существовал. Такие объекты элементов каталогов сохраняются, чтобы в будущем поиск по имени пути проходил быстрее. Хотя такие объекты dentry и полезны, но они при необходимости могут уничтожаться, поскольку никто их на самом деле не использует.
Объект dentry может быть освобожден, оставаясь в слябовом кэше объектов, как обсуждалось в предыдущей главе. В таком случае на этот объект нет ссылок ни в коде VFS, ни в коде файловых систем.
После того как подсистема VFS преодолела все трудности, связанные с переводом всех элементов пути в объекты элементов каталогов, и был достигнут конец пути, то было бы достаточно расточительным выбрасывать на ветер всю проделанную работу. Ядро кэширует объекты в кэше элементов каталога, который называют dcache .
Кэш объектов dentry состоит из трех частей.
• Список "используемых" объектов dentry, которые связаны с определенным файловым индексом (поле i_dentryобъекта inode). Поскольку указанный файловый индекс может иметь несколько ссылок, то ему может соответствовать несколько объектов dentry, а следовательно используется связанный список.
• Двухсвязный список неиспользуемых и негативных объектов dentry "с наиболее поздним использованием" (last recently used, LRU). Вставки элементов в этот список отсортированы по времени, поэтому элементы, которые находятся в начале списка, — самые новые. Когда ядро должно удалить элементы каталогов для освобождения памяти, то эти элементы берутся из конца списка, потому что там находятся элементы, которые использовались наиболее давно и для которых меньше шансов, что они понадобятся в ближайшем будущем.
• Хеш-таблица и хеш-функция, которые позволяют быстро преобразовать заданный путь в объект dentry.
Указанная хеш-таблица представлена с помощью массива dentry_hashtable. Каждый элемент массива — это указатель на список тех объектов dentry, которые соответствуют одному ключу. Размер этого массива зависит от объема физической памяти в системе.
Значение ключа определяется функцией d_hash(), что позволяет для каждой файловой системы реализовать свою хеш-функцию.
Поиск в хеш-таблице выполняется с помощью функции d_lookup(). Если в кэше dcache найден соответствующий объект, то это значение возвращается. В случае ошибки возвращается значение NULL.
В качестве примера рассмотрим редактирование файла исходного кода в вашем домашнем каталоге, /home/dracula/src/fоо.с. Каждый раз, когда производится доступ к этому файлу (например, при первом открытии, при последующей записи, при компиляции и так далее), подсистема VFS должна пройти через псе элементы каталогов в соответствии с путем к файлу: /, home, dracula, srcи, наконец, foo.c. Для того чтобы каждый раз при доступе к этому (и любому другому) имени пути избежать выполнения данной операции, которая требует довольно больших затрат времени, подсистема VFS вначале может попытаться найти это имя пути в dentry-кэше. Если поиск проходит успешно, то необходимый конечный элемент каталога нужного пути получается без особых усилий. Если же данного элемента каталога нет в dentry-кэше, то подсистема VFS должна самостоятельно отследить путь. После завершения поиска найденные объекты dentry помещаются в кэш dcache, чтобы ускорить поиск в будущем.
Читать дальше