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


Методы prepare_write и commit_write для файлов блочных устройств

Операции записи в файлы блочных устройств очень похожи на соответствующие операции для обычных файлов. Метод prepare write объекта address space у файлов блочных устройств обычно реализуется следующей функцией:
int blkdev_prepare_write(struct file file, struct page page,
unsigned from, unsigned to){
return block_prepare_write(page, from, to, blkdev_get_block);}
Как видите, она является интерфейсом К функции block_prepare_write(), описанной в предыдущем разделе. Естественно, есть отличие во втором параметре, который указывает на функцию, преобразующую номер блока относительно начала файла в логический номер блока относительно начала блочного устройства. Вспомним, что у файлов блочных устройств эти два номера совпадают. Метод commit write для файлов блочных устройств реализуется простой интерфейсной функцией:
int blkdev_commit_write(struct file file, struct page page,
unsigned from, unsigned to){
return block_commit_write(page, from, to);}
Нетрудно заметить, ЧТО метод commit write для файлов блочных устройств делает, в сущности, то же самое, что метод commit write для обычных файлов (мы описали функцию biock_commit_write в предыдущем разделе). Единственное отличие заключается в том, что метод не проверяет, увеличился ли файл в результате операции записи: вы не можете увеличить файл блочного устройства, добавляя символы в его конец.

Запись грязных страниц на диск

Результат работы системного вызова write о заключается в изменении содержимого некоторых страниц в кэше, возможно, с выделением новых страниц и добавлением их в кэш, если их там не было. В некоторых случаях (например, если файл был открыт с флагом o sync) пересылка данных начинается немедленно (см. шаг 6 В описании функции generic_file_write в разд. ”Запись в файл”ранее в этой главе). Впрочем, как правило, ввод/вывод данных откладывается, что было подробно обсуждено в разд. "Запись грязных страниц на диск”

Когда ядро хочет запустить фактическую пересылку данных, оно, в конечном счете, вызывает метод writepages объекта address space этого файла, а метод ищет грязные страницы в базисном дереве и записывает их на диск. Например, в файловой системе Ext2 метод writepages реализован следующей функцией:
int ext2_writepages(struct address_space mapping, struct writeback_control wbc){
return mpage_writepages(mapping, wbc, ext2_get_block);}
Нетрудно заметить, что эта функция является интерфейсом к функции общего назначения mpage writepages о. На практике, если в файловой системе метод writepages не определен, напрямую ядро вызывает функцию mpage writepages , передавая ей null в качестве третьего аргумента. Функция ext2_get_biock о, уже упоминавшаяся в разд. ”Чтение из файла”ранее в этой главе, является специфичной для файловой системы и преобразует номер блока в файле в логический номер блока.

Структура writeback controi является дескриптором, уточняющим, как должна выполняться операция обратной записи на диск;
Функция mpage writepages выполняет следующие действия:
1. Если очередь запросов переполнена запросами на запись, а процесс не должен блокироваться, функция возвращает управление, ничего не записав на диск.
2. Определяет первую страницу, подлежащую рассмотрению. Если дескриптор writeback controi задает начальную позицию в файле, функция преобразует ее в индекс страницы. В противном случае, если дескриптор writeback controi отмечает, что процесс не хочет ждать окончания пересылки данных, функция устанавливает индекс первой страницы равным значению, которое хранится в поле mapping->writeback_index (то есть перебор страниц начнется с последней страницы, рассмотренной в предыдущей операции обратной записи). Наконец, если процесс должен ждать окончания пересылки данных, перебор страниц начинается с первой страницы файла.
3. Вызывает функцию f ind get pages tag , чтобы найти дескрипторы грязных страниц в кэше
4. Для каждого дескриптора страницы, полученного на предыдущем шаге, функция выполняет следующие действия:
• вызывает функцию lock page , чтобы заблокировать страницу;
• проверяет, что страница по-прежнему корректна и находится в кэше страниц (потому что другой управляющий тракт ядра мог воздействовать на страницу между шагами 3 и 4);
• проверяет флаг PG writeback этой страницы. Если он установлен, значит, страница уже записывается на диск. Если процесс должен ждать
окончания пересылки данных, функция вызывает функцию wait_on_ page bito, чтобы заблокировать текущий процесс, пока не будет сброшен флаг PG writeback; когда функция закончит работу, любая ранее запущенная операция обратной записи заканчивается. В противном случае, если процесс не хочет ждать, функция проверяет флаг PG dirty. Если он уже сброшен, значит, о странице позаботится текущая операция обратной записи. Поэтому функция разблокирует страницу и переходит назад, к шагу 4, чтобы продолжить со следующей страницы;
• если параметр get biock равен null (метод writepages не определен), функция вызывает метод mapping->writepage объекта address space данного файла, чтобы записать страницу на диск. В противном случае, если параметр get biock не равен null, функция вызывает функцию mpage writepage . Подробности даны в описании шага 8.
5. Вызывает функцию cond reschedO, чтобы проверить состояние флага tif need resched текущего процесса и, если флаг установлен, вызвать функцию schedule .
6. Если функция перебрала не все страницы в заданном диапазоне, или количество страниц, фактически записанных на диск, меньше исходного значения, заданного дескриптором writeback controi, функция переходит назад, к шагу 3.
7. Если дескриптор writeback controi не задает первоначальную позицию в файле, функция записывает В поле mapping->writeback_index индекс последней рассмотренной страницы.
8. Если на шаге 4 была вызвана функция mpage writepage , и она возвратила адрес дескриптора bio, описываемая функция вызывает функцию mpage_bio_submit.

Типичная файловая система, такая как Ext2, реализует метод writepage в виде интерфейса к функции общего назначения block write full раде о, передавая ей в качестве параметра адрес специфичной для файловой системы функции get biock. Функция biock_write_fuii_page во многом аналогична функции block read full page , описанной в разд. "Чтение из файла"ранее в этой главе: она выделяет головы буферов для страницы (если страница еще не была страницей буферов) и вызывает функцию submit bh о для каждой головы, задавая в качестве операции write. Что касается файлов блочных устройств, для них метод writepage реализован с помощью функции blkdev writepage , которая является интерфейсом ДЛЯ функции block_write_ full_page.

Многие не журналируемые файловые системы используют функцию mpage writepage , а не специализированный метод writepage. Это повышает производительность, поскольку функция mpage writepage старается выполнять пересылку данных, собрав как можно больше страниц в одном дескрипторе bio. Такой подход позволяет драйверам блочных устройств использовать возможности современных дисковых контроллеров по DMA-пересылке вразброс.
Короче говоря, функция mpage writepage проверяет, содержит ли страница, подлежащая записи, блоки, не смежные на диске, содержит ли эта страница "дыру” файла, а также является ли какой-нибудь блок на этой странице "не грязным” или не устаревшим. Если выполняется хотя бы одно из этих условий, функция прибегает к помощи зависящего от файловой системы метода writepage, как описано ранее. В противном случае функция добавляет страницу в качестве сегмента к дескриптору bio. Адрес дескриптора bio передается функции в качестве параметра. Если передано значение null, функция mpage writepage инициализирует новый дескриптор bio и возвращает его адрес вызывающей функции, которая, в свою очередь, передает его обратно функции mpage writepage , когда вызывает ее в следующий раз. Таким способом достигается добавление нескольких страниц в один bio. Если страница не является смежной к последней добавленной странице, функция mpage writepage вызывает функцию mpage bio submit , чтобы запустить пересылку данных для этого bio, а сама выделяет для страницы новый bio.

Функция mpage bio submit устанавливает метод bi end io в адрес функции mpage end io write , Затем вызывает фуНКЦИЮ submit bio , Чтобы ЗапуС- тить пересылку данных. После успешного окончания пересылки данных функция завершения mpage end io write "будит" процессы, ожидающие завершения пересылки, и уничтожает дескриптор 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 без проблем

ВведениеЕсли вы цените свое время, умеете считать деньги и знаете стоимость информации, то эта книга для вас. А так как к книге прилагается компакт- диск с готовой к работе операционной системой Knoppix Live CD, то лишь достаточно вставить его в привод и перегрузить компьютер,...

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

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

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

Копирование при записи В системах Unix первых поколений создание процесса было реализовано довольно неуклюже: получив системный вызов fork о, ядро в буквальном смысле дублировало все адресное пространство родителя и присваивало копию процессу-потомку. Такая операция...

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

Буферы блоков и головы буферовУ каждого буфера есть дескриптор голова буфера, имеющий тип buffer head. Этот дескриптор содержит всю информацию, необходимую ядру для работы с блоком, так что перед обработкой блока ядро обязательно проверяет голову...