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
-
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.
-
Nowe implementacje funkcji link() i unlink() muszą uwzględniać
uprawnienia wywołującego je procesu użytkownika.
-
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).
-
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).
-
Mechanizm odzyskiwania plików ma być zrealizowany dla systemu plików
EXT2.
Autor: Piotr Niedolistek