Do spisu treści systemu plików
Opis realizacji operacji odczytu i zapisu
w systemie plików FAT
Operacje odczytu i zapisu, realizujące interfejs pomiędzy procesem
w systemie Linux a systemem plików FAT w kilku szczegółach istotnie
różnią się od swoich odpowiedników obsługujących system ext2.
Oto lista najistotniejszych różnic, które warto skonfrontować z
komentarzami do kodu źródłowego tych funkcji:
Podział na pliki binarne i tekstowe
Odmienny format zapisu tekstu i konieczność konwersji
Upakowywanie plików w sektorach sprzętowych
Pliki w systemie MsDOS mogą być binarne lub tekstowe. Informacja
o tym, jakiego rodzaju jest dany plik zawarta jest w deksyptorze
pliku (struktura "file"). Informacja ta nie jest zapisana w
strukturach systemu plików FAT. Linux automatycznie rozpoznaje
typ pliku podczas otwierania go (por. funkcja open()).
Konsekwencją podziału na te dwa rodzaje plików jest odmienne
ich traktowanie przez funkcje
fat_file_read() oraz
fat_file_write().
Występują tu dwie istotne różnice.
Pierwsza jest wynikiem odmienności formatów zapisu tekstu w
systemach Linux i MsDOS. W systemie Linux znakiem końca wiersza
jest linefeed i nie ma żadnego szczególnego oznaczenia końca
pliku. W systemie MsDOS wiersz kończy się sekwencją
carriage-return i linefeed, a koniec pliku zaznacza się znakiem
ctrl-Z. Przy zapisie i odczycie plików tekstowych Linux
dokonuje konwersji "w locie" wewnątrz funkcji
fat_file_read() i
fat_file_write().
Dane są kopiowane z buforów dyskowych
do bufora dostarczonego przez użytkownika i na odwrót znak po
znaku (używa się w tym celu funkcji get_user() oraz
put_user()). W przypadku plików binarnych nie ma żadnej
filtracji i dane kopiowane są blokami z użyciem funkcji
memcpy_tofs() i memcpy_fromfs().
Druga istotna różnica dotyczy wczytywania bloków z wyprzedzeniem.
Zakłada się, że rozmiar bloku do odczytania, przekazany jako
parametr do funkcji read(), w przypadku pliku binarnego
jest podany dokładnie, użytkownik życzy sobie wczytania dokładnie
takiej porcji danych, jaką wskazał. Dlatego za pierwszym razem,
kiedy funkcja read() wywoływana jest na rzecz pliku
binarnego, nie dokonuje się wczytywania z wyprzedzeniem. Natomiast
jeśli użytkownik ponownie zażąda danych z tego pliku, mechanizm
wczytywania z wyprzedzeniem zostanie uaktywniony.
W przypadku plików tekstowych zakłada się, że użytkownik wczytuje
dane małymi porcjami i z góry nie wiadomo, ile danych docelowo
będzie chciał wczytać, dlatego pliki tekstowe zawsze wczytywane
są z wyprzedzeniem.
Kolejna istotna różnica wynika z dość nieporadnego sposobu
postępowania systemu MsDOS z nietypowymi nośnikami danych.
Jeżeli sektory sprzętowe dysku są duże, MsDOS może stworzyć
na nim partycję z clusterami mniejszymi niż sprzętowe sektory.
Ta patologiczna sytuacja rodzi wiele problemów, przede wszystkim
problem zmniejszenia wydajności pracy z dyskiem, ponieważ
system zmuszony jest odczytywać niepotrzebnie większe porcje
danych. Nieco więcej informacji na ten temat znajduje się w
komentarzach do funkcji
fat_bread().
Innych większych różnic nie ma. W szczególności funkcje
te korzystają z tego samego podsystemu obsługi puli buforów
co funkcje systemu ext2, zaś osobne funkcje do obsługi buforów,
zdefiniowane m.in. w pliku "fs/buffer.c", są potrzebne
tylko po to, aby poprawnie radzić sobie z patologicznym
przypadkiem systemu FAT na nośniku z dużymi sektorami
(por. komentarze do kodu tych funkcji) i nie zawierają żadnego
elementu istotnie nowego w stosunku do standardowych funkcji
do obsługi buforów, z których korzystają.
Autor: Krzysztof Ostrowski