Aller au contenu principal
Version: 2024

Devoir 2 - Système de Fichiers

Informations générales

info

Date limite: 09 avril, 23:59
Points: 2 points de la note finale
Lien: Devoir 2 - FileSystem
Télécharger en retard: 1 points / jour (maximum 4 jours)

Connaissances évaluées

  • Utiliser le langage Rust
  • Comprendre le mode de fonctionnement du système de fichiers
  • Simuler un système de fichiers

Règles

  1. Le devoir doit contenir un fichier nommé Readme.md avec des explications concernant la manière choisie pour résoudre le devoir (-0.1p)
  2. Le devoir doit être implémenté en Rust et seulement en utilisant des fonctions de la bibliothèque standard Rust. Toute autre implémentation conduira à l'annulation du devoir.(0 points)

Copiage

Le devoir est individuel. Toute tentative de copier entraînera 0p pour les devoirs. On utilisera un système automatisé pour détecter le copiage. Si on a des doutes, on va vous adresser des questions supplémentaires concernant le devoir.

Questions

Si vous avez des questions concernant le devoir, posez-les en publiant un issue sur le github https://github.com/UPB-FILS-SdE2/questions avec le format [filesystem] "le titre de votre question" . Vous aurez besoin d'un compte github pour publier des questions.

danger

NE PUBLIEZ PAS DE CODE SOURCE. Cela est considéré comme copiage et vous aller recevoir 0p pour le devoir.

Si vous voulez recevoir un e-mail lorsque des problèmes sont signalés ou lorsqu'il y a de nouveaux messages, accédez au site github repository et cliquez sur Watch.

Système de Fichiers

Le but de ce devoir est d'implémenter un système de fichiers simplifié similaire à celui utilisé sous Linux. Vous devrez la mettre en œuvre:

  • une structure arborescente qui stocke les fichiers et les dossiers du système de fichiers;
  • une table de descripteurs de fichiers;
  • les fonctions permettant d'accéder au système de fichiers simulé.

Afin de résoudre les devoirs, vous devez stocker et gérer les descripteurs de fichiers internes du système de fichiers personnalisé afin de pouvoir suivre les fichiers ouverts. Vous pouvez gérer cette partie comme vous le souhaitez.

Après cela, vous devez implémenter les opérations de base du système de fichiers qui seront détaillées ci-dessous et mettre à jour la table des descripteurs de fichiers en conséquence.

attention

Vous devez vous assurer qu'après chaque opération le fichier correspondant sera fermé!

Énumération INode

Le système de fichiers a une structure arborescente qui est représentée par l'énumération ci-dessous. Un inode est une donnée structure qui garde une trace de tous les fichiers et répertoires. Chaque fichier et répertoire de notre système de fichiers se voit attribuer un INode. À partir du nœud racine, chaque fois que nous souhaitons créer un nouveau fichier ou dossier dans notre système, nous devons en réalité faire créez un nouvel élément INode avec les informations nécessaires.

Il y a 2 champs dans notre énumération :

  1. Folder - une structure qui représente un dossier dans notre système de fichiers; le contenu est un
    • HashMap qui contient le nom du dossier ou fichier comme clé et les fichiers et répertoires enfants du dossier représenté par INodes;
    • permissions - les autorisations indiquent la lecture/écriture autorisations du dossier
  2. File - une structure qui représente un fichier dans notre système de fichiers;
    • data est un vecteur d'octets qui contient les données à l'intérieur du déposer;
    • permissions - les autorisations indiquent les autorisations de lecture/écriture du fichier

Exemple de système de fichiers INode:

Folder {
contents: {
"folder1": Folder {
contents: {},
permissions: ReadWrite,
},
"file1": File {
data: [],
permissions: ReadWrite,
},
},
permissions: ReadWrite,
}
astuce

Il est conseillé de définir des fonctions dédiées à l'ajout et à la suppression d'INodes car cela rendra ces opérations plus modulaires.

Opérations requises

mount

Cette fonction monte le système de fichiers (crée le nœud racine) qui va être utilisé par les opérations définies dans le Trait du système de fichiers. Il renvoie un un pointeur intelligent (Box) vers une structure qui implémente le trait FileSystem.

pub fn mount(_size: usize) -> Box<dyn FileSystem>

Bonus - limiter la taille du système de fichiers en utilisant le paramètre _size

FileSystem trait

create

Cette fonction créera un fichier s'il n'existe pas et l'ouvrira en mode lecture seule. Il renvoie soit le descripteur de fichier correspondant au fichier spécifié, soit une erreur. Les erreurs suivantes doivent être gérées par cette fonction :

  1. InvalidType si le chemin pointe vers un dossier
  2. PermissionDenied si le répertoire dans lequel nous créons le fichier ne dispose pas des autorisations d'écriture
fn create(
&mut self,
path: &str,
permission_mode: PermissionsMode,
) -> Result<usize, FileSystemError>;
open

Cette fonction tente d'ouvrir un fichier avec les autorisations demandées. Soit il renvoie le descripteur de fichier correspondant pour le fichier spécifié ou une erreur. Les erreurs suivantes doivent être gérées par cette fonction :

  1. FileNotFound si le fichier spécifié par le chemin donné en paramètre n'existe pas
  2. InvalidType si le chemin pointe vers un dossier
  3. PermissionDenied si les autorisations avec lesquelles le fichier a été créé sont compatibles avec les autorisations avec lesquelles nous souhaitons ouvrir le fichier
fn open(&mut self, path: &str, permissions: PermissionsMode) -> Result<usize, FileSystemError>;
close

Cette fonction ferme un fichier ouvert, ce qui signifie qu'elle doit supprimer toutes les informations existantes dont il dispose pour le descripteur de fichier correspondant (fd). Il doit renvoyer l'erreur InvalidFileDescriptor si le descripteur de fichier spécifié ne correspond à aucun fichier ouvert.

fn close(&mut self, fd: usize) -> Result<(), FileSystemError>;
read

Cette fonction lit le contenu du fichier indiqué par le descripteur de fichier, qui est passé en paramètre (fd), et remplit le tampon avec eux. Il renvoie soit le nombre d'octets lus, soit une erreur. Les erreurs suivantes doivent être gérées par cette fonction :

  1. InvalidFileDescriptor si le descripteur de fichier n'est pas valide
fn read(&mut self, fd: usize, buffer: &mut [u8]) -> Result<usize, FileSystemError>;
write

Cette fonction écrit une tranche contenant tout le contenu d'un fichier indiqué par le descripteur de fichier, qui est passé en paramètre (fd). Il renvoie soit le nombre d'octets écrits, soit une erreur. Les erreurs suivantes doivent être gérées par cette fonction :

  1. InvalidFileDescriptor si le descripteur de fichier n'est pas valide
  2. DiskFull s'il n'y a plus d'espace sur le disque (bonus uniquement)
fn write(&mut self, fd: usize, contents: &[u8]) -> Result<usize, FileSystemError>;
dup2

Cette fonction crée une copie du descripteur de fichier spécifié en utilisant le fd spécifié. Il se comporte de manière similaire à dup() sauf qu'il essaiera d'utiliser le fd spécifié au lieu d'en allouer un nouveau. Si new_fd est ouvert, cette fonction le fermera. Les erreurs suivantes doivent être gérées par cette fonction :

  1. InvalidFileDescriptor est old_fd n'existe pas
fn dup2(&mut self, old_fd: usize, new_fd: usize) -> Result<(), FileSystemError>;
remarque

Vous pouvez en savoir plus sur dup et dup2 ici.

seek

Cette fonction déplace le curseur de fichier dans le fichier. Il n'y a pas d'erreur OutOfBounds, la position du fichier sera trucée soit à 0, soit à la taille du fichier. Les erreurs suivantes doivent être gérées par cette fonction :

  1. InvalidFileDescriptor si le descripteur de fichier n'est pas valide
fn seek(&mut self, fd: usize, position: OffsetFrom) -> Result<usize, FileSystemError>;
remarque

Vous pouvez en savoir plus sur seek ici.

file descriptor info

Cette fonction renvoie une référence à la structure FileDescriptorInfo correspondant au paramètre fd. Si le fd n'est pas valide, cette fonction doit renvoyer None.

fn file_descriptor_info(&mut self, fd: usize) -> Option<&dyn FileDescriptorInfo>;
chmod

Cette fonction modifie les autorisations sur un certain fichier/répertoire spécifié par le chemin. Les erreurs suivantes doivent être gérées par cette fonction :

  1. FileNotFound si le fichier au chemin spécifié n'existe pas
    fn chmod(
&mut self,
path: &str,
permissions_mode: PermissionsMode,
) -> Result<(), FileSystemError>;
stat

Cette fonction renvoie la structure FileInfo correspondant au paramètre path. Les erreurs suivantes doivent être gérées par cette fonction :

  1. FileNotFound si le fichier au chemin spécifié n'existe pas
fn stat(&mut self, path: &str) -> Result<FileInfo, FileSystemError>;
mkdir

Cette fonction crée un nouveau répertoire au chemin spécifié. Les erreurs suivantes doivent être gérées par cette fonction :

  1. FileExists si le répertoire existe déjà ou s'il existe un fichier à la place
  2. PermissionDenied si le répertoire parent ne dispose pas d'autorisations en écriture
fn mkdir(&mut self, path: &str) -> Result<(), FileSystemError>;
rmdir

Cette fonction supprime le répertoire spécifié par le chemin uniquement si le répertoire est vide. Les erreurs suivantes doivent être gérées par cette fonction :

  1. DirectoryNotEmpty si le répertoire n'est pas vide
  2. InvalidFiletype si le chemin pointe vers un fichier
  3. PermissionDenied si le répertoire parent ne dispose pas d'autorisations en écriture
fn rmdir(&mut self, path: &str) -> Result<(), FileSystemError>;
rm

Cette fonction supprime le fichier spécifié par le chemin. Le répertoire qui contient le fichier doit disposer des autorisations d'écriture. Les erreurs suivantes doivent être gérées par cette fonction :

  1. InvalidFiletype si le chemin pointe vers un répertoire
  2. PermissionDenied si le répertoire parent ne dispose pas d'autorisations en écriture
fn rm(&mut self, path: &str) -> Result<(), FileSystemError>;
list dir

Cette fonction répertorie tous les fichiers du répertoire spécifié par le paramètre path. Les erreurs suivantes doivent être gérées par cette fonction :

  1. PermissionDenied si le répertoire ne dispose pas d'autorisations de lecture ou de lecture en écriture
  2. FileNotFound si le chemin est inaccessible
  3. InvalidType si le chemin spécifié pointe vers un fichier
fn list_dir(&mut self, path: &str) -> Result<Vec<String>, FileSystemError>;
rename

Cette fonction renomme un fichier de son ancien chemin vers un nouveau chemin spécifié par les paramètres. Le new_path ne devrait pas déjà exister. Les autorisations nécessaires à son fonctionnement sont : Lire dans le répertoire parent, Ecrire dans le répertoire de destination. Les erreurs suivantes doivent être gérées par cette fonction :

  1. FileNotFound si l'ancien chemin n'est pas valide
  2. FileExists si new_path existe déjà
  3. PermissionDenied si les permissions sont compatibles avec celles attendues
fn rename(&mut self, old_path: &str, new_path: &str) -> Result<(), FileSystemError>;

Structures de données

Dans le dépôt de votre travail, lancez cargo doc -open pour ouvrir la documentation.

Exécuter le devoir

Ecrivez un code qui utilise la bibliothèque que vous avez créée pour votre devoir (sde2_fs) dans sde2_fs/src/tests.rs dans la fonction run. Pour l'exécuter, écrivez cargo test run -- --nocapture.