Разработка ядра Linux
Шрифт:
Поле b_
Таблица 13.1. Значения флагов поля
Флаг состояния | Назначение |
---|---|
BH_Uptodate | Буфер содержит действительные данные |
BH_Dirty | Буфер изменен (содержимое буфера новее соответствующих данных на диске, и поэтому буфер должен быть записан на диск) |
BH_Lock | Для буфера выполняется операция чтения-записи дисковых данных, и буфер заблокирован, чтобы предотвратить конкурентный доступ |
BH_Req | Буфер включен в запрос |
BH_Mapped | Буфер является действительным и отображается на дисковый блок |
BH_New | Буфер только что выделен и к нему еще не было доступа |
BH_Async_Read | Для буфера выполняется асинхронная операция чтения |
BH_Async_Write | Для буфера выполняется асинхронная операция записи |
BH_Delay | С буфером еще не связан дисковый блок |
BH_Boundary | Буфер является последним в последовательности смежных блоков — следующий за ним блок не является смежным с этой серией |
Перечисление
Флаги, которые используются драйверами, могут быть определены на основании значения этого флага, что позволяет гарантированно избежать перекрытия с битами, которые официально используются уровнем блочного ввода-вывода.
Поле
Перед
Физический блок на жестком диске, которому соответствует буфер, — это блок с логическим номером
Физическая страница памяти, в которой хранятся данные буфера, соответствует значению поля
Назначение заголовка буфера — это описание отображения между блоком на диске и буфером в физической памяти (т.е. последовательностью байтов, которые хранятся в указанной странице памяти). Выполнение роли дескриптора отображения буфер-блок — единственное назначение этой структуры данных ядра.
В ядрах до серии 2.6 заголовок буфера был значительно более важной структурой данных. По существу, это была единица ввода-вывода данных в ядре. Он не только выполнял роль дескриптора для отображения буфер-блок-страница физической памяти, но и выступал контейнером для всех операций блочного ввода-вывода. Это приводило к двум проблемам. Первая проблема заключалась в том, что заголовок буфера был большой и громоздкой структурой данных (сегодня он несколько уменьшился в размерах), а кроме того, выполнение операций блочного ввода-вывода в терминах заголовков буферов было непростой и довольно непонятной задачей. Вместо этого, ядру лучше работать со страницами памяти, что одновременно и проще и позволяет получить большую производительность. Использовать большой заголовок буфера, описывающий отдельный буфер (который может быть размером со страницу памяти), — неэффективно. В связи с этим в ядрах серии 2.6 было сделано много работы, чтобы дать возможность ядру выполнять операции непосредственно со страницами памяти и пространствами адресов, вместо операций с буферами. Некоторые из этих операций обсуждаются в главе 15, "Страничный кэш и обратная запись страниц", где также рассматривается структура
Вторая проблема, связанная с заголовками буферов, — это то, что они описывают только один буфер. Когда заголовок буфера используется в качестве контейнера для операций ввода-вывода, то это требует, чтобы ядро разбивало потенциально большую операцию блочного ввода-вывода на множество мелких структур
Структура
Основным контейнером для операций ввода-вывода в ядре является структура bio, которая определена в файле