LINUX.ORG.RU

Чтение файла ядром

 , ,


0

1

Добрый день,

пытаюсь разобраться как работает чтение файлов в ядре. Рассмотрим функицию do_generic_file_read. В этой функции есть большой цикл, в котором данные читаются постранично. Допустим, что страницы не в кеше, поэтому здесь функция вернет NULL. Далее предположим, что readahead тоже не прочитал страницу, поэтому будет осуществлен переход на эту строку. Тут создастся новая страница, а потом вызовется функция add_to_page_cache_lru.

Вот что делает add_to_page_cache_lru я как раз и не могу понять. Сначала она вызывает add_to_page_cache, которая добавляет в адресное пространство файла созданную страницу. При чем я не вижу тут связи между тем, что функция делает и ее именем.

Потом я не понимаю работу функции lru_cache_add_file. Как я понимаю, она добавляет страницу в локальный для процессора pagevec и потом, когда pagevec заполняется, она перемещает страницы в глобальный список, отдельный для каждой зоны. Когда страницы из pagevec перемещены в список зоны, он очищается функцией release_pages.

Объясните, пожалуйста, зачем добавлять только что созданные страницы в LRU и зачем их все потом очищать. Причем, когда страница добавляется в page cache, вызывается функция radix_tree_insert(&mapping->page_tree, offset, page), а когда вызывается release_pages страницы, если освобождаются сохранются в структурах buddy allocator, локальных для зоны, но при этом radix_tree_insert(&mapping->page_tree) никогда не вызывается. Почему?

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

Они не очищаются. В момент попадания в release_pages(), refcount у каждой из этих страниц инкрементирован как минимум дважды: в add_to_page_cache_locked() и в __lru_cache_add() функцией page_cache_get().

Однократное put_page_testzero() в release_pages() не приводит к его обнулению, поэтому никакой очистки не выполняется.

ttnl ★★★★★ ()
Ответ на: комментарий от ttnl

Правильно ли я понимаю, что счетчик должен быть инкрементирован минимум трижды? Два раза в add_to_page_cache_lru. И один раз подсистемой, которая инициировала создание файловой системы, например ext2.

Меня на эту мысль навело то, что в функции ext2_inode_by_name в конце уменьшается счетчик страниц.

DesertFox ()
Ответ на: комментарий от DesertFox

Правильно ли я понимаю, что счетчик должен быть инкрементирован минимум трижды? Два раза в add_to_page_cache_lru. И один раз подсистемой, которая инициировала создание файловой системы, например ext2.

Я не могу гарантировать, поскольку не являюсь специалистом по fs.

Общий принцип в ядре — когда подсистема чем-то пользуется, то инкрементирует refcount, а когда перестает пользоваться, то декрементирует.

Если refcount равен 0, то обычно объект особождается.

ttnl ★★★★★ ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.