read:
DEFINICJA:
int read(unsigned int fd, char *buf, unsigned int count );
WYNIK: liczba wczytanych bajtow,
0 w przypadku napotkania na koniec pliku,
-1 w przypadku bledu;
errno =EDEADLOCK(jezeli na plik lub rekordy jest zalozona blokada)
EFAULT(w przestrzeni wirtualnej nie ma zaalokowanego
bufora uzytkownika )
EINVAL(jezeli nie mozemy wywolac funkcji read dla konkreatnego systemu plikow)
{
pobieramy i-wezel korzystajac z deskryptora pliku uzytkownika
sprawdzamy w tablicy plikow prawo do czytania dla pliku
sprawdzamy czy mozemy wywolac read dla konkretnego systemu plikow
upewniamy sie czy nie ma blokady na rekord do czytania(wywolujemy funkcje locks_verivy_area)
upewniamy sie czy struktura danych uzytkownika jest zaalokowana w jego przestrzeni(funkcja verify_area)
dla systemu plikow EXT2 wywolujemy funkcje generic_file_read
}
struct file {
loff_t f_pos; /* pozycja w pliku */
f_rawin; /*rozmiar danych wczytanych w trakcie ostatnio wykonywanego czytania z wyprzedzeniem */
f_ramax; /*aktualny maksymalny rozmiar danych, ktore mozna przeczytac z wyprzedzeniem */
struct file_operations /* operacje na pliku w konkretnym file-systemie */
generic_file_read:
DEFINICJA:
int generic_file _read(struct inode *inode,struct file *filp, char *buf,int count)
WYNIK:
liczba wczytanych bajtow
0 w przypadku napotkania na koniec pliku
-1 w przypadku bledu
errno=ENOMEM(blad przy tworzeniu ramki pamieci)
EIO(blad wejscia-wyjscia)
Parametry buf i count takie same jak w wywolaniu read.
{
Jesli aktualna pozycja w pliku znajduje sie poza obszarem
poprzednio wczytanym z wyprzedzeniem, to ustawiamy pola
f_rawin, f_ramax na 0
W przeciwnym przypadku stierdzamy, ze dostep do pliku jest sekwencyjny
i kontynuujemy czytanie z wyprzedzeniem ustawiajac zmienna reada_ok na 1
Jesli ilosc danych do przeczytania z pliku jest mniejsza niz polowa rozmiaru
ramki pamieci(PAGE_SIZE=4kb) to f_ramax=0
W przeciwnym przypadku jesli ilosc bajtow do przeczytania jest wieksza niz f_ramax
to f_ramax=(ilosc danych do przeczytania)
for(;;)
{
Probujemy znalezc ramke pamieci zawierajaca dane z pliku na aktualnej
pozycji
Jesli udalo sie nam to idziemy do etykiety znaleziono_ramke
Jesli nie to do etykiety nie_znaleziono_ramki
znaleziono_ramke:
Jesli ramka jest aktualna lub zablokowana(np. z powodu zapelniania jej danymi) to
probujemy dostac nastepna ramke wywolujac funkcje generic_file_read
W przeciwnym przypadku pole f_ramax ustawiamy na MIN_READAHEAD
Czekamy na ramke(nie na ta dodatkowa byc moze zwrocona przez generic_file_readahead)
Jesli ramka jest nieaktualna to idziemy do etykiety ramka_blad
Jesli jest aktualna to do etykiety sukces
sukces:
Obliczamy ilosc bajtow, ktore mamy wczytac z ramki
Kopjujemy dane z ramki do bufora uzytkownika
Nie zwalniamy ramki ale zmniejszamy licznik odwolan do niej
Zwiekszamy pozycje w pliku, pozycje w buforze, ilosc przeczytanych bajtow i ilosc bajtow, ktore mamy
do przeczytania o ilosc bajtow przeczytanych z ramki
Jesli nie mamy nic do czytania to wyskocz z petli for
W przeciwnym przypadku idz na poczatek petli for(continue)
nie_znaleziono_ramki:
Jesli nie mamy dodatkowej ramki przeczytanej z wyprzedzeniem to tworzymy nowa ramke (_get_free_page)
i jesli funkcja nie zwrocila bledu to idziemy na poczatek petli for(continue)
W przeciwnym przypadku jesli mamy dodatkowa ramke pamieci to dodajemy ja do kolejki haszujacej
ramek (wywolujemy funkcje add_to_page_cache) a nastepnie wywolujemy funkcje readpage zglaszajac
zadanie zapisania ramki danymi z dysku
Jesli operacja zakonczy sie pomyslnie to idziemy do etykiety znaleziono_ramke
Jesli blad to wyskakujemy z petli for
ramka_blad::
/*znalezlismy ramke ale nie jest aktualna*/
Zglaszamy zadanie zapisu ramki (funkcja readpage)
Jesli wszystko poszlo dobrze to czekamy na ramke (byc moze jest w trakcie zapelniania)
i idziemy do etykiety sukces
W przeciwnym przypadku wyskakujemy z petli for
}/*koniec petli for*/
Jesli mamy dodatkowa ramke to ja zwalniamy
Jesli i-wezel nie jest tylko do odczytu to aktualizujemy czas ostatniego dostepu do i-wezla na aktualny
Zaznaczamy ze i-wezel jest brudny
Zwracamy ilosc przeczytanych bajtow
}/*koniec algorytmu funkcji generic_file_read