Главная » Ядро Linux » Структура bi o

0

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

struct bio {

*/

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; /* деструктор */

};

Главное назначение структуры bi o — это представление активной (выполняющейся) операции блочного ввода-вывода. В связи  с этим  большинство полей  этой  структуры являются служебными. Наиболее важные поля — это  bi_io_vecs , bi_vcn t и bi_idx.

Структура bio

bi_io_vec         bi idx

bio_vec bio vec bio_vec bio_vec

Массив структур biovec , содержащий bio_vcnt элементов

Структура page

Структура page

Структура page

Сгруктура page

Структуры page, задействованные

в операции блочного ввода-вывода

Рис.  13.2. Связь  между структурами struct  bio,  struct  b,io_vec u struct  page

Поле  bi_io_vec s указывает па  начало  массива структур  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_vcn t элементов  типа  bio_vec, начало  которого содержится в поле  bi _io_vecs.  В процессе выполнения операции блочного ввода-вывода поле  bi_id x используется для указания  па текущий элемент массива.

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

в массиве bi_vcn t  сегментов.  В  процессе того, как  уровень блочного ввода-вывода обрабатывает сегменты запроса,  обновляется значение  поля  bi_idx , чтобы  его  значение  соответствовало номеру  текущего сегмента. На  рис.  13.2  показана связь  между структурами  bio , bio_ve c    и  page .

Поле   bi_id x  указывает на  текущую   структуру   bio_ve c  в  массиве,  что  позволяет уровню   блочного ввода-вывода  поддерживать частично выполненные  операции блочного ввода-вывода.  Однако  более  важное   использование  состоит в  том,  что драйверы  таких  устройств,  как  RAID   (Redundant Array  of Inexpensive/Independent Disks, массив недорогих/независимых  дисковых устройств с  избыточностью — специальный способ использования жестких  дисков, при  котором один  логический том может  быть  распределен но  нескольким физическим дискам для  увеличения надежности  или  производительности),  могут  одну структуру  bio , которая изначально была адресована одному  устройству, разбивать на  несколько частей, которые предназначаются  различным дискам RAID  массива. Все, что  необходимо сделать  драйверу  RAID, это  создать  необходимое количество копий  структуры bio , которая предназначалась одному  устройству, и  изменить для  каждой копии значение поля  bi_idx , чтобы  оно указывало  на  ту часть  массива,  откуда  каждый диск  должен   начать   свою  операцию ввода-вывода.

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

void bio_get(struct bio *bio)

void bio_put(struct bio *bio)

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

И  наконец, поле  bio_privat e — это  поле  данных   создателя  (владельца)  структуры.  Как  правило, это  поле  необходимо считывать или  записывать только  тому, кто создал  данный экземпляр  структуры bio .

Сравнение старой и новой реализаций

Между  заголовками  буферов  и  новой  структурой bi o  существуют важные  отличия.     представляет операцию  ввода-вывода,  которая  может  включать одну или  больше  страниц в физической памяти. С другой  стороны, заголовок буфера связан с одним  дисковым блоком, который занимает не  более  одной  страницы памяти.   Поэтому использование заголовков буферов приводит к  ненужному делению запроса ввода-вывода на  части, размером в один  блок, только  для  того, чтобы  их потом  снова  объединить.  Работа   со  структурами bi o  выполняется быстрее,  эта  структура  может  описывать несмежные  блоки   и  не  требует  без  необходимости  разбивать операции ввода-вывода на  части.

Переход   о т  структуры  struc t    buffer_hea d  к  структурам  struc t    bi o  позволяет получить также  и  другие  преимущества.

• Структура  bi o  может  легко  представлять верхнюю  память  (см.  главу 11),  так как  структура  struc t  bi o работает  только  со страницами физической памяти, а не с указателями.

• Структура  bi o  может  представлять как  обычные страничные операции  вводавывода, так и операции непосредственного (direct)  ввода-вывода (т.е.  те, которые  не проходят  через  страничный кэш;  страничный кэш  обсуждается  в  главе 15 ).

• Структура  bi o  позволяет легко  выполнять операции блочного  ввода-вывода типа распределения-аккумуляции (scatter-gather), в которых данные  находятся в нескольких страницах физической памяти.

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

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

Источник: Лав,  Роберт. Разработка ядра  Linux, 2-е  издание. : Пер.  с англ.  — М.  : ООО  «И.Д.  Вильяме» 2006. — 448 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии