Operacje GETBLK, BREAD i BREADA

System plików Linuxa został podzielony na warstwy, dzięki którym jest on bardziej elastyczny i umożliwia swobodne dostosowywanie go do potrzeb użytkownika.

Jedną z tych warstw jest Pamięć Buforowa. Pozwala ona na czytanie i pisanie całych bloków bajtów na urządzenie blokowe. Buforowanie pozwala na czytanie danych z wyprzedzeniem oraz zapisywanie z opóźnieniem. Pozwala to znacząco zwiększyć wydajność systemu.


Bufor składa się z nagłówka (buffer_head) i właściwej zawartości bufora

struct buffer_head		(podstawowe pola struktury danych)

struct buffer_head *b_next;	- wskaźnik na następny bufor w liście w tablicy haszującej
unsigned long b_blocknr;	- numer bloku
unsigned short b_size;		- rozmiar bloku

kdev_t b_dev;			- numer urządzenia (B_FREE oznacza, że bufor jest wolny)
atomic_t b_count; 		- ilość procesów korzystających z bufora

unsigned long b_state;		- mapa bitowa stanu bufora (flagi)

struct buffer_head *b_next_free;	- następny element na liście wolnych buforów(free) / LRU
struct buffer_head *b_prev_free;	- poprzedni element na liście wolnych buforów(free) / LRU
struct buffer_head *b_this_page;	- lista buforów dla danej strony
struct buffer_head ** b_pprev;	- wskaźnik do kolejki haszującej

char * b_data;			- wskaźnik do bloku danych 
struct page *b_page; - strona, do której jest przydzielony bufor
Zaleca się, aby najczęściej wykorzystywane pola nie przekraczały 16 bajtów - zwiększa to wydajność operacji na buforach (np. wyszukiwanie w tablicy haszującej)


Najważniejsze flagi:

BH_Uptodate - czy zawartość bufora zgadza się z zawartością odpowiedniego bloku na dysku
BH_Dirty - czy dane w buforze były modyfikowane
BH_Lock - czy dostęp do bufora jest zablokowany (np. przez operacje wejścia/wyjścia)

Obecnie jest używanych sumie 8 flag.



GETBLK() - Algorytm znajdowania bufora z żądanym blokiem

struct buffer_head * getblk (kdev_t dev, int block, int size)
Parametry wywołania:
- dev     : typu kdev_t (=unsigned short)	- numer urządzenia
- block   : typu int				- numer bloku
- size    : typu int				- rozmiar bufora
Działanie algorytmu:
- Sprawdza w tablicy haszującej, czy dany blok już jest zapamiętany


CIEKAWOSTKA: Jeśli brakuje pamięci, to getblk() powinien się wykrzaczyć.


BREAD() - Blokowe czytanie danych z urządzenia

struct buffer_head * bread (kdev_t dev, int block, int size) 
Parametry wywołania:
- dev     : typu kdev_t (unsigned short)	- numer urządzenia
- block   : typu int				- numer bloku
- size    : typu int				- rozmiar bufora
Przebieg wykonania:
- Wywołuje funkcję getblk() szukającą bufora odpowiadającego danemu urządzeniu, numerowi bloku i jego rozmiarowi
- Sprawdza, czy zwrócony bufor zawiera aktualne dane (sprawdzenie flagi BH_Uptodate):


BREADA() - Blokowe czytanie danych z wyprzedzeniem

Wygląda na to, że breada() nie ma w Linuxie 2.4.7 ...


Przygotowanie: Tomasz Okniński