Хрестоматия по программированию на Си в Unix




Системные вызовы и взаимодействие с UNIX. Хрестоматия по программированию на Си в Unix - стр. 11


Буферизация блоков позволяет системе экономить число обращений к диску. При обращении к bread() сначала происходит поиск блока (dev,bno) в таблице кэш-буферов. Если блок уже был ранее прочитан в кэш, то обращения к диску не происходит, поскольку копия содержимого дискового блока уже есть в памяти ядра. Если же блока еще нет в кэш-буферах, то в ядре выделяется чистый буфер, в заголовке ему прописываются нужные значения полей b_dev и b_blkno, и блок считывается в буфер с диска вызовом функции

bp->b_flags |= B_READ; // род работы: прочитать (*bdevsw[major(dev)].d_startegy)(bp); // bno и минор - берутся из полей *bp

из драйвера конкретного устройства.

Когда мы что-то изменяем в файле вызовом write(), то изменения на самом деле происходят в кэш-буферах в памяти ядра, а не сразу на диске. При записи в блок буфер помечается как измененный:

b_flags B_DELWRI; // отложенная запись

и на диск немедленно не записывается. Измененные буфера физически записываются на диск в таких случаях:

  • Был сделан системный вызов sync();
  • Ядру не хватает кэш-буферов (их число ограничено). Тогда самый старый буфер (к которому дольше всего не было обращений) записывается на диск и после этого используется для другого блока.
  • Файловая система была отмонтирована вызовом umount;
  • Понятно, что не измененные блоки обратно на диск из буферов не записываются (т.к. на диске и так содержатся те же самые данные). Даже если файл уже закрыт close, его блоки могут быть еще не записаны на диск - запись произойдет лишь при вызове sync. Это означает, что измененные блоки записываются на диск "массированно" - по многу блоков, но не очень часто, что позволяет оптимизировать и саму запись на диск: сортировкой блоков можно достичь минимизации перемещения магнитных головок над диском.

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




    Содержание  Назад  Вперед