System plików

Zadanie dla studentów


    Moduł do obsługi podręcznej pamięci buforowej w systemie Linux korzysta z tych samych stron pamięci, co pozostałe procesy. Zasadniczą jego cechą jest to, że na buforowanie bloków dyskowych pobiera tyle pamięci, ile jest aktualnie dostępne (z drobnym tylko ograniczeniem).

    Dokładniej: jeśli zajdzie potrzeba na buforowanie bloku dyskowego, którego nie ma jeszcze w pamięci buforowej, a lista buforów ,,wolnych'' będzie pusta, to pierwszym krokiem systemu będzie próba zarezerwowania nowej strony pamięci (funkcja refill_freelist).

    Strategia taka prowadzi do zajęcia bardzo dużej części pamięci przez pamięć buforową. Jeśli inne procesy zgłoszą zapotrzebowanie na pamięć, to zachodzi potrzeba zwolnienia stron z użytkowania przez bufory. System musi poświęcić na to pewną ilość czasu.

    Zachodzi pytanie, czy strategia stosowana w Linuxie jest zawsze korzystna. Może lepiej byłoby ograniczyć pamięć, którą mogą wypełnić bufory.

    Niech ,,trafienie'' oznacza wywołanie funkcji getblk, dla którego żądany blok znajduje się już w pamięci. Skuteczność podręcznej pamięci buforowej możemy mierzyć ilością trafień w stosunku do ogólnej liczby wywołań funkcji getblk.

    Jeżeli procent trafień zależy liniowo od pamięci przeznaczonej na pamięć buforową, to oczywiście ograniczenie tej pamięci zawsze będzie wiązać się z pogorszeniem efektywności systemu:



    Jeżeli jednak narastanie nie jest liniowe, ale np. takie:

to obcięcie pamięci przeznaczonej na buforowanie na poziomie np. p0 (zaznaczonym linią przerywaną) nie powinno osłabić zbytnio efektu buforowania, a rzadziej trzeba by było zwalniać strony zajmowane przez bufory.

    Oczywiście badanie procenta trafień powinno odbywać się przy jakimś ustalonym użytkowaniu systemu, tzn. przy działaniu tych samych programów w tym samym przedziale czasu.



    Tematem zadania jest:

    Podpunkt a) powinien być zrealizowany tak, aby umożliwiać zmianę ograniczenia pamięci z poziomu użytkownika, tzn. bez ponownej kompilacji jądra.



    Wskazówki:

    1. Jak umożliwić przesyłanie parametrów do działającego systemu:

    Można to oczywiście zrobić na wiele sposobów, ten opisany poniżej jest chyba najprostszy, choć nieelegancki. Przesyłanie danych nie jest jednak głównym tematem zadania.

    Jedną z funkcji, którą udostępnia moduł obsługujący pamięć buforową jest fsync, która wymusza zapisanie pliku na dysk. Taki jest jej nagłówek:

   asmlinkage int sys_fsync(unsigned int fd);

    Argument fd jest numerem deskryptora, więc jest zawsze mniejszy niż 20. Proponuję, aby dla wartości większych od 20 funkcja wykonywała jakąś nową (naszą) procedurę. Początek funkcji sys_fsync mógłby wyglądać tak:

   asmlinkage int sys_fsync(unsigned int fd)
   {
      if (fd>;20) { zrób_coś_nowego(fd); return NULL; };
      ...
   }

    Po skompilowaniu i uruhomieniu tak wyglądającego jądra możemy wywołać funkcję zrób_coś_nowego uruchamiając np. taki program napisany w C:

   main() {
      fsync(123);
   };             


   

 2. Jak wyświetlać informacje dotyczące jądra:

    Wywołanie przez jądro procedury:

  write_tty_message(current->;tty, "Tekst, np. zmienna typu char* \r\n");

    spowoduje wypisanie odpowiedniego napisu na ekranie użytkownika.



autor: Tomasz Bogusławski