Разработка ядра Linux
Шрифт:
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; /* деструктор */
};
Главное назначение структуры
bio
— это представление активной (выполняющейся) операции блочного ввода-вывода. В связи с этим большинство полей этой структуры являются служебными. Наиболее важные поля — это bi_io_vecs
, bi_vcnt
и bi_idx
. Поле
bi_io_vecs
указывает на начало массива структур bio_vec
. Эти структуры используются в качестве списка отдельных сегментов в соответствующей операции блочного ввода-вывода. Каждый экземпляр структуры bio_vec
представляет собой вектор следующего вида: <страница памяти, смещение, размер>
, который описывает определенный сегмент, соответственно страницу памяти, где этот сегмент хранится, положение блока — смещение внутри страницы — и размер блока. Массив рассмотренных векторов описывает весь буфер полностью. Структура bio_vec
определена в файле <linux/bio.h>
следующим образом. struct bio_vec {
/* указатель на страницу физической памяти, где находится этот буфер */
struct page *bv_page;
/* размер буфера в байтах */
unsigned int bv_len;
/* смещение в байтах внутри страницы памяти, где находится буфер */
unsigned int bv_offset;
};
Для каждой операции блочного ввода-вывода создается массив из
bi_vcnt
элементов типа bio_vec
, начало которого содержится в поле bi_io_vecs
. В процессе выполнения операции блочного ввода-вывода поле bi_idx
используется для указания на текущий элемент массива. В общем, каждый запрос на выполнение блочного ввода-вывода представляется с помощью структуры
bio
. Каждый такой запрос состоит из одного или более блоков, которые хранятся в массиве структур bio_vec
. Каждая из этих структур представляет собой вектор, который описывает
bi_io_vec
. Каждый следующий сегмент следует сразу за предыдущим. Всего в массиве bi_vcnt
сегментов. В процессе того, как уровень блочного ввода-вывода обрабатывает сегменты запроса, обновляется значение поля bi_idx
, чтобы его значение соответствовало номеру текущего сегмента. На рис. 13.2 показана связь между структурами bio
, bio_vec
и page
. Рис. 13.2. Связь между структурами
struct bio
, struct bio_vec
и struct page
Поле
bi_idx
указывает на текущую структуру bio_vec
в массиве, что позволяет уровню блочного ввода-вывода поддерживать частично выполненные операции блочного ввода-вывода. Однако более важное использование состоит в том, что драйверы таких устройств, как RAID (Redundant Array of Inexpensive/Independent Disks, массив недорогих/независимых дисковых устройств с избыточностью — специальный способ использования жестких дисков, при котором один логический том может быть распределен но нескольким физическим дискам для увеличения надежности или производительности), могут одну структуру bio
, которая изначально была адресована одному устройству, разбивать на несколько частей, которые предназначаются различным дискам RAID массива. Все, что необходимо сделать драйверу RAID, это создать необходимое количество копий структуры bio
, которая предназначалась одному устройству, и изменить для каждой копии значение поля bi_idx
, чтобы оно указывало на ту часть массива, откуда каждый диск должен начать свою операцию ввода-вывода. Структура
bio
содержит счетчик использования, который хранится в поле bi_cnt
. Когда значение этого поля становится равным нулю, структура удаляется, и занятая память освобождается. Следующие две функции позволяют управлять счетчиком использования. void bio_get(struct bio *bio);
void bio_put(struct bio *bio);
Первая увеличивает на единицу значение счетчика использования, а вторая — уменьшает значение этого счетчика на единицу и, если это значение становится равным нулю, уничтожает соответствующую структуру
bio
. Перед тем как работать с активной структурой bio
, необходимо увеличить счетчик использования, чтобы гарантировать, что экземпляр структуры не будет удален во время работы. После окончания работы необходимо уменьшить счетчик использования. И наконец, поле
bio_private
— это поле данных создателя (владельца) структуры. Как правило, это поле необходимо считывать или записывать только тому, кто создал данный экземпляр структуры bio
. Сравнение старой и новой реализаций
Между заголовками буферов и новой структурой
bio
существуют важные отличия. Структура bio
представляет операцию ввода-вывода, которая может включать одну или больше страниц в физической памяти. С другой стороны, заголовок буфера связан с одним дисковым блоком, который занимает не более одной страницы памяти. Поэтому использование заголовков буферов приводит к ненужному делению запроса ввода-вывода на части, размером в один блок, только для того, чтобы их потом снова объединить. Работа со структурами bio выполняется быстрее, эта структура может описывать несмежные блоки и не требует без необходимости разбивать операции ввода-вывода на части.
Поделиться:
Популярные книги
Ретроградный меркурий
4. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
5.00
рейтинг книги
Я еще не барон
1. Дорогой барон!
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Полковник Империи
3. Безумный Макс
Фантастика:
альтернативная история
6.58
рейтинг книги
Бремя империи
Бремя империи - 1.
Фантастика:
альтернативная история
9.34
рейтинг книги
Инферно
2. Легенда
Фантастика:
фэнтези
8.57
рейтинг книги
Адмирал южных морей
4. Девятый
Фантастика:
фэнтези
8.96
рейтинг книги
Защитник
7. Сопряжение
Фантастика:
боевая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Я – Орк. Том 3
3. Я — Орк
Фантастика:
юмористическое фэнтези
попаданцы
5.00
рейтинг книги
Мир-о-творец
8. Помещик
Фантастика:
альтернативная история
5.00
рейтинг книги
Кодекс Крови. Книга II
2. РОС: Кодекс Крови
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Я – Орк. Том 4
4. Я — Орк
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Хозяйка лавандовой долины
2. Хозяйка своей судьбы
Любовные романы:
любовно-фантастические романы
6.25
рейтинг книги
Разбуди меня
7. Серьёзные мальчики в форме
Любовные романы:
современные любовные романы
остросюжетные любовные романы
5.00
рейтинг книги
Курсант: назад в СССР 9
9. Курсант
Фантастика:
попаданцы
альтернативная история
5.00