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


Функция handle_ra_miss

В некоторых случаях ядро должно корректировать параметры опережающего чтения, если стратегия оказывается не очень эффективной. Рассмотрим функцию do_generic_fiie_read, описанную в разд. На шаге 7 вызывается функция page_cache_readahead . либо запрошенная страница находится в текущем или опережающем окне и, вероятнее всего, была прочитана заранее, либо это не так, и для ее чтения вызывается функция blockable_page_cache_readahead . В обоих случаях функция do_generic_ fiie reado должна найти страницу в кэше на шаге 8. Если ей это не удается, значит, алгоритм утилизации страничных кадров удалил эту страницу из кэша. Тогда функция do_generic_file_read вызывает фуНКЦИЮ handie ra miss о, которая настраивает алгоритм опережающего чтения, устанавливая флаг ra flag miss и сбрасывая флаг ra flag incache.

Запись в файл

Вспомним, что системный вызов write , среди прочего, перемещает данные из адресного пространства режима пользователя вызывающего процесса в структуры ядра, а затем — на диск. Метод write файлового объекта разрешает файловой системе любого типа определять специализированную операцию записи. В системе Linux 2.6 метод write каждой дисковой файловой системы является процедурой, которая идентифицирует блоки диска, вовлеченные в операцию записи, копирует данные из адресного пространства режима пользователя в страницы, принадлежащие кэшу, и помечает буферы в этих страницах как грязные”.

Многие файловые системы (в том числе Ext2 и JFS) реализуют метод write файлового объекта с помощью функции generic_fiie_write(), которая принимает следующие параметры:
- file — указатель на файловый объект;
- buf — адрес в адресном пространстве режима пользователя, по которому находятся символы, подлежащие записи в файл;
- count — количество символов, которые должны быть записаны в файл;
- ppos — адрес переменной, содержащей смещение внутри файла, с которого должна начаться запись.
Функция выполняет следующие шаги:
1. Инициализирует локальную переменную типа iovec, содержащую адрес и длину буфера режима пользователя.
2. Определяет адрес inode индексного дескриптора, соответствующего файлу, в который пишутся данные (fiie->f_mapping->host), и получает сема- фор inode->i_sem. Благодаря этому семафору только один процесс сможет ВЫПОЛНИТЬ системный ВЫЗОВ write для файла.
3. Вызывает макрос init sync kiocb, чтобы проинициализировать локальную переменную типа kiocb. Как было сказано ранее в этой главе, данный макрос записывает в поле ki key значение kiocb sync key (операция синхронного ввода/вывода), в поле ki fiip— значение file, а в поле ki_obj — значение current.
4. Вызывает generic_file_aio_write_nolock(), ЧТОбы пометить Затронутые
страницы как "грязные”. В качестве параметров передает вызванной функции адреса локальных переменных типа iovec и kiocb, количество сегментов для буфера режима пользователя (в этом случае — только один) и параметр ppos.
5. Освобождает семафор inode->i_sem.
6. Проверяет флаг o sync файла, флаг s sync индексного дескриптора и флаг ms synchronous суперблока. Если хотя бы один из них установлен, функция вызывает функцию sync page rangeo, заставляя ядро сбросить на диск все страницы из кэша, которые были затронуты на шаге 4. При этом текущий процесс блокируется до окончания операции ввода/вывода. Со своей стороны, функция sync_page_range ВЫПОЛНЯеТ либо МеТОД writepages объекта address space, если этот метод определен, либо функцию mpage writepages чтобы запустить операцию записи для грязных” страниц; затем она вызывает функцию generic_osync_inode, чтобы сбросить на диск индексный дескриптор и ассоциированные буферы, и, наконец, вызывает функцию wait on page bit , ЧТОбы прИОСТанОВИТЬ Текущий про- цесс до тех пор, пока все биты PG writeback страниц, записываемых на диск, не будут сброшены.
7. Возвращает КОД возврата, полученный ОТ функции generic_file_aio_
write_noiock(). Как правило, это количество фактически записанных байтов.
Функция generic_fiie_aio_write_noiock принимает четыре параметра:
адрес iocb дескриптора kiocb, адрес iov массива дескрипторов iovec, длину
этого массива и адрес переменной ppos, в которой хранится указатель файла.
Если функция была вызвана функцией generic_fiie_write, то массив дескрипторов iovec состоит из одного элемента, описывающего буфер режима пользователя, содержащий данные, подлежащие записи в файл.

Примечание

Вариант системного вызова write , называемый writev , позволяет приложению определить несколько буферов режима пользователя, из которых ядро получает данные, подлежащие записи в файл. Функция generic_file_ aio_write_nolock обрабатывает и этот случай. В дальнейшем мы будем предполагать, что данные получены из одного буфера режима пользователя, но читатель без труда догадается, какие дополнительные действия необходимы для работы с несколькими буферами.

Предыдущая страница | 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...