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


Выделение страниц буферов блочных устройств

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

Чтобы добавить страницу буферов блочного устройства в кэш страниц, ядро вызывает функцию grow buffers , которая принимает три параметра, идентифицирующие блок:
- адрес bdev дескриптора block_device;
- логический номер блока block, т. е. позицию блока в блочном устройстве;
- размер блока size.
Функция выполняет следующие действия:
1. Вычисляет смещение index страницы данных в пределах блочного устройства, содержащего запрошенный блок.
2. Вызывает функцию grow dev page , чтобы создать новую страницу буферов блочного устройства, если это необходимо. Вызванная функция вызывает функцию f ind or create page , передавая ей объект address space блочного устройства (bdev->bd_inode->i_mapping), смещение в странице index и флаг gfp nofs. Как было сказано ранее, в разд. "Функции работы
с кэшем страниц", функция find or create page о ищет страницу в кэше
и, если необходимо, вставляет в кэш новую страницу.
3. Итак, требуемая страница находится в кэше, и у функции есть адрес ее дескриптора. Тогда функция проверяет флаг PG private. Если он равен null, значит, страница еще не является страницей буферов (с ней не ассоциированы никакие головы буферов). Функция find or create page о переходит на шаг 6.
4. Страница является страницей буферов. Функция извлекает из поля private дескриптора страницы адрес bh первой головы буфера и проверяет, равен ли размер блока bh->size размеру запрошенного блока. Если это так, значит, страница, найденная в кэше, является допустимой страницей буферов. Функция f ind or create page переходит на шаг 8.
5. Страница содержит блоки не того размера. Функция вызывает try_to_ free buffers о, чтобы освободить имеющиеся головы буферов в странице буферов.
6. find_or_create_page вызывает функцию alloc_page_buf fers , чтобы разместить головы буферов для блоков необходимого размера в пределах страницы и занести их в однонаправленный циклический список, организованный с помощью полей b this page. Кроме этого, функция записывает в поля b page голов буферов адрес дескриптора страницы, а в поля b data — смещение или линейный адрес буфера внутри страницы.
7. find or create page сохраняет адрес первой головы буфера в поле private, устанавливает поле PG private и увеличивает счетчик обращений страницы (считается, что буферы блоков внутри страницы обращаются к странице).
8. find_or_create_page вызывает функцию init_page_buf fers () ДЛЯ инициализации полей b bdev, b biocknr и b bstate голов буферов, связанных со страницей. Все блоки расположены на диске смежно, значит, их логические номера идут последовательно, и их легко вычислять на основании параметра block.
9. f ind or create page возвращает адрес дескриптора страницы.
10. Функция grow buffers снимает блокировку со страницы (была заблокирована функцией f ind or create page ).
11. Затем она уменьшает счетчик обращений (счетчик был увеличен все той же функцией f ind_or_create_page ).
12. Функция growbuf fers (возвращает 1 (успех).

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