Linux Kernel (Ядро линукса) (часть 3)

Буферы блоков и головы буферов

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

Два поля головы буфера кодируют адрес блока на диске: поле b bdev идентифицирует блочное устройство (обычно диск или раздел), содержащее блок а поле b biocknr хранит логический номер блока, т. е. индекс блока внутри диска или раздела.

Поле b data задает позицию буфера блока внутри страницы буферов. Фактически кодирование этой позиции зависит от того, находится ли страница в верхней памяти. Если находится, поле b data содержит смещение буфера блока от начала страницы; в противном случае в этом поле хранится линейный адрес буфера блока.

Поле b state может хранить несколько флагов. Кроме того, любая файловая система может определить собственные флаги головы буфера.

Работа с головами буферов

Головы буферов имеют собственный кэш slab-аллокатора, дескриптор которого kmem cache s хранится В переменной bh cachep. Функции alloc_buffer_ head о и f ree buf fer head используются, соответственно, для выделения и освобождения головы буфера.

Поле b count головы буфера является счетчиком обращений для соответствующего буфера блока. Счетчик увеличивается непосредственно перед каждой операцией над буфером блока и уменьшается сразу после нее. Буферы блоков, хранящиеся в кэше страниц, просматриваются периодически, а также при нехватке памяти, и только буферы с нулевыми счетчиками обращений могут быть утилизированы.

Когда управляющий тракт ядра захочет обратиться к буферу блока, он будет должен вначале увеличить счетчик обращений. Функция, которая находит блок внутри кэша страниц ( getbiko, см. разд. «Поиск блоков в кэше страниц» далее в этой главе), делает это автоматически. Поэтому функции высокого уровня, как правило, не увеличивают счетчик обращений буфера блока.

Когда управляющий поток ядра прекращает работу с буфером блока, он должен вызвать либо breiseo, либо bforgeto, чтобы уменьшить счетчик обращений. Разница между этими двумя функциями заключается в том, что bforget , кроме всего прочего, удаляет блок из всех списков косвенных блоков (поле b assoc buffers головы буфера) и помечает буфер как «чистый», заставляя ядро забыть про все изменения в буфере, который еще должен быть записан на диск.

Страницы буферов

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

  • при чтении и записи страниц файла, которые хранятся не в смежных блоках диска. Это происходит либо потому, что файловая система разместила файл не в смежных блоках, либо потому, что файл содержит «дыры»;
  • при обращении к одному блоку на диске (например, при чтении суперблока или блока индексного дескриптора).

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

Во втором случае дескриптор страницы буферов вставляется в базисное дерево, корень которого находится в объекте address space индексного дескриптора в специальной файловой системе bdev, ассоциированной с блочным устройством. Страницы буферов этого типа должны удовлетворять строгому ограничению: все буферы блоков относятся к смежным блокам блочного устройства.

В качестве примера рассмотрим ситуацию, в которой виртуальная файловая система пытается прочитать 1024-байтовый блок индексного дескриптора, содержащий индексный дескриптор некоторого файла. Вместо выделения одного буфера ядро должно выделить целую страницу с четырьмя буферами. Эти буферы будут содержать данные из четырех смежных блоков блочного устройства, включая запрошенный блок индексного дескриптора.

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

Все буферы блоков внутри одной страницы буферов должны иметь одинаковый размер. Следовательно, в архитектуре 80×86 страница буферов может включать в себя от одного до восьми буферов, в зависимости от размера блока.

Когда некоторая страница выступает в качестве страницы буферов, все головы буферов блоков, хранящиеся в ней, организованы в однонаправленный циклический список. Поле private дескриптора страницы буферов указывает на голову буфера первого блока в странице2, а каждая голова буфера содержит в поле b this page указатель на следующую голову буфера в списке.

Кроме того, каждая голова буфера содержит адрес дескриптора страницы буферов в поле b page.

Zalman
Добавить комментарий

;-) :| :x :twisted: :smile: :shock: :sad: :roll: :razz: :oops: :o :mrgreen: :lol: :idea: :grin: :evil: :cry: :cool: :arrow: :???: :?: :!: