JFFS

Z Wikipedii, wolnej encyklopedii

Journalling flash File System (lub JFFS) – system plików o strukturze dziennika, używany w urządzeniach pamięci flash typu NOR w systemie operacyjnym Linux. Jego następcą jest JFFS2.

Projekt[edytuj | edytuj kod]

Pamięć flash posiada liczne ograniczenia, nie występujące w przypadku klasycznych urządzeń do przechowywania danych, takich jak dyski magnetyczne. W szczególności usuwanie danych z pamięć Flash:

  • jest konieczne przed każdym zapisem
  • jest powolne (w porównaniu z innymi typami pamięci)
  • musi być wykonane dużymi segmentami (zwykle o rozmiarze 64KB lub większym)
  • może zostać przeprowadzone tylko pewną ograniczoną z góry liczbę razy (zwykle poniżej miliona)

Systemy plików takie jak ext2 zwykle aktualizują swoje struktury danych w miejscu: takie struktury jak i-węzły są aktualizowane na dysku po każdej modyfikacji. Brak procesu równoważenia zużycia sprawia, że tradycyjne systemy plików nie są odpowiednie do zastosowania w urządzeniach typu flash umożliwiających zarówno zapis, jak i odczyt.

JFFS wymusza równoważenie zużycia w ten sposób, że traktuje urządzenie flash jako cykliczny plik zawierający dziennik. Każda zmiana dotycząca plików czy katalogów jest zapisywana na końcu takiego pliku w postaci "węzła". W każdym węźle w pierwszej kolejności zapisywany jest nagłówek zawierający metadane, następnie zaś zapisywane są dane, jeśli takie istnieją. Węzły rozpoczynają swój czas życia jako "ważne", a gdy tworzona jest ich nowsza wersja, stają się "unieważnione".

Wolną przestrzeń w systemie plików stanowi przerwa między początkiem pliku dziennika oraz jego końcem. Kiedy jest jej bardzo mało, garbage collector kopiuje ważne węzły z początku pliku dziennika na jego koniec, pomijając węzły unieważnione, i odzyskuje w ten sposób przestrzeń do ponownego użycia.

Format danych[edytuj | edytuj kod]

W JFFS istnieje jeden typ węzła, reprezentowany przez strukturę jffs_raw_node; każdy taki węzeł skojarzony jest z dokładnie jednym i-węzłem i składa się z nagłówka oraz, opcjonalnie, pewnych danych. Nagłówek zawiera:

  • numer i-węzła, z którym węzeł jest skojarzony
  • pozostałe metadane dotyczące i-węzła, takie jak uid, gid, mtime, atime itp.
  • nazwę i-węzła, z którym węzeł jest skojarzony
  • numer i-węzła będącego rodzicem i-węzła, z którym węzeł jest skojarzony
  • (tylko, jeśli dane są obecne) przesunięcie, pod którym w pliku rozpoczynają się dane

Węzły reprezentujące zmiany dotyczące pewnego i-węzła są uporządkowane: każdy z nich zawiera dodatkowo numer wersji version, będący liczbą 32-bitową; oznacza to, że podczas całego życia systemu plików teoretycznie możliwe jest zapisanie 4 miliardów węzłów dotyczących pojedynczego i-węzła.

Ze względu na to, że istnieje ograniczenie rozmiaru węzła, w przypadku dużych plików do ich zapisu wykorzystanych jest wiele węzłów, z których każdy przechowuje tylko fragment danych pliku (oraz informację o przesunięciu względem jego początku).

Działanie[edytuj | edytuj kod]

Podczas montowania systemu plików każdy z węzłów jest odczytywany i interpretowany. Dane przechowywane w węzłach są wystarczające do tego, aby odtworzyć zarówno hierarchię katalogów jak i odwzorowanie każdego i-węzła w odpowiadająca mu lokalizację na fizycznym nośniku. Tworzone podczas montowania struktury danych są dostępne przez cały czas zamontowania, dzięki czemu każde żądanie przeszukania katalogu jest wykonywane natychmiastowo; podobnie szybko wykonywane są odczyty z plików do przygotowanych buforów - znane są ich dokładne lokalizacje na fizycznym nośniku.

Zmiana metadanych (np. praw czy właściciela pliku) odbywa się przez zapisanie nowego węzła na końcu dziennika; zmiana danych w pliku odbywa się podobnie, przy czym zapisywany nowy węzeł będzie dodatkowo posiadał dane. Węzły zawierające dane z zakresu pokrytego również przez późniejsze węzły, jak również węzły nie posiadające danych, a których metadane zostały zdezaktualizowane przez późniejsze węzły, są węzłami "unieważnionymi". Przestrzeń zajęta przez "unieważnione" węzły nazywana jest "brudną przestrzenią", której odzyskiwaniem zajmuje się garbage collector.

Garbage collection[edytuj | edytuj kod]

Odzyskiwanie "brudnej przestrzeni" może mieć miejsce w dwóch sytuacjach:

  • w kontekście wątku jądra, gdy jądro próbuje uzyskać wolną przestrzeń zanim ta będzie potrzebna
  • w kontekście procesu użytkownika, gdy na nośniku nie ma wystarczającej ilości miejsca potrzebnego do zakończenia operacji zapisu

Celem garbage collectora jest skasowanie (wyczyszczenie) pierwszego bloku pamięci flash. Analizuje on w tym celu wszystkie węzły począwszy od "głowy" dziennika, czyli od najstarszego węzła. Węzły "unieważnione" ignoruje, natomiast węzły ważne "unieważnia", zapisując wcześniej ich ważne wersje w "ogonie" dziennika. W ten sposób uzyskuje blok zawierający same unieważnione węzły - ten blok zostanie skasowany i będzie dostępny dla nowych węzłów w "ogonie" dziennika.

Warunkiem takiego działania garbage collectora jest pewna ilość wolnego miejsca, w którym mogą być tworzone nowe wersje unieważnianych węzłów (w przypadku pesymistycznym wszystkie węzły w bloku są ważne). Doświadczalnie ustalono, że wystarczającą ilością wolnego miejsca, które system plików musi zapewnić garbage collectorowi, to cztery sektory pamięci flash.

Wady[edytuj | edytuj kod]

  • W momencie montowania kod montujący system plików musi przeczytać cały łańcuch węzłów i wczytać go do pamięci. Może to być bardzo czasochłonne. Dodatkowo, zużycie pamięci w systemie plików JFFS jest proporcjonalne do liczby plików.
  • Zaprojektowanie systemu plików jako cyklicznego dziennika oznacza, że wszystkie dane są przepisywane z miejsca na miejsce, niezależnie od tego, czy są one statyczne, czy nie (np. biblioteki dzielone, kod wykonywalny itp). Powoduje to wiele niepotrzebnych cykli kasowania danych, przez co czas życia urządzenia flash zostaje znacznie zredukowany.
  • JFFS nie umożliwia kompresji danych, co ze względu na wysoki koszt pamięci flash stanowi istotną wadę
  • System plików nie umożliwia tworzenia "twardych" linków

Rozwój[edytuj | edytuj kod]

JFFS był początkowo używany przez szwedzką firmę Axix Communications w urządzeniach pracujących z Linuksem w wersji 2.0; po udostępnieniu kodu źródłowego JFFS został włączony do jądra 2.3. Red Hat zapewnił komercyjne wsparcie klientowi w linii 2.2 jądra.

Bibliografia[edytuj | edytuj kod]

Zobacz też[edytuj | edytuj kod]

Linki zewnętrzne[edytuj | edytuj kod]