Opracowano poprawki do projektu OpenZFS 2.1.14 i 2.2.2, który rozwija implementację systemu plików ZFS dla Linuxa i FreeBSD. W aktualizacjach rozwiązano problem w kodzie sprawdzania spójności pamięci podręcznej dnode, który prowadził do uszkodzenia danych w plikach zawierających puste obszary podczas ich kopiowania po wprowadzeniu zmian.
Początkowo problem próbowano rozwiązać w wersji 2.2.1, ale poprawka okazała się nieskuteczna. Błąd pozostawał przez długi czas niezauważony i zaczął się ujawniać po zmianach wprowadzonych w narzędziu „cp” w pakiecie coreutils 9.x. Przyjmuje się, że w Red Hat Enterprise Linux i dystrybucjach opartych na nim problem się nie ujawnia, ponieważ w RHEL 9 używany jest pakiet coreutils 8.x z inną logiką działania narzędzia „cp”.
Problem ujawnia się przy użyciu narzędzi do kopiowania plików, które potrafią wykrywać i optymalizować puste obszary w plikach. Uszkodzenie może wystąpić w obciążonych systemach plików przy kopiowaniu pliku, jeśli operacja zostanie wykonana niemal natychmiast po wprowadzeniu zmian, a część danych pozostaje tylko w dirty-cache i nie została jeszcze zrzucona na dysk.
Aby optymalizować pracę z pustymi obszarami w plikach, OpenZFS, począwszy od wydania 0.6.2, wspiera operacje SEEK_HOLE i SEEK_DATA, które pozwalają pominąć pusty obszar pliku podczas odczytu z dysku. Wykrywanie pustych obszarów i zapisywanie informacji o nich odbywa się tylko po zrzuceniu na dysk wszystkich pozostałych w pamięci podręcznej danych związanych z plikiem. W OpenZFS istnieje mechanizm do inicjowania zrzutu, który ocenia obecność w pamięci podręcznej niezapisanych danych i wykonuje wymuszone zrzuty informacji na dysk, co jest konieczne do użycia SEEK_HOLE i SEEK_DATA.
Niestety, kontrola okazała się niekompletna i w wyniku pewnych okoliczności dane dotyczące stanu resetu mogły być źle określone, a na dysku znajdowały się stare informacje o zawartości pliku, jeżeli zapytanie wpadło w małe okno czasowe pomiędzy dwoma operacjami resetowania danych z pamięci podręcznej. Operacje odczytu, optymalizujące ładowanie pustych obszarów, mogły w tym momencie pominąć odczyt części danych, uznając je za puste, podczas gdy program pracujący z plikiem mógł wcześniej wprowadzić zmiany w pustych obszarach. W rezultacie użycie narzędzia „cp” mogło prowadzić do stworzenia kopii zawierającej puste obszary tam, gdzie ich nie było w oryginalnym pliku.
Źródło: opennet.ru
