					FAIL-SYSTEM

SCOPO DEL PROGETTO:

scrittura di un modulo di file system che utilizza un file in memoria secondaria
come supporto per la memorizzazione.


ORGANIZZAZIONE DEL PROGETTO:

Il progetto e' organizzato in 3 file eseguibili:
	- mkfs.fail:  tool per creare la struttura dati vuota
	- failsystem: eseguibile che permette di utilizzare
		      la struttura tramite fuse
	- fsck.fail:  tool per il controllo sulla coerenza dei dati
Per la sintassi di utilizzo basta lanciare gli eseguibili senza parametri, verra'
stampato un help.
Il codice e' stato sviluppato utilizzando gli autotools gnu, per l'installazione
e' quindi sufficiente dare i comandi "./configure", "make" e "make install".
Non sono previsti file di configurazione ne' script.


ARCHITETTURA DI FAIL-SYSTEM:

Fail-system e' un processo ordinario basato su fuse.
Il filesystem e' stato organizzato utilizzando un tabella di allocazione (FAT);
lo spazio non occupato e' gestito tramite una lista libera, che si integra
perfettamente con la gestione fat.
La struttura dati su disco viene memorizzata in questo modo:

        +--------------------------------------------------+
        |     0      |  1 ... 5  |     6 7 ........        |
	+--------------------------------------------------+
        | superblock |    fat    |           data          |
        +--------------------------------------------------+

Il superblock contiene informazioni sulle proprieta' del filesystem (e.g. blocksize)
ed anche la root directory entry (vedi sotto).

La FAT e' un vettore di interi, vi e' una corrispondenza diretta tra la posizione del
vettore ed il blocco fisico. Ad esempio, seguendo il diagramma di cui sopra, il vettore
fat avra' le prime 6 posizioni inutilizzate in quanto non corrispondono a blocchi dati.

Un file (o una directory) e' memorizzato in una lista di blocchi, ogni intero della tabella
di allocazione contiene il numero del blocco dati successivo che fa parte dello stesso file,
l'ultimo blocco di un file avra' quindi riferimento al blocco 0.

Una directory e' composta da una lista di directory entry strutturate come segue:

        +---------------------------------------+
        |  name  |     stat    |    block ptr   |
        +---------------------------------------+

La root directory presenta un'eccezione in quanto la sua directory entry (descrizione)
viene memorizzata nel superblock, i contenuti invece vengono trattati normalmente come
descritto sopra.


STRUTTURA CODICE SORGENTE:

- failsystem.h
	headers comuni a tutto il progetto
- mkfs.fail.c
	codice relativo all'eseguibile mkfs.fail
- fsck.fail.c
	codice relativo all'eseguibile fsck.fail
- ioctl.c
	funzioni per la scrittura a "basso livello" sulla struttura dati, permettono di
	astrarre dagli accessi sequenziali (read/write) un'interfaccia in grado di gestire
	la fat ed i blocchi
- helper.c
	funzioni di "livello intermedio", vengono invocate dalle funzioni di interfaccia
	di fuse e permettono di astrarre dalla struttura a fat/blocchi un sistema di gestione
	dei file e delle directory entry.
- failsystem.c
	programma principale, contiene tutte le funzioni di interfaccia passate a fuse
	attraverso una struttura di puntatori a funzione
- failutils.c
	raccolta di funzioni di utilita'


PROBLEMATICHE RISCONTRATE DURANTE LA PROGETTAZIONE:

P: L'architettura iniziale prevedeva l'allocazione di un blocco per ogni directory entry
  (una directory era in sostanza una lista di puntatori a blocchi). Questo comportava
  un elevato spreco di spazio, ma soprattutto l'impossibilita' di poter gestire i file
  e le directory con un'unica funzione e quindi aumentava la complessita' del codice.
S: E' stata ristrutturata la directory come un semplice file che contiene tutte le
   directory entry figlie.

P: Nell'eliminazione di una directory entry, non avendo una struttura dati di tipo lista,
   si formavano dei "buchi" nel file che rappresenta la directory padre.
S: E' stato introdotto un sistema di deframmentazione al momento della cancellazione di
   una directory entry.

P: Lentezza nell'accesso alla fat su disco in quanto richiedeva un elevato numero di seek su file.
S: E' stata mappata la fat in memoria ed e' stata aggiunta una classe di funzioni per
   gestire il caricamento e l'aggiornamento della fat su memoria secondaria.

P: Lentezza nelle operazioni di lettura/scrittura su file. Originariamente ogni funzione
   invocata da fuse prevedeva una ricerca su memoria secondaria della directory entry.
S: E' stata introdotta una struttura contenente informazioni su di un file aperto.
   Sfruttando l'handle passatoci da fuse (fuse_file_info->fh) nell'invocazione di una open
   siamo riusciti a tener traccia del file aperto eseguendo cosi' un'unica lookup al momento
   dell'apertura del file.

P: Creazione degli hard-link (unsolved).
S: La gestione degli hard link prevede un "contatore di riferimenti" al blocco iniziale
   di un file. L'introduzione di questo contatore avrebbe cambiato notevolmente la struttura
   dati e, di conseguenza, tutta l'architettura del progetto.


