Zapewnia jednolity dostęp do urządzeń blokowych dla systemów plików.
Zapobiega wielokrotnemu czytaniu z dysku tych samych danych, zbędnego ich zapisywania na dysk.
Umożliwia wcześniejsze przeczytanie danych (w wolnym momencie), które będą najprawdopodobniej później potrzebne.
Pozwala nie zatrzymywać procesu, który chce coś zapisać na dysk lub odczytać z dysku.
Pozwala rozłożyć zapisy w czasie.
Zapewnia synchronizację.
W Linuksie istnieje pięć pamięci podręcznych związanych z systemami plików. Są to:
Główną pamięcią podręczną jest obecnie pamięć stron.
Przechowuje się w niej strony plików (niekoniecznie kolejne bloki pliku z dysku).
Główne struktury danych to: tablica hashująca i listy stron plików przy każdym i-węźle.
Na stronach są zazwyczaj bufory (ich dane) - jeśli czytamy stronę pliku to tworzymy kilka buforów na tej stronie, i wczytujemy do nich dane (chociaż tak nie musi być).
Bufory nie są już tak istotną częścią linux'a jak w jądrach przed 2.4; spadek ich ważności uwidacznia się w przydzielanej im pamięci (e. g. tablica hashująca 4 razy mniejsza niż tablica hashująca page cache'a).
Buforowanie jest prawie całkowicie uwątkowione, tzn. blokadę jądra (kernel_lock) zamyka się rzadko, a większość pracy wykonywana jest asynchronicznie.
Jest ono też przystosowane do działania na systemach wieloprocesorowych.
Powiadamia system, że już nie używamy bufora.
Atomowo zmniejsza ilość użytkowników bufora (b_count).
Licznik ten służy jako pewnego rodzaju blokada, dopóki jest większy od zera system nie pozbędzie się bufora. Większość operacji na buforach jest otoczona parą: zwiększ licznik, zmniejsz licznik.
Brelse dodatkowo dodaje wpis do historii bufora.
Jest to funkcja "do pary" do bread'a, który zwiększa ten licznik.
To samo co brelse, poza tym, że próbuje wstawić bufor na listę wolnych buforów.
Algorytm:
Utrzymywana jest rezerwa nieużywanych nagłówków buforów dla asynchronicznych operacji wejścia/wyjścia - żeby uniknąć blokady; na przykład przy braku pamięci i konieczności wyrzucania stron na dysk.
Zmienione bufory od czasu do czasu przydałoby się zapisać na dysk.
Robią to dwa demony - kupdate i bdflush.
Pierwszy budzi się co pewien czas (co 5 sS) i zapisuje wszystkie metadane i brudne bufory.
Drugi jest budzony zazwyczaj gdy brudnych buforów zaczyna być zbyt dużo, czy też brakuje miejsca na nowe bufory.
Obydwa wykorzystują procedurę (asynchronicznego) zapisywania buforów na dysk: flush_dirty_buffers (jest to w ogóle jedyna taka procedura).
Demon bdflush w kółko wykonuje następujące czynności:
Demona można budzić - wakeup_bdflush - dzieje się to czasem podczas uzyskiwania wolnych buforów.
Kupdate - drugi demon, budzi się co pewien czas i wypisuje niezablokowane węzły indeksowe, super bloki, i stare bufory; wykonuje, również synchronicznie, kolejkę zadań dyskowych (run_task_queue(&tq_disk)).
Działanie bdflush'a jest sparametryzowane, można je zmieniać nawet podczas działania systemu (sys_bdflush).
Parametry demona to:
parametr | opis | wartość ustalona | wartość minimalna | wartość maksymalna |
nfract | procent brudnych buforów, przy którym zwalnia się je asynchronicznie | 30% | 0% | 100% |
nfract_sync | procent brudnych buforów, przy którym zwalnia się je synchronicznie (blokująco) | 60% | 0% | 100% |
ndirty | maksymalna liczba buforów wypisanych przy jednym obudzeniu | 64 | 10 | 50000 |
age_buffer | przez jaki czas bufor będzie zbyt młody żeby go wypisać | 30s | 1s | 6000s |
interval | czas pomiędzy uruchumieniami kupdate'a | 5s | 0s | 600s |
nrefill | liczba buforów, jaką próbuje się uzyskać przy jednym wywołaniu refill_freelist (nieużywane) | 64 | 5 | 20000 |
wersja jądra: 2.4.7 |
autor: Wojciech Ruszczewski |
Czytanie z wyprzedzeniem