Semestre 7‎ > ‎ISS7AC - OS‎ > ‎Archives‎ > ‎

TD "Systèmes de Fichiers" du 07/11/2016

Objectifs généraux

Dans ce TD nous proposons de réaliser un système de fichiers de type FAT simplifié. Des canevas de code sont fournis en annexe.
Vous n'aurez pas à modifier Device.java, sauf lorsque vous aborderez les questions plus avancées. Vous aurez à modifier ProtoFileSystem.java pour implanter les fonctionnalités demandées, mais les signatures des fonctions fournies devront rester telles quelles. Vous pourrez néanmoins définir d'autres fonctions ou d'autres structures de données en fonction de vos besoins. La sous-classe ProtoFileSystem.FileDescriptor, notamment, pourra être redéfinie et étendue selon vos besoins.

Travail demandé

  1. Prise en main de la classe  Device.java.
    1. Écrire un petit programme de test qui utilise les primitives de  Device.java pour écrire et lire un petit texte dans un bloc d'un Device que vous aurez crée préalablement. Nous considérons ici que le Device n'est pas formaté en système de fichiers; il s'agit uniquement de lire et d'écire des données brutes. Pour cela la documentation de la classe ByteBuffer vous sera utile.
    2. En préparation de la suite du TD, nous allons maintenant supposer qu'un bloc sur le device contient la description d'un dossier du système de fichiers. Comme dans l'item précédent, nous ne considérons toujours pas que le Device est formaté en système de fichiers; il s'agit juste de lire un bloc de données dont la structure répond à un certain nombre de critères.
      En occurence, un dossier est représenté dans un bloc comme une énumération de structures de 32 octets tels que
      • Les octets 0-7 contiennent les 8 lettres du nom du fichier (si le premier caractère est 0x00, l'enregistrement est libre);
      • les octets 8-10 contienent les 3 lettres de l'extension du fichier;
      • l'octet 11 contient les bits d'attributs du fichier (le bit correspondant à 0x08 détermine si le fichier est un répertoire)
      • les octets 20-23 contiennent l'entier correspondant à l'indice du premier bloc du fichier (normalement, les différents octets représentant cette valeur ne sont pas contigus en mémoire, nous les regroupons pour simplifier l'implémentation);
      • les octets 28-31 contiennent l'entier correspondant à la taille du fichier en octets.
      Quelles sont les limites de cette représentation ? (combien de fichiers peut-on stocker dans un bloc, combien de blocs peut-on avoir par fichier, quelle est la taille maximale d'un fichier, est-ce cohérent avec le nombre de blocs ...)

      Écrire une fonction dir(block) qui affiche le contenu d'un tel bloc. Afin de simplifier l'implémentation on pourra considérer que les octets 20-23 représentent un entier signeé (int). Il faudra également faire attention au fait que les caractères (char) sont encodés sur deux octets 
      en Java : la méthode getBytes(Charset charset) de la classe String ainsi que le constructeur String(byte[] bytes, Charset charset) pourront donc être utiles en utilisant le format "UTF-8".
  2. Réalisation d'un système de fichiers de type FAT.
    Dans ce TD nous ne vous demandons pas de gérer des sous-dossiers. À des fins de simplification, le système de fichiers est réduit au seul dossier racine qui ne comporte que des fichiers simples.
    1. Utiliser le canevas fourni ProtoFileSystem.java pour réaliser la fonction format(dev). Cette fonction écrit les données nécessaires dans le Device fourni, de sorte à pouvoir l'utiliser comme système de fichiers. En fonction des propriétés du Device (taille des blocs, taille totale ...) il sera nécessaire de calculer les valeurs et tailles exactes pour chaque élément de la structure de données. De façon générale, on retrouvera la structure suivante :
      1. premier bloc du Device = MBR (Master Boot Record) qui contiendra un certain nombre de données utiles à l'analyse de la structure de données (notamment l'indice du premier bloc de données, etc.)
      2. les blocs suivants contiendront la FAT (File Allocation Table) avec la structure de liste chaînée expliquée ici. Vous pouvez encoder la fin de liste chainé par le nombre -1.
      3. le bloc qui suit la FAT contient le dossier racine (cf. exercice précédent)
      4. les autres blocs sont libres et serviront pour stocker les différents fichiers qui seront créés.
    2. Réaliser la fonction fopen() en mode 'w'. Cette fonction retourne un FileDescriptor qui répertorie (entre autres) le bloc de début du fichier. 
      La fonction va vérifier si le fichier demandé existe déjà ou pas. S'il n'existe pas, il sera crée (une entrée est ajoutée dans le dossier racine, et le premier bloc est alloué dans la
      FAT). S'il existe, son entrée dans le dossier racine n'est pas modifiée, mais sa taille est mise à zéro, et seul son premier bloc est maintenu dans la FAT ; les éventuels autres blocs sont marqués comme libres.
      Tester avec la fonction
      dir() faite précédemment que fopen() fonctionne bien.
    3. Réaliser les fonctions fwrite() et fread() et les tester - il faudra également adapter la fonction fopen() pour prendre en compte le mode 'r' . Vous pourrez également réaliser une fonction del() qui efface un fichier existant.
  3. Pour aller plus loin
    Si cela vous plaît, vous pourrez étendre votre système de fichiers de fonctionalités supplémentaires ... la liste n'est pas exhaustive. Vous pourrez également essayer d'implanter un autre système à base d'i-nodes par exemple.
    1. Tester la cohérence des données (FAT et fichiers)
    2. Gestion des sous-répertoires.
    3. Réaliser des fonctions de copie, déplacer, fwrite() non destructif (permettant, par exemple, d'insérer des données en fin de fichier, ou de modifier des données en milieu de fichier)
    4. Gérer des attributs plus complexes (date de création, date de dernière modification ...)
    5. Supposer que le Device est de type SSD. La particularité des disques SSD est que les cellules de stockage (= blocks) permettent seulement un nombre limité de cycles d'écriture avant de devenir défaillantes. Optimiser la stratégie de sélection de nouveaux blocs pour que l'usure du disque soit la plus homogène possible (i.e. que chaque bloc ait approximativement le même nombre d'opérations d'écriture à son actif à tout moment)
ċ
Device.java
(3k)
Bart Lamiroy,
6 nov. 2016 à 07:09
ċ
ProtoFileSystem.java
(2k)
Bart Lamiroy,
6 nov. 2016 à 11:01
Comments