Linux Kernel (Ядро линукса) (часть 3)


Метод readpage для обычных файлов

Мы видели, что метод readpage неоднократно вызывается функцией do generic f ile read ДЛЯ ЧТеНИЯ ОТДеЛЬНЫХ СТраНИЦ ИЗ ДИСКа В ПамЯТЬ.
Метод readpage объекта address space содержит адрес функции, которая фактически активизирует пересылку данных с физического диска в кэш страниц. Для обычных файлов это поле указывает на интерфейсную функцию, вызывающую функцию mpage readpage . Например, в файловой системе Ext3 метод readpage реализован следующей функцией:
int ext3_readpage(struct file file, struct page page){
return mpage_readpage(page, ext3_get_block);}
Интерфейсная функция необходима, поскольку функция mpage readpage принимает в качестве параметров дескриптор раде страницы, которую необходимо заполнить, и адрес get biock функции, которая помогает функции mpage readpage найти нужный блок. Интерфейсная функция специфична для файловой системы и поэтому может предоставить необходимую функцию получения блока. Эта функция преобразует номера блоков относительно начала файла в логические номера блоков в разделе диска Естественно, последний параметр зависит от типа файловой системы, которой принадлежит данный обычный файл. В предыдущем примере параметром является адрес функции ext3_get_biock. Функция, передаваемая как get biock, всегда пользуется головой буфера для хранения важной информации о блочном устройстве (поле b dev), позиции запрошенных данных в устройстве (поле b biocknr) и состоянии блока (поле b state).

Функция mpage readpage выбирает одну из двух стратегий чтения страницы с диска. Если запрошенные данные содержатся в смежных блоках диска, функция выдает команду на ввод/вывод общему блочному слою при помощи одного дескриптора bio. В противном случае каждый блок страницы читается с использованием отдельного дескриптора bio. Специфичная для файловой системы функция get biock играет решающую роль в определении, является ли следующий блок в файле также и следующим блоком на диске.

Функция mpage readpage выполняет следующие действия:
1. Проверяет поле PG private дескриптора страницы. Если оно установлено, значит, это страница буферов, т. е. она связана со списком голов буферов, описывающих блоки, составляющие страницу (см. разд. "Хранение блоков в кэше страниц" главы 15). Это свидетельствует о том, что страница уже была прочитана с диска в прошлом, а ее блоки не являются смежными на диске. Функция переходит к шагу 11, чтобы выполнить поблочное чтение страницы.
2. Извлекает размер блока (из ПОЛЯ page->mapping->host->i_blkbits индексного дескриптора) и вычисляет два значения, необходимые для обращения ко всем блокам этой страницы: количество блоков в странице и номер в файле первого блока страницы, т. е. индекс первого блока страницы относительно начала файла.
3. Для каждого блока страницы функция вызывает специфичную для файловой системы функцию get biock, полученную в качестве параметра, чтобы узнать логический номер блока, т. е. индекс блока относительно начала диска или раздела. Логические номера всех блоков в странице хранятся в локальном массиве.
4. Проверяет, не возникли ли аномалии при выполнении предыдущего шага. В частности, некоторые блоки могут оказаться не смежными на диске, или какой-то блок может попасть в дыру в файле” или буфер блока уже мог быть заполнен функцией get biock. Во всех этих случаях описываемая функция переходит к шагу 11, чтобы выполнить поблочное чтение страницы.
5. Если функция дошла до этого шага, значит, все блоки в странице являются смежными на диске. Однако страница могла быть последней страницей данных в файле, и поэтому некоторые из ее блоков, возможно, не имеют образа на диске. Если это действительно так, функция заполняет нулями соответствующие буферы блоков на странице. В противном случае она устанавливает флаг PG mappedtodisk дескриптора страницы.
6. Вызывает функцию bio aiiocO для выделения нового дескриптора bio, состоящего из единственного сегмента, и для инициализации полей bijodev и bi sector этого дескриптора адресом дескриптора блочного устройства и логическим номером первого блока страницы соответственно. Оба информационных элемента были определены в шаге 3.
7. Записывает в дескриптор bio vec сегмента, принадлежащего bio, начальный адрес страницы, смещение первого байта, подлежащего чтению (то есть ноль), и общее количество байтов, которые необходимо прочитать.
8. Сохраняет адрес функции mpage_end_io_read В ПОЛе bio->bi_end_io.
9. Вызывает функцию submitjoio , которая устанавливает флаг bi rw в соответствии с направлением движения данных, обновляет переменную page states (свою у каждого процессора), чтобы отследить количество прочитанных секторов, И, наконец, вызывает функцию generic_make_ request для дескриптора bio 10. Возвращает ноль (успех).
11. Если функция находится на этом шаге, значит, страница содержит блоки, не являющиеся смежными на диске. Если страница не устарела (флаг PG uptodate установлен), функция вызывает функцию unlock_page для разблокировки страницы; в противном случае она вызывает функцию biock read fuii page , чтобы начать поблочное чтение страницы.
12. Возвращает ноль (успех).
Функция mpage end io read является методом завершения для дескриптора bio. Она выполняется сразу по окончании пересылки данных. Если предположить, что ошибок ввода/вывода не было, функция устанавливает флаг PG uptodate Дескриптора страницы, вызывает функцию unlock page , чтобы разблокировать страницу и возобновить выполнение процессов, возможно, ожидающих это событие, и вызывает функцию bio put , чтобы уничтожить дескриптор bio.

Предыдущая страница | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 | Следующая страница




Возможно, Вас также заинтересует:

ОС Knoppix - это Linux без про...

ВведениеЕсли вы цените свое время, умеете считать деньги и знаете стоимость информации, то эта книга...

Linux Kernel (Ядро линукса) (ч...

Спин-блокировкаСпин-блокировка необходима в многопроцессорной системе, потому что могут возникнуть...

Linux Kernel (Ядро линукса) (ч...

Копирование при записи В системах Unix первых поколений создание процесса было реализовано довольно...

Linux Kernel (Ядро линукса) (ч...

Буферы блоков и головы буферовУ каждого буфера есть дескриптор голова буфера, имеющий тип buffer...