Zadanie 4: Powrót bufora zapisów

Data ogłoszenia: 02.06.2020

Termin oddania: 08.09.2020 (brak możliwości spóźnienia)

Materiały dodatkowe

Wprowadzenie

Syscall mmap z MAP_SHARED jest starym i dobrze przyjętym narzędziem do modyfikacji plików. Ma jednak poważny problem: gdy program zacznie modyfikować plik i napotka błąd na którymś etapie, nie jest w stanie łatwo przywrócić pliku do stanu początkowego, powodując istnienie częściowo zmodyfikowanego pliku.

Zadanie

Napisać modyfikację do jądra pozwalającą na użycie mapowań MAP_PRIVATE jako “bufora zapisów”, które następnie będzie można zaaplikować na plik, gdy poprosi o to użytkownik, bądź też odrzucić.

Nowa funkcjonalność powinna być obsługiwana przez nowe flagi do syscalla msync:

#define MS_DISCARD      0x08 /* odrzuca wszystkie zmiany na mapowaniu MAP_PRIVATE, przywraca do stanu z dysku */
#define MS_COMMIT       0x10 /* aplikuje wszystkie zmiany na mapowaniu MAP_PRIVATE do pliku */
#define MS_MAKE_SHARED  0x20 /* zmienia typ istniejącego mapowania na MAP_SHARED */
#define MS_MAKE_PRIVATE 0x40 /* zmienia typ istniejącego mapowania na MAP_PRIVATE */

Wspierane kombinacje nowych flag powinny być następujące:

  • MS_DISCARD (na MAP_PRIVATE): kasuje zmiany użytkownika

  • MS_COMMIT (na MAP_PRIVATE): aplikuje zmiany użytkownika

  • MS_DISCARD | MS_MAKE_SHARED (na MAP_PRIVATE): kasuje zmiany użytkownika, po czym konwertuje mapowanie w MAP_SHARED)

  • MS_COMMIT | MS_MAKE_SHARED (na MAP_PRIVATE): aplikuje zmiany użytkownika, po czym konwertuje mapowanie w MAP_SHARED)

  • MS_MAKE_PRIVATE (na MAP_SHARED): konwertuje mapowanie w MAP_PRIVATE

Nowe flagi można łączyć z już istniejącymi flagami — w tym wypadku akcja związana z nowymi flagami powinna zostać wykonana w pierwszej kolejności.

Operacja msync powinna wciąż działać tylko na zakresie stron podanym jako parametr — może to oznaczać wykonanie operacji na wielu mapowaniach, bądź na części mapowania. W szczególności, wynikiem operacji MS_MAKE_* może być “pocięcie” istniejącego mapowania na dwa (lub trzy) różne mapowania o różnych typach.

Rozwiązanie powinno działać co najmniej na zmapowanych plikach z systemów plików tmpfs oraz ext4 (bez opcji DAX). W przypadku wywołania operacji na nieobsługiwanym systemie plików, należy zwrócić błąd -EINVAL.

Zasady oceniania

Za zadanie można uzyskać do 10 punktów. Na ocenę zadania składają się dwie części:

  • wynik testów (od 0 do 10 punktów)

  • ocena kodu rozwiązania (od 0 do -10 punktów)

Punktacja

Punkty ujemne za kod można było dostać za:

  1. Brak README (-0.1)

  2. Brak zwracania błędu w przypadku wywołania COMMIT na pliku readonly (-0.1)

  3. Brak zwracania błędu przy nieobsługiwanym fs (w przypadku niepełnej obsługi; np 9p) (-0.1)

  4. Brak zwracania błędu przy nieprawidłowej kombinacji flag (MS_DISCARD | MS_COMMIT) (-0.1)

  5. Mieszanie warstw abstrakcji – wywoływanie vfs_write z wnętrza sterownika ext4 (-0.0)

Forma rozwiązania

Jako rozwiązanie należy wysłać paczkę zawierającą:

  • patcha na jądro w wersji 5.5.5, w jednym z następujących formatów:

    • patch wygenerowaniy przez diffa z opcjami -uprN nakładający się przez patch -p1

    • git format-patch

  • krótki opis rozwiązania

Paczka powinna nazywać się ab123456.tar.gz (gdzie ab123456 jest loginem na students) i po rozpakowaniu tworzyć katalog ab123456 ze źródłami. Rozwiązania prosimy nadsyłać na adres p.zuk@mimuw.edu.pl z kopią do mwk@mimuw.edu.pl. Prosimy o umieszczenie [ZSO] w tytule wiadomości.

Wskazówki

Ponieważ implementacja części operacji może zależeć od systemu plików, proponujemy następujący schemat:

  • dodać nowe pole w vm_operations_struct na nową operację

  • zaimplementować ją dla tmpfs i ext4

  • w msync wywołać tą operację przez vm_operations_struct, bądź zwrócić -EINVAL, jeśli odpowiednie pole jest równe NULL