Do spisu treści rozdziału 6 

Zadanie laboratoryjne nr 15

Wprowadzenie

W systemie operacyjnym Linux do usuwania dowiązania do pliku służy funkcja systemowa unlink(). W przypadku usuwania ostatniego dowiązania do danego pliku zwalnia ona także (poprzez funkcje iput() i free()) jego bloki danych. Jednakże nie ma funkcji systemowej, która pozwoliłaby w łatwy sposób odzyskać plik, który omyłkowo skasowaliśmy. Tematem poniższego zadania jest zaprojektowanie i zaimplementowanie pewnego mechanizmu, który pozwoliłby odzyskiwać usunięte dowiązania, a w szczególności bloki danych plików.

Opis zadania

W celu stworzenia takiego mechanizmu należy odpowiednio zmodyfikować funkcje systemowe link() i unlink() oraz stworzyć pomocniczą strukturę, w której będziemy przechowywać kopie usuwanych za pomocą unlink() dowiązań. Funkcja unlink() nie może zatrzeć informacji o usuwanym dowiązaniu, a więc trzeba zadbać o zapamiętanie nazwy ścieżkowej pliku i odpowiadającego jej numeru i-węzła w pomocniczej strukturze. Nie może ona też spowodować usunięcia bloków pliku poprzez wywołanie iput() (a więc nie można dopuścić aby w wyniku wywołania unlink() liczba dowiązań do pliku równała się zero).
Funkcja link() wywołana z pierwszym argumentem równym NULL ma służyć do odzyskania (usuniętego za pomocą unlink()) dowiązania do pliku o nazwie określonej przez drugi argument funkcji. Natomiast wywołanie funkcji link() z drugim argumentem równym NULL ma powodować usunięcie kopii dowiązania, które zostało wcześniej usunięte za pomocą unlink() i jest określone przez pierwszy argument funkcji. A więc wywołując link(nazwa_pliku, NULL) tracimy możliwość odzyskania dowiązania nazwa_pliku za pomocą wcześniej opisanego wywołania link(). Z kolei funkcja link() wywołana z obydwoma argumentami różnymi od NULL wykonuje to, co obecnie, a więc tworzy nowe dowiązanie do pliku. Funkcja link() tak jak dotychczas zwraca 0, jeśli wykona się pomyślnie, natomiast w przypadku błędu -1.
Powyższe funkcje muszą być tak zaimplementowane aby spełniały poniższe założenie: jeśli dowiązanie nazwa_pliku zostało usunięte za pomocą wywołania unlink(nazwa_pliku) oraz potem nie wykonano link(nazwa_pliku, NULL), to zawsze można je odzyskać za pomocą link(NULL, nazwa_pliku), o ile w katalogu macierzystym tego dowiązania nie został zapisany nowy plik o nazwie nazwa_pliku. Tak więc jeśli w czasie działania systemu w danym katalogu powstawały i były usuwane (za pomocą unlink()) pliki o tej samej nazwie, to funkcja link() ma odzyskać ostatnio usunięty plik o tej nazwie.
Dodatkowo należy zaimplementować dwa programy uruchamiane z poziomu interpretatora poleceń. Pierwszy z nich o nazwie undelete jest programem uruchamianym bez argumentów i odzyskuje on wszystkie możliwe do odzyskania za pomocą funkcji link() dowiązania w bieżącym katalogu. Natomiast drugi program o nazwie clear ma usuwać przetrzymywane przez nasz mechanizm kopie dowiązań, które zostały usunięte za pomocą unlink() i pochodziły z bieżącego katalogu.

Uwagi

  1. Ta z pozoru dziwna nowa specyfikacja funkcji link() jest spowodowane koniecznością zachowania istniejącego zbioru funkcji systemowych wraz z definicjami ich nagłówków.
  2. Nowe implementacje funkcji link() i unlink() muszą uwzględniać uprawnienia wywołującego je procesu użytkownika.
  3. Wywołanie link(nazwa_pliku, NULL) powoduje tylko i wyłącznie usunięcie kopii dowiązania, które zostało wcześniej usunięte za pomocą unlink(nazwa_pliku).
  4. W celu całkowitego skasowania pliku o nazwie nazwa_pliku z danego katalogu należy przy nowej implementacji posłużyć się sekwencją: unlink(nazwa_pliku); link(nazwa_pliku, NULL).
  5. Mechanizm odzyskiwania plików ma być zrealizowany dla systemu plików EXT2.


Autor: Piotr Niedolistek