Opis działania funkcji bread()
Spis treści
Funkcja bread służy do uzyskania żądanego bloku danych.Algorytm funkcji bread() w skrócie polega na sprawdzeniu, czy żądany blok jest w puli buforów; jeśli go nie ma to zostaje sprowadzony z dysku.
Parametry wejściowe: numer żądanego bloku w systemie plików.
Zwracana wartość: bufor zawierający dane lub NULL w przypadku niepowodzenia .
Kod źródłowy funkcji znajduje się w pliku fs/buffer.c
Kod źródłowy opatrzony komentarzami można znaleźć tutaj
Nagłówek funkcji ma postać: struct buffer_head * bread(kdev_t dev, int block, int size)
Parametry funkcji:
Funkcja jest wywoływana w momencie zapotrzebowania na blok dyskowy. Pierwszym krokiem jest wywołanie algorytmu getblk() do odszukania bloku w puli buforów. Algorytm zwraca wskaźnik do nagłówka żądanego bufora w przypadku znalezienia go w puli buforów lub wskaźnik do nagłówka nowego bufora w przypadku niepowodzenia. Zmienna bh jest zmienną pomocniczą w której przechowujemy nagłowek bufora. Jej typem jest struct buffer_head *. W przypadku niepowodzenia getblk(), co raczej nie powinno się zdarzyć, zwracany jest NULL. (W funkcji getblk() nie ma explicite powrotu z NULL jako zwracaną wartością.) Należy teraz zbadać, czy zwrócony przez getblk() wskaźnik do nagłowka bufora dotyczy bufora z aktualnymi danymi, czy też nowego bufora (w zależności od skutków poszukiwania). Dokonuje tego funkcja buffer_uptodate(). Jeśli dane są aktualne bufor zwracamy. W przeciwnym przypadku inicjujemy odczyt żądanego bloku z dysku wywołując niskopoziomową funkcję ll_rw_block(). Wywołanie ma postać: ll_rw_block(READ, 1, &bh);. Po zinicjowaniu podprogramu obsługi dysku funkcja bread() zasypia w oczekiwaniu na zdarzenie zakończenie wejścia-wyjścia, wywołując funkcję wait_on_buffer(). Po przebudzeniu konieczne jest sprawdzenie, czy odczytane dane są aktualne. Zabezpiecza to przed błędem operacji dyskowych. Jeśli wszystko się powiodło zwracamy to zwracamy bufor. W przeciwnym przypadku zwalniamy bufor (oznaczony przez getblk() jako używany) funkcją brelse() i zwracamy NULL.
static inline int buffer_uptodate(struct buffer_head * bh)
{ return test_bit(BH_Uptodate, &bh->b_state); }
void ll_rw_block(int rw, int nr, struct buffer_head * bh[]);
Opracował: Jarosław Wawszczak