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