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

Лав Роберт

Шрифт:

Физический блок на жестком диске, которому соответствует буфер, — это блок с логическим номером

b_blocknr
, который находится на блочном устройстве
b_bdev
.

Физическая страница памяти, в которой хранятся данные буфера, соответствует значению поля

b_page
. Поле
b_data
— это указатель прямо на данные блока (которые хранятся где-то в странице памяти
b_page
), размер блока хранится в поле
b_size
. Следовательно, блок хранится в памяти, начиная с адреса
b_data
и заканчивая адресом (
b_data + b_size
).

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

В ядрах до серии 2.6 заголовок буфера был значительно более важной структурой данных. По существу, это была единица ввода-вывода данных в ядре. Он не только выполнял роль дескриптора для отображения буфер-блок-страница физической памяти, но и выступал контейнером для всех операций блочного ввода-вывода. Это приводило к двум проблемам. Первая проблема заключалась в том, что заголовок буфера был большой и громоздкой структурой данных (сегодня он несколько уменьшился в размерах), а кроме того, выполнение операций блочного ввода-вывода в терминах заголовков буферов было непростой и довольно непонятной задачей. Вместо этого, ядру лучше работать со страницами памяти, что одновременно и проще и позволяет получить большую производительность. Использовать большой заголовок буфера, описывающий отдельный буфер (который может быть размером со страницу памяти), — неэффективно. В связи с этим в ядрах серии 2.6 было сделано много работы, чтобы дать возможность ядру выполнять операции непосредственно со страницами памяти и пространствами адресов, вместо операций с буферами. Некоторые из этих операций обсуждаются в главе 15, "Страничный кэш и обратная запись страниц", где также рассматривается структура

address_space
и демоны
pdflush
.

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

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

Структура

bio

Основным контейнером для операций ввода-вывода в ядре является структура bio, которая определена в файле

<linux/bio.h>
. Эта структура представляет активные операции блочного ввода-вывода в виде списка сегментов (segment). Сегмент — это участок буфера, который является непрерывным в физической памяти, т.е. отдельные буферы не обязательно должны быть непрерывными в физической памяти. Благодаря тому, что буфер может представляться в виде нескольких участков, структура
bio
даст возможность выполнять операции блочного ввода-вывода, даже если данные одного буфера хранятся в разных местах памяти. Ниже показана структура
bio
с комментариями, описывающими назначение каждого поля.

struct bio {

 sector_t bi_sector; /* соответствующий сектор на диске */

 struct bio *bi_next; /* список запросов */

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

 unsigned long bi_flags; /* состояние и флаги команды */

 unsigned long bi_rw; /* чтение или запись? */

 unsigned short bi_vcnt; /* количество структур bio vec

в массиве bi_io_vec */

 unsigned short bi_idx; /* текущий индекс в массиве bi_io_vec */

 unsigned short bi_phys_segments; /* количество сегментов

после объединения */

 unsigned short bi_hw_segments; /* количество сегментов после

перестройки отображения */

 unsigned int bi_size; /* объем данных для ввода-вывода */

 unsigned int bi_hw_front_size; /* размер первого

объединяемого сегмента */

 unsigned int bi_hw_front_size; /* размер последнего объединяемого

сегмента */

 unsigned int bi_max_vecs; /* максимально возможное количество

структур bio_vecs */

 struct bio_vec *bi_io_vec; /* массив структур bio_vec */

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

 atomic_t bi_cnb; /* счетчик использования */

 void *bi_private; /* поле для информации создателя */

 bio_destructor_t *bi_destructor; /* деструктор */

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

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

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

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

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