Главная » Ядро Linux » Объект dentry

0

Как уже  рассказывалось,  подсистема VFS  представляет  каталоги  так  же,  как   и файлы. В  имени пути   /bin/vi ,  и  элемент bin , и  элемент vi — это  файлы, только bi n  — это   специальный  файл,  который является  каталогом,  a  vi  — это   обычный файл.  Объекты файловых индексов  служат для  представления обоих этих  компонентов.   Несмотря на  такую полезную унификацию,  подсистеме VFS  также необходимо

5   Расширенны е атрибут ы — эт о нова я функциональность , котора я появилас ь в ядр е 2.6 для того , чтобы создавать параметр ы файло в в виде па р имя/значени е по аналогии с базой данных. Эти  параметры поддерживаются  не многими файловым и системами, и к тому же они еще  используются не достаточно  широко .

выполнять операции, специфичные для каталогов, такие  как поиск  компонента пути по его имени, проверка того,  что указанный элемент  пути сущестпует, и переход  на следующий компонент пути.

Для решения этой задачи  в подсистеме VFS реализована концепция элемента каталога (directory  entry или  dentry).  Объект  dentry  — это определенный компонент пути. В предыдущем примере компоненты  /, bi n и vi — это  объекты  элементов каталога. Первые  два— это каталоги, а последний— обычный файл.  Важным  моментом является то, что все объекты  dentry— это компоненты пути,  включая  и обычные  файлы.

Элементы пути также  могут включать  в себя точки  монтирования. В имени  пути

/mnt/cdrom/foo, компоненты /, mnt,  cdrom  и foo — это  все объекты  типа  dentry. Подсистема VFS при  выполнении операций с каталогами по необходимости конструирует  объекты  элементов каталога  на лету.

Объекты   типа  dentry  представлены  с  помощью  структуры   struc t   dentr y  и определены в файле  <linux/dcache.h> . Эта структура  с комментариями, которые определяют назначение каждого  поля,  имеет  следующий вид.

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 создает эти  объекты  на лету  на  основании строкового представления имени пути. Поскольку объекты элементов каталога не  хранятся физически на  дисках, то  в структуре struc t dentr y нет  никаких флагов, которые указывают на то, изменен ли  объект (т.е. должен ли  он быть записан назад на  диск).

Состояние элементов каталога

Действительный объект элемента  каталога,  может быть в одном из трех состояний: используемый  fused), неиспользуемый (unused) и негативный  (negative).

Используемый объект соответствует существующему файловому  индексу (т.е. поле d_inode указывает на связанный объект типа mode) и используется  один или более раз (т.е. значение поля d_count — положительное число). Используемый элемент каталога используется  подсистемой  VFS, а также указывает на существующие данные, поэтому не может быть удален.

Неиспользуемый объект типа dentry соответствует  существующему объекту inode (поле d_inode указывает на объект файлового  индекса),  но подсистема VFS в данный  момент  не использует этот элемент  каталога  (поле  d_count  содержит нулевое значение).  Так как элемент каталога указывает на существующий объект, то он сохраняется на случай, если вдруг окажется нужным. Если объект не ликвидировать преждевременно, то его и не нужно будет создавать заново,  если вдруг он понадобится в будущем, и поиск  по имени  пути пройдет быстрее. Когда же появляется  необходимость освободить  память,  то такой  объект элемента  каталога может быть удален, потому что он никем не используется.

Негативный объект dentry6   не связан с существующим  файловым  индексом  (поле d_inode равно значению  NULL), потому что или файловый  индекс был удален, или соответствующий  элемент  пути никогда не существовал.  Такие  объекты элементов каталогов сохраняются,  чтобы в будущем поиск  по имени  пути проходил быстрее. Хотя такие объекты dentry и полезны,  но они при необходимости  могут уничтожаться, поскольку никто их на самом деле не использует.

может быть освобожден,  оставаясь в слябовом  кэше объектов,  как обсуждалось в предыдущей главе. В таком случае на этот объект нет ссылок ни в коде VFS, ни в коде файловых систем.

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

После того как подсистема VFS преодолела все трудности, связанные  с переводом всех элементов пути в объекты элементов каталогов,  и был достигнут конец пути, то было бы достаточно расточительным  выбрасывать  на ветер всю проделанную  работу. Ядро кэширует объекты в кэше элементов каталога, который называют dcache.

Кэш  объектов dentry состоит из трех частей.

• Список  "используемых" объектов  dentry,  которые  связаны  с определенным файловым  индексом  (поле  i_dentr y объекта inode). Поскольку  указанный  файловый  индекс может иметь несколько  ссылок, то ему может соответсвовать несколько  объектов dentry, а следовательно используется связанный список.

• Двухсвязный  список  неиспользуемых  и негативных  объектов  dentry "с  наиболее поздним  использованием" (last recently used, LRU).  Вставки элементов в этот список отсортированы по времени,  поэтому элементы, которые находятся в начале списка, — самые новые. Когда ядро должно удалить элементы каталогов для освобождения  памяти,  то эти элементы берутся из конца списка.

6   Это  названи е  нескольк о  сбивает  с толку.  В таки х объектах  не т  ничег о  негативног о  ил и  отрицательного.   Более  удачным  было  бы,  наверное ,  название   invalid denlry  или  несуществующий   элемент каталога.

потому что там находятся элементы,  которые использовались наиболее давно и для которых меньше шансов, что они понадобятся в ближайшем будущем.

• Хеш-таблица и хеш-функция,  которые позволяют быстро преобразовать  заданный путь в  объект dentry.

Указанная  хеш-таблица представлена с  помощью массива dentry_hashtable . Каждый элемент массива — это указатель на список тех  объектов dentry, которые соответствуют одному ключу. Размер этого массива зависит от  объема физической памяти в системе.

Значение ключа определяется функцией d_has h () , что позволяет для каждой файловой системы реализовать свою хеш-функцию.

Поиск в хеш-таблице выполняется с помощью функции d_lookup (). Если в кэше dcache найден соответствующий объект, то  это значение возвращается. В  случае ошибки возвращается значение NULL.

В  качестве примера рассмотрим редактирование файла исходного кода в вашем домашнем каталоге,  /home/dracula/src/fоо.с . Каждый раз, когда производится доступ к этому файлу (например, при первом открытии, при последующей записи, при компиляции и так далее), подсистема VFS должна пройти через псе элементы каталогов в соответствии с путем к файлу: /, home, dracula , sr e  и, наконец, foo.с . Для того чтобы каждый раз при доступе к этому (и любому другому) имени пути избежать выполнения  данной  операции,  которая требует довольно больших затрат времени,  подсистема VFS вначале может попытаться найти это имя пути в  dentryкэше. Если поиск проходит успешно, то  необходимый конечный элемент каталога нужного пути получается без  особых усилий. Если же  данного элемента каталога нет в  dentry-кэше, то  подсистема VFS должна самостоятельно отследить путь. После завершения поиска найденные объекты dentry помещаются в   кэш dcache, чтобы ускорить поиск в  будущем.

Кэш dcache также является интерфейсом к кэшу файлопых индексов icache. Объекты inode связаны с  объектами dentry, поскольку объект dentry поддерживает положительное значение счетчика использования для связанного с  ним индекса. Это в  свою очередь позволяет объектам dentry удерживать связанные  с  ними объекты mode в памяти. Иными словами, если закэширован элемент каталога, то  соответственно оказывается закэшированным и соответствующий ему файловый индекс. Следовательно, если поиск в  кэше для некоторого имени пути прошел успешно, то соответствующие файловые индексы уже  закэшированы в  памяти.

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

Структура dentry_operation s  содержит методы,  которые подсистема  VFS может вызывать для элементов каталогов определенной файловой системы. Эта структура определена в  файле <linux/dcache.h > следующим образом.

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 *) ;

};

Методы служат для следующих целей

•  in t  d_revalidate(struc t   dentr y    *dentry ,   in t  flags )

Эта функция определяет, является ли указанный объект элемента каталога действительным. Подсистема VFS вызывает эту функцию, когда она пытается использовать объект dentry из кэша dcache. Для большинства файловых систем этот метод установлен в значение NULL,  потому что объекты denry, которые находятся в кэше, всегда действительны.

• in t  d_hash(struc t  dentr y   *dentry ,  struc t  qst r  *name)

Эта функция создает значение хеш-ключа на основании указанного объекта dentry. Подсистема VFS вызывает эту функцию всякий раз, когда добавляет объект элемента каталога в хеш-таблицу.

• in t   d_compare(struc t  dentr y   *dentry , struc t   qst r    *narael, struc t  qst r    *name2)

Эта функция  вызывается подсистемой VFS для сравнения двух имен файлов namel и name2. Большинство файловых систем используют умолчание VFS, которое соответствует простому сравнению двух строк. Для некоторых файловых систем, таких как FAT, не достаточно простого сравнения строк. Файловая система FAT не чувствительна к регистру символов в именах файлов, поэтому появляется необходимость в реализации функции,  которая при сравнении не учитывает регистр символов. Эта функция вызывается при захваченной блокировке  dcache_lock7 .

• in t  d_delet e   (struc t  dentr y   *dentry )

Эта функция  вызывается подсистемой VFS, когда количество ссылок d_count указанного объекта dentry становится равным пулю. Функция вызывается при захваченной блокировке dcache_lock.

• void  d_release(struc t   dentr y    *dentry )

Эта функция вызывается подсистемой VFS, когда она собирается освободить указанный объект dentry. По умолчанию данная функция не выполняет никаких действий.

• void  d_iput(struc t  dentr y   *dentry ,  struc t  inode  *inode)

Эта функция вызывается подсистемой VFS, когда элемент каталога теряет связь со своим файловым индексом (например, когда этот элемент каталога удаляется с диска). По умолчанию подсистема VFS просто вызывает функцию ipu t (), чтобы освободить соответствующий объект inode. Если файловая система переопределяет эту функцию, то она также должна вызывать функцию  ipu t ()  в дополнение к специфичной для файловой системы работе.

7     А  также   пр и   захваченной    блокировке   dentry->d_lock.  —  Примеч.   перев.

Источник: Лав,  Роберт. Разработка ядра  Linux, 2-е  издание. : Пер.  с англ.  — М.  : ООО  «И.Д.  Вильяме» 2006. — 448 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии