Вход/Регистрация
Разработка ядра Linux
вернуться

Лав Роберт

Шрифт:

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

Когда блок хранится в памяти (скажем, после считывания или в ожидании записи), то он хранится в структуре данных, называемой буфером (buffer). Каждый буфер связан строго с одним блоком. Буфер играет роль объекта, который представляет блок в оперативной памяти. Вспомним, что блок состоит из одного или больше секторов, но по размеру не может быть больше одной страницы памяти. Поэтому одна страница памяти может содержать один или больше блоков. Поскольку для ядра требуется некоторая управляющая информация, связанная с данными (например, какому блочному устройству и какому блоку соответствует буфер), то каждый буфер связан со своим дескриптором. Этот дескриптор называется заголовком буфера (buffer head) и представляется с помощью структуры

struct buffer_head
.

Структура

buffer_head
содержит информацию, которая необходима ядру для управления буферами и определена в файле
<linux/buffer_head.h>
.

Рассмотрим эту структуру с комментариями, которые описывают назначение каждого поля.

struct buffer_head {

 unsigned long b_state; /* флаги состояния буфера */

 atomic_t b_count; /* счетчик использования буфера */

 struct buffer_head *b_this_page; /* список буферов в текущей

странице памяти */

 struct page *b_page; /* соответствующая страница памяти */

 sector_t b_blocknr; /* логический номер блока */

 u32 b_size; /* размер блока (в байтах) */

 char *b_data; /* указатель на буфер в странице памяти */

 struct block_device *b_bdev; /* соответствующее блочное устройство */

 bh_end_io_t *b_end_io; /* метод завершения ввода-вывода */

 void *b_private; /* данные метода завершения */

 struct list_head b_assoc_buffers; /* список связанных отображений */

};

Поле b_

state
содержит состояние определенного буфера. Это значение может содержать один или несколько флагов, которые перечислены в табл. 13.1. Возможные значения флагов описаны в виде перечисления
bh_state_bits
, которое описано в файле
<linux/buffer_head.h>
.

Таблица 13.1. Значения флагов поля

bh_state

Флаг состояния Назначение
BH_Uptodate
Буфер содержит действительные данные
BH_Dirty
Буфер изменен (содержимое буфера новее соответствующих данных на диске, и поэтому буфер должен быть записан на диск)
BH_Lock
Для буфера выполняется операция чтения-записи дисковых данных, и буфер заблокирован, чтобы предотвратить конкурентный доступ
BH_Req
Буфер включен в запрос
BH_Mapped
Буфер является действительным и отображается на дисковый блок
BH_New
Буфер только что выделен и к нему еще не было доступа
BH_Async_Read
Для буфера выполняется асинхронная операция чтения
BH_Async_Write
Для буфера выполняется асинхронная операция записи
BH_Delay
С буфером еще не связан дисковый блок
BH_Boundary
Буфер является последним в последовательности смежных блоков — следующий за ним блок не является смежным с этой серией

Перечисление

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

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

Поле

b_count
— это счетчик использования буфера. Значение этого поля увеличивается и уменьшается двумя функциями, которые определены в файле
<linux/buffer_head.h>
следующим образом.

static inline void get_bh(struct buffer_head *bh) {

 atomic_inc{&bh->b_count);

}

static inline void put_bh(struct buffer_head *bh) {

 atomic_dec(&bh->b_count);

}

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

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

  • Читать дальше
  • 1
  • ...
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: