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