getblk()
i funkcje pomocnicze:
getblk()
getblk()
jest dostarczenie bufora z podrecznej pamieci
buforowej odpowiadajacego wskazanemu blokowi. Blok ten jest opisany przez
parametry funkcji podajace urzadzenie (kdev_t dev
), z ktorego blok
ma byc pobrany, numeru bloku (int block
) oraz jego rozmiaru (int size
).
Te trzy parametry jednoznacznie wyznaczaja blok oraz przyporzadkowany mu
bufor z podrecznej pamieci buforowaj.
DEFINICJA: struct buffer_head* getblk(kdev_t dev, int block, int size) WYNIK: wskaznik do naglowka bufora w przypadku sukcesu NUll wpp.
getblk()
.getblk()
tzn. ktorego pola b_dev
, b_blocknr
, b_size
z naglowka
bufora sa odpowiednio rowne dev
, block
, size
.
b_state
naglowka bufora
rowny jest 0) tzn. jego dane sa takie same jak dane zpisane
w odpowiadajacym mu bloku fizycznego urzadzenia, to ustawiamy czas
zapisu (pole b_flushtime
naglowka bufora) na 0. Jesli dodatkowo bufor
zawiera aktualne dane (bit BH_Uptodate pola b_state
rowny 1) to
wstawiamy go na koniec odpowiadajacej mu kolejki lru (najdluzej
nieuzywanych buforow) za pomoca funkcji put_last_lru()
.
Oznaczamy bufor jako dotkniety tzn. ustawiamy bit BH_Touched
pola b_state
na 1. Nastepnie zwracamy znaleziony bufor konczac funkcje
getblk()
.
Uwaga. Wszystkie bufory znajdujace sie w kolejkach haszujacych zawieraja aktualne dane. Dlatego bufor znaleziony w kolejce haszujacej i nie bedacy brudnym zawsze zawiera aktualne dane. (Tak mi sie wydaje)
refill_freelist()
. Funkcja ta dostarczy wolne
bufory do danej kolejki,
refill_freelist()
jest mozliwosc zasniecia podczas
oczekiwania na pewne zdarzenia,
b_count
) rowny 1,
czas zapisu (b_flushtime
) rowny 0,
oznaczamy go jako "dotkniety",
okreslamy blok, ktoremu bedzie odpowiadal ten bufor tzn.
urzadzenie (b_dev
) rowne podanemu (dev
), numer bloku (b_blocknr
)
rowny podanemu (block
),
insert_into_queues()
).
getblk()
.
refill_freelist()
.refill_freelist()
ma na celu dostarczenie wolnych
buforow podanego rozmiaru i wstawienie ich do kolejki wolnych buforow.
DEFINICJA: void refill_freelist(int size)Algorytm dzialania funkcji
refill_freelist()
.
needed
). Liczba tworzonych buforow podczas
jdnego wywolania funkcji refill_freelist()
jest podana w bdf_prm.b_un.nrefill
.
nr_free_pages
) jest dwa razy wieksza
niz okreslona w zmiennej min_free_pages
minimalna liczba wolnych stron
i nie utworzylismy jeszcze wystarczajacej liczby buforow (needed
>0 ) to
wywolujemy funkcje grow_buffers()
. Funkcja ta probuje zwiekszyc liczbe
buforow podanego rozmiaru
Jesli funkcji grow_buffers()
udalo sie stworzyc nowe bufory, to
zmniejszamy zapotrzebowanie na pamiec (needed
) i wracamy do punktu 2.
needed
<= 0) jesli tak,
to konczymy funkcje refill_freelist()
.
refill_freelist
.
Wyszukiwaniem zbednych buforow i usuwaniem ich zajmuje sie funkcja
maybe_shrink_lav_buffers()
, zas tworzeniem nowych funkcja grow_buffers()
.
b_lru_time
naglowka bufora).
Usuwamy go z kolejki lru i haszujacej, nastepnie wstawiamy do kolejki
buforow wolnych.
Wybieramy nastepnego kandydata dla kolejki, z ktorej wybralismy zwyciezce.
Sprawdzamy czy mamy juz dosyc wolnych buforow. Jesli tak, to konczymy
funkcje, jesli nie to wracamy do elekcji.
grow_buffers()
jesli tylko liczba wolnych
stron pamieci jest o piec wieksza niz minimalna liczba wolnych stron
( min_free_pages
). Jesli udalo sie, to wracamy do punktu piatego.
grow_buffers()
z wiekszym priorytetem, niz do tej pory.
Jesli i to zawodzi, to budzimy proces bdflush (zapisuje brudne bufory),
a sami zasypiamy czekajac na zakonczenie jego dzialania.
grow_buffers()
grow_buffers()
probuje zwiekszyc liczbe dostepnych buforow
podanego rozmiaru.
DEFINICJA: int grow_buffers(int pri, int size) WYNIK: 1 w przypadku sukcesu 0 wpp
get_free_page()
, wywolujac ja
z priorytetem podanym w parametrach (pri
).
Jesli to sie nie uda, to zwraca zero.
create_buffers()
, podajac w parametrach pobrana strone
oraz rozmiar bufora. Funkcja ta stworzy nam bufory, ktorych dane beda
umieszczane na podanej stronie.
create_buffers()
.DEFINICJA: struct buffer_head* create_buffers(unsigned long page, unsigned long size) WYNIK: wskaznik do naglowka bufora NULL jesli nie udalo sie stworzyc buforyFunkcja
create_buffers()
tworzy bufory podanego rozmiaru, ktorych dane
przechowywane beda na dostarczonej (jako parametr funkcji) stronie pamieci.
Dokladniej dopoki jest miejsce na stronie pamieci pobiera nieuzywany naglowek
bufora (funkcja get_unused_buffer_head()
), a nastepnie przydziela mu (pole
b_data
naglowka) kolejny kawalek strony. Otrzymane bufory laczymy w liste
przez pola b_this_page
w naglowku bufora. Zwracamy pierwszy bufor z tej listy.
get_unused_buffer_head()
DEFINICJA: buffer_head* get_unused_buffer_head(void) WYNIK: wskaznik do naglowka bufora NULL jesli nie udalo sie pobrac naglowka buforaFunkcja
get_unused_buffer_head()
dostarcza nieuzywany naglowek bufora.
Jesli nie ma nieuzywanych naglowkow, ktore sa trzymane na liscie unused_list
,
to probujemy je stworzyc. W tym celu pobieramy wolna strone pamieci i tworzymy
na niej naglowki buforow. Jesli to sie nie uda (mamy za malo pamieci), to
zasypiamy w oczekiwaniu na zwolnienie jakiegos naglowka.
maybe_shrink_lav_buffers()
.DEFINICJA: int maybe_shrink_lav_buffers(int size) WYNIK: 1 w przypadku sukcesu 0 wppFunkcja
maybe_shrink_lav_buffers()
wybiera bufory (dokladniej rozmiar buforow),
o rozmiarze roznym niz podany w parametrze, ktore byly stosunkowo rzadko
uzywane. Nastepnie probuje zwolnic jedna strone pamieci, zajmowana przez te
bufory (korzystajac z funkcji shrink_specific_buffers()
).
shrink_specific_buffers()
.shrink_specific_buffers()
probuje zwolnic jedna strone pamieci
zajmowana przez bufory rozmiaru podanego w parametrach.
DEFINICJA: int shrink_specific_buffers(unsigned int priority, int size) WYNIK: 1 w przypadku sukcesu 0 wpp
Uwaga
Dzialanie tej funkcji opisalem dla wywolania przez funkcje maybe_shrink_lav_buffers()
,
czyli z priorytetem (pri
) rownym 6.