+livello, è opportuno usare sempre gli \textit{stream} per la loro maggiore
+portabilità, essendo questi ultimi definiti nello standard ANSI C;
+l'interfaccia con i \textit{file descriptor} infatti segue solo lo standard
+POSIX.1 dei sistemi Unix, ed è pertanto di portabilità più limitata.
+
+
+% \subsection{Caratteristiche specifiche dei file in Unix}
+% \label{sec:fileint_unix_spec}
+
+% Essendo un sistema multitasking e multiutente esistono alcune caratteristiche
+% specifiche di un sistema unix-like che devono essere tenute in conto
+% nell'accesso ai file. È infatti normale che più processi o programmi possano
+% accedere contemporaneamente allo stesso file e devono poter eseguire le loro
+% operazioni indipendentemente da quello che fanno gli altri processi.
+
+% Per questo motivo le strutture usate per all'accesso ai file sono relative al
+% processo che effettua l'accesso. All'apertura di ogni file infatti viene
+% creata all'interno del processo una apposita struttura in cui sono memorizzati
+% tutti gli attributi del medesimo, che viene utilizzata per tutte le
+% operazioni. Questa è una struttura che resta locale al processo stesso; in
+% questo modo processi diversi possono usare le proprie strutture locali per
+% accedere ai file (che può essere sempre lo stesso) in maniera assolutamente
+% indipendente.
+
+% Questo ha delle conseguenze di cui è bene tenere conto; ad esempio in tutti i
+% sistemi POSIX uno degli attributi di un file aperto è la posizione corrente nel
+% file, cioè il punto nel file in cui verrebbe letto o scritto alla operazione
+% successiva. Essa è rappresentata da un numero intero che indica il numero di
+% byte dall'inizio del file, che viene (a meno che non si apra il file in
+% append) inizializzato a zero all'apertura del medesimo.
+
+% Questo è uno dei dati che viene mantenuto nella suddetta struttura, per cui
+% ogni processo avrà la sua posizione corrente nel file, che non sarà
+% influenzata da quello che altri processi possono fare. Anzi, aprire un file
+% significa appunto creare ed inizializzare una tale struttura, per cui se si
+% apre due volte lo stesso file all'interno dello stesso processo, si otterranno
+% due file descriptor o due stream che avranno ancora una posizione corrente nel
+% file assolutamente indipendente.
+
+% Si tenga conto inoltre che un'altro dei dati contenuti nella struttura di
+% accesso è un riferimento all'inode del file, pertanto anche se il file viene
+% cancellato da un altro processo, sarà sempre possibile mantenere l'accesso ai
+% dati, e lo spazio su disco non verrà rilasciato fintanto che il file non sarà
+% chiuso e l'ultimo riferimento cancellato. È pertanto possibile (come vedremo
+% in dettaglio in \secref{sec:file_link}) aprire un file provvisorio per
+% cancellarlo immediatamente dopo; in questo modo all'uscita del programma il
+% file scomparirà definitivamente dal disco, ma il file ed il suo contenuto
+% saranno disponibili per tutto il tempo in cui il processo è attivo.
+
+% Ritorneremo su questo più avanti in \secref{sec:file_fd}, quando tratteremo
+% l'input/output sui file, esaminando in dettaglio come tutto ciò viene
+% realizzato.
+
+
+\section{L'architettura della gestione dei file}
+\label{sec:file_arch_func}
+
+Per capire fino in fondo le proprietà di file e directory in un sistema
+unix-like ed il comportamento delle relative funzioni di manipolazione occorre
+una breve introduzione al funzionamento gestione dei file da parte del kernel
+e sugli oggetti su cui è basato un filesystem. In particolare occorre tenere
+presente dov'è che si situa la divisione fondamentale fra kernel space e user
+space che tracciavamo al \capref{cha:intro_unix}.
+
+In questa sezione esamineremo come viene implementato l'accesso ai file in
+Linux, come il kernel può gestire diversi tipi di filesystem, descrivendo
+prima le caratteristiche generali di un filesystem di un sistema unix-like,
+per poi trattare in maniera un po' più dettagliata il filesystem standard di
+Linux, l'\acr{ext2}.
+
+% in particolare si riprenderà, approfondendolo sul piano dell'uso nelle
+% funzioni di libreria, il concetto di \textit{inode} di cui abbiamo brevemente
+% accennato le caratteristiche (dal lato dell'implementazione nel kernel) in
+% \secref{sec:file_vfs}.
+
+
+\subsection{Il \textit{Virtual Filesystem} di Linux}
+\label{sec:file_vfs}
+
+% Questa sezione riporta informazioni sui dettagli di come il kernel gestisce i
+% file. L'argomento è abbastanza ``esoterico'' e questa sezione può essere
+% saltata ad una prima lettura; è bene però tenere presente che vengono
+% introdotti qui alcuni termini che potranno comparire in seguito, come
+% \textit{inode}, \textit{dentry}, \textit{dcache}.
+
+In Linux il concetto di \textit{everything is a file} è stato implementato
+attraverso il \textit{Virtual Filesystem} (da qui in avanti VFS) che è uno
+strato intermedio che il kernel usa per accedere ai più svariati filesystem
+mantenendo la stessa interfaccia per i programmi in user space. Esso fornisce
+un livello di indirezione che permette di collegare le operazioni di
+manipolazione sui file alle operazioni di I/O, e gestisce l'organizzazione di
+queste ultime nei vari modi in cui i diversi filesystem le effettuano,
+permettendo la coesistenza di filesystem differenti all'interno dello stesso
+albero delle directory.
+
+Quando un processo esegue una system call che opera su un file, il kernel
+chiama sempre una funzione implementata nel VFS; la funzione eseguirà le
+manipolazioni sulle strutture generiche e utilizzerà poi la chiamata alle
+opportune routine del filesystem specifico a cui si fa riferimento. Saranno
+queste a chiamare le funzioni di più basso livello che eseguono le operazioni
+di I/O sul dispositivo fisico, secondo lo schema riportato in
+\figref{fig:file_VFS_scheme}.
+
+\begin{figure}[htb]
+ \centering
+ \includegraphics[width=7cm]{img/vfs}
+ \caption{Schema delle operazioni del VFS.}
+ \label{fig:file_VFS_scheme}
+\end{figure}
+
+Il VFS definisce un insieme di funzioni che tutti i filesystem devono
+implementare. L'interfaccia comprende tutte le funzioni che riguardano i file;
+le operazioni sono suddivise su tre tipi di oggetti: \textit{filesystem},
+\textit{inode} e \textit{file}, corrispondenti a tre apposite strutture
+definite nel kernel.
+
+Il VFS usa una tabella mantenuta dal kernel che contiene il nome di ciascun
+filesystem supportato: quando si vuole inserire il supporto di un nuovo
+filesystem tutto quello che occorre è chiamare la funzione
+\code{register\_filesystem} passandole un'apposita struttura
+(\var{file\_system\_type}) che contiene i dettagli per il riferimento
+all'implementazione del medesimo, che sarà aggiunta alla citata tabella.
+
+In questo modo quando viene effettuata la richiesta di montare un nuovo disco
+(o qualunque altro \textit{block device} che può contenere un filesystem), il
+VFS può ricavare dalla citata tabella il puntatore alle funzioni da chiamare
+nelle operazioni di montaggio. Quest'ultima è responsabile di leggere da disco
+il superblock (vedi \secref{sec:file_ext2}), inizializzare tutte le variabili
+interne e restituire uno speciale descrittore dei filesystem montati al VFS;
+attraverso quest'ultimo diventa possibile accedere alle routine specifiche per
+l'uso di quel filesystem.
+
+Il primo oggetto usato dal VFS è il descrittore di filesystem, un puntatore ad
+una apposita struttura che contiene vari dati come le informazioni comuni ad
+ogni filesystem, i dati privati relativi a quel filesystem specifico, e i
+puntatori alle funzioni del kernel relative al filesystem. Il VFS può così
+usare le funzioni contenute nel \textit{filesystem descriptor} per accedere
+alle routine specifiche di quel filesystem.
+
+Gli altri due descrittori usati dal VFS sono relativi agli altri due oggetti
+su cui è strutturata l'interfaccia. Ciascuno di essi contiene le informazioni
+relative al file in uso, insieme ai puntatori alle funzioni dello specifico
+filesystem usate per l'accesso dal VFS; in particolare il descrittore
+dell'inode contiene i puntatori alle funzioni che possono essere usate su
+qualunque file (come \func{link}, \func{stat} e \func{open}), mentre il
+descrittore di file contiene i puntatori alle funzioni che vengono usate sui
+file già aperti.
+
+
+\subsection{Il funzionamento del VFS}
+\label{sec:file_vfs_work}
+
+La funzione più importante implementata dal VFS è la system call \func{open}
+che permette di aprire un file. Dato un pathname viene eseguita una ricerca
+dentro la \textit{directory entry cache} (in breve \textit{dcache}), una
+tabella che contiene tutte le \textit{directory entry} (in breve
+\textit{dentry}) che permette di associare in maniera rapida ed efficiente il
+pathname a una specifica \textit{dentry}.
+
+Una singola \textit{dentry} contiene in genere il puntatore ad un
+\textit{inode}; quest'ultimo è la struttura base che sta sul disco e che
+identifica un singolo oggetto del VFS sia esso un file ordinario, una
+directory, un link simbolico, una FIFO, un file di dispositivo, o una
+qualsiasi altra cosa che possa essere rappresentata dal VFS (i tipi di
+``file'' riportati in \tabref{tab:file_file_types}). A ciascuno di essi è
+associata pure una struttura che sta in memoria, e che, oltre alle
+informazioni sullo specifico file, contiene anche il riferimento alle funzioni
+(i \textsl{metodi} del VFS) da usare per poterlo manipolare.
+
+Le \textit{dentry} ``vivono'' in memoria e non vengono mai salvate su disco,
+vengono usate per motivi di velocità, gli \textit{inode} invece stanno su
+disco e vengono copiati in memoria quando serve, ed ogni cambiamento viene
+copiato all'indietro sul disco, gli inode che stanno in memoria sono inode del
+VFS ed è ad essi che puntano le singole \textit{dentry}.
+
+La \textit{dcache} costituisce perciò una sorta di vista completa di tutto
+l'albero dei file, ovviamente per non riempire tutta la memoria questa vista è
+parziale (la \textit{dcache} cioè contiene solo le \textit{dentry} per i file
+per i quali è stato richiesto l'accesso), quando si vuole risolvere un nuovo
+pathname il VFS deve creare una nuova \textit{dentry} e caricare l'inode
+corrispondente in memoria.
+
+Questo procedimento viene eseguito dal metodo \code{lookup()} dell'inode
+della directory che contiene il file; questo viene installato nelle relative
+strutture in memoria quando si effettua il montaggio lo specifico filesystem
+su cui l'inode va a vivere.
+
+Una volta che il VFS ha a disposizione la \textit{dentry} (ed il relativo
+\textit{inode}) diventa possibile accedere alle varie operazioni sul file come
+la \func{open} per aprire il file o la \func{stat} per leggere i dati
+dell'inode e passarli in user space.
+
+L'apertura di un file richiede comunque un'altra operazione, l'allocazione di
+una struttura di tipo \var{file} in cui viene inserito un puntatore alla
+\textit{dentry} e una struttura \var{f\_ops} che contiene i puntatori ai
+metodi che implementano le operazioni disponibili sul file. In questo modo i
+processi in user space possono accedere alle operazioni attraverso detti
+metodi, che saranno diversi a seconda del tipo di file (o dispositivo) aperto
+(su questo torneremo in dettaglio in \secref{sec:file_fd}). Un elenco delle
+operazioni previste dal kernel è riportato in \ntab.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|p{7cm}|}
+ \hline
+ \textbf{Funzione} & \textbf{Operazione} \\
+ \hline
+ \hline
+ \textsl{\code{open}} & apre il file \\
+ \textsl{\code{read}} & legge dal file \\
+ \textsl{\code{write}} & scrive sul file \\
+ \textsl{\code{llseek}} & sposta la posizione corrente sul file \\
+ \textsl{\code{ioctl}} & accede alle operazioni di controllo
+ (tramite la \func{ioctl})\\
+ \textsl{\code{readdir}}& per leggere il contenuto di una directory \\
+ \textsl{\code{poll}} & \\
+ \textsl{\code{mmap}} & chiamata dalla system call \func{mmap}.
+ mappa il file in memoria\\
+ \textsl{\code{release}}& chiamata quando l'ultima referenza a un file
+ aperto è chiusa\\
+ \textsl{\code{fsync}} & chiamata dalla system call \func{fsync} \\
+ \textsl{\code{fasync}} & chiamate da \func{fcntl} quando è abilitato
+ il modo asincrono per l'I/O su file. \\
+ \hline
+ \end{tabular}
+ \caption{Operazioni sui file definite nel VFS.}
+ \label{tab:file_file_operations}
+\end{table}
+
+In questo modo per ciascun file diventano possibili una serie di operazioni
+(non è detto che tutte siano disponibili), che costituiscono l'interfaccia
+astratta del VFS. Qualora se ne voglia eseguire una, il kernel andrà ad
+utilizzare l'opportuna routine dichiarata in \var{f\_ops} appropriata al tipo
+di file in questione.
+
+In questo modo è possibile scrivere allo stesso modo sulla porta seriale come
+su normale un file di dati; ovviamente certe operazioni (nel caso della
+seriale ad esempio la \code{seek}) non saranno disponibili, però con questo
+sistema l'utilizzo di diversi filesystem (come quelli usati da Windows o
+MacOs) è immediato e (relativamente) trasparente per l'utente ed il
+programmatore.
+
+
+\subsection{Il funzionamento di un filesystem Unix}
+\label{sec:file_filesystem}
+
+Come già accennato in \secref{sec:file_organization} Linux (ed ogni sistema
+unix-like) organizza i dati che tiene su disco attraverso l'uso di un
+filesystem. Una delle caratteristiche di Linux rispetto agli altri Unix è
+quella di poter supportare, grazie al VFS, una enorme quantità di filesystem
+diversi, ognuno dei quali ha una sua particolare struttura e funzionalità
+proprie. Per questo, per il momento non entreremo nei dettagli di un
+filesystem specifico, ma daremo una descrizione a grandi linee che si adatta
+alle caratteristiche comuni di qualunque filesystem di sistema unix-like.
+
+Lo spazio fisico di un disco viene usualmente diviso in partizioni; ogni
+partizione può contenere un filesystem. La strutturazione tipica
+dell'informazione su un disco è riportata in \nfig; in essa si fa riferimento
+alla struttura del filesystem \acr{ext2}, che prevede una separazione dei dati
+in \textit{blocks group} che replicano il superblock (ma sulle caratteristiche
+di \acr{ext2} torneremo in \secref{sec:file_ext2}). È comunque caratteristica
+comune di tutti i filesystem per Unix, indipendentemente da come poi viene
+strutturata nei dettagli questa informazione, prevedere una divisione fra la
+lista degli inodes e lo spazio a disposizione per i dati e le directory.
+
+\begin{figure}[htb]
+ \centering
+ \includegraphics[width=12cm]{img/disk_struct}
+ \caption{Organizzazione dello spazio su un disco in partizioni e
+ filesystem.}
+ \label{fig:file_disk_filesys}
+\end{figure}
+
+Se si va ad esaminare con maggiore dettaglio la strutturazione
+dell'informazione all'interno del singolo filesystem (tralasciando i dettagli
+relativi al funzionamento del filesystem stesso come la strutturazione in
+gruppi dei blocchi, il superblock e tutti i dati di gestione) possiamo
+esemplificare la situazione con uno schema come quello esposto in \nfig.
+
+\begin{figure}[htb]
+ \centering
+ \includegraphics[width=12cm]{img/filesys_struct}
+ \caption{Strutturazione dei dati all'interno di un filesystem.}
+ \label{fig:file_filesys_detail}
+\end{figure}
+
+Da \curfig\ si evidenziano alcune delle caratteristiche di base di un
+filesystem, sulle quali è bene porre attenzione visto che sono fondamentali
+per capire il funzionamento delle funzioni che manipolano i file e le
+directory che tratteremo nel prossimo capitolo; in particolare è opportuno
+ricordare sempre che:
+
+\begin{enumerate}
+
+\item L'\textit{inode} contiene tutte le informazioni riguardanti il file: il
+ tipo di file, i permessi di accesso, le dimensioni, i puntatori ai blocchi
+ fisici che contengono i dati e così via; le informazioni che la funzione
+ \func{stat} fornisce provengono dall'\textit{inode}; dentro una directory si
+ troverà solo il nome del file e il numero dell'\textit{inode} ad esso
+ associato, cioè quella che da qui in poi chiameremo una \textsl{voce}
+ (traduzione approssimata dell'inglese \textit{directory entry}, che non
+ useremo anche per evitare confusione con le \textit{dentry} del kernel di
+ cui si parlava in \secref{sec:file_vfs}).
+
+\item Come mostrato in \curfig\ si possono avere più voci che puntano allo
+ stesso \textit{inode}. Ogni \textit{inode} ha un contatore che contiene il
+ numero di riferimenti (\textit{link count}) che sono stati fatti ad esso;
+ solo quando questo contatore si annulla i dati del file vengono
+ effettivamente rimossi dal disco. Per questo la funzione per cancellare un
+ file si chiama \func{unlink}, ed in realtà non cancella affatto i dati del
+ file, ma si limita ad eliminare la relativa voce da una directory e
+ decrementare il numero di riferimenti nell'\textit{inode}.
+
+\item Il numero di \textit{inode} nella voce si riferisce ad un \textit{inode}
+ nello stesso filesystem e non ci può essere una directory che contiene
+ riferimenti ad \textit{inodes} relativi ad altri filesystem. Questo limita
+ l'uso del comando \cmd{ln} (che crea una nuova voce per un file
+ esistente, con la funzione \func{link}) al filesystem corrente.
+
+\item Quando si cambia nome ad un file senza cambiare filesystem, il contenuto
+ del file non viene spostato fisicamente, viene semplicemente creata una
+ nuova voce per l'\textit{inode} in questione e rimossa la vecchia (questa è
+ la modalità in cui opera normalmente il comando \cmd{mv} attraverso la
+ funzione \func{rename}).
+
+\end{enumerate}
+
+Infine è bene avere presente che, essendo file pure loro, esiste un numero di
+riferimenti anche per le directory; per cui, se a partire dalla situazione
+mostrata in \curfig\ creiamo una nuova directory \file{img} nella directory
+\file{gapil}, avremo una situazione come quella in \nfig, dove per chiarezza
+abbiamo aggiunto dei numeri di inode.
+
+\begin{figure}[htb]
+ \centering
+ \includegraphics[width=12cm]{img/dir_links}
+ \caption{Organizzazione dei link per le directory.}
+ \label{fig:file_dirs_link}
+\end{figure}
+
+La nuova directory avrà allora un numero di riferimenti pari a due, in quanto
+è referenziata dalla directory da cui si era partiti (in cui è inserita la
+nuova voce che fa riferimento a \file{img}) e dalla voce \file{.}
+che è sempre inserita in ogni directory; questo vale sempre per ogni directory
+che non contenga a sua volta altre directory. Al contempo, la directory da
+cui si era partiti avrà un numero di riferimenti di almeno tre, in quanto
+adesso sarà referenziata anche dalla voce \file{..} di \file{img}.
+
+
+\subsection{Il filesystem \textsl{ext2}}
+\label{sec:file_ext2}
+
+Il filesystem standard usato da Linux è il cosiddetto \textit{second extended
+ filesystem}, identificato dalla sigla \acr{ext2}. Esso supporta tutte le
+caratteristiche di un filesystem standard Unix, è in grado di gestire nomi di
+file lunghi (256 caratteri, estendibili a 1012) con una dimensione massima di
+4~Tb.
+
+Oltre alle caratteristiche standard, \acr{ext2} fornisce alcune estensioni che
+non sono presenti sugli altri filesystem Unix. Le principali sono le seguenti:
+\begin{itemize}
+\item i \textit{file attributes} consentono di modificare il comportamento del
+ kernel quando agisce su gruppi di file. Possono essere settati su file e
+ directory e in quest'ultimo caso i nuovi file creati nella directory
+ ereditano i suoi attributi.
+\item sono supportate entrambe le semantiche di BSD e SVr4 come opzioni di
+ montaggio. La semantica BSD comporta che i file in una directory sono creati
+ con lo stesso identificatore di gruppo della directory che li contiene. La
+ semantica SVr4 comporta che i file vengono creati con l'identificatore del
+ gruppo primario del processo, eccetto il caso in cui la directory ha il bit
+ di \acr{sgid} settato (per una descrizione dettagliata del significato di
+ questi termini si veda \secref{sec:file_access_control}), nel qual caso file
+ e subdirectory ereditano sia il \acr{gid} che lo \acr{sgid}.
+\item l'amministratore può scegliere la dimensione dei blocchi del filesystem
+ in fase di creazione, a seconda delle sue esigenze (blocchi più grandi
+ permettono un accesso più veloce, ma sprecano più spazio disco).
+\item il filesystem implementa link simbolici veloci, in cui il nome del file
+ non è salvato su un blocco, ma tenuto all'interno dell'inode (evitando
+ letture multiple e spreco di spazio), non tutti i nomi però possono essere
+ gestiti così per limiti di spazio (il limite è 60 caratteri).
+\item vengono supportati i file immutabili (che possono solo essere letti) per
+ la protezione di file di configurazione sensibili, o file
+ \textit{append-only} che possono essere aperti in scrittura solo per
+ aggiungere dati (caratteristica utilizzabile per la protezione dei file di
+ log).
+\end{itemize}
+
+La struttura di \acr{ext2} è stata ispirata a quella del filesystem di BSD:
+un filesystem è composto da un insieme di blocchi, la struttura generale è
+quella riportata in \figref{fig:file_filesys_detail}, in cui la partizione
+è divisa in gruppi di blocchi.
+
+Ciascun gruppo di blocchi contiene una copia delle informazioni essenziali del
+filesystem (superblock e descrittore del filesystem sono quindi ridondati) per
+una maggiore affidabilità e possibilità di recupero in caso di corruzione del
+superblock principale.
+
+\begin{figure}[htb]
+ \centering
+ \includegraphics[width=9cm]{img/dir_struct}
+ \caption{Struttura delle directory nel \textit{second extented filesystem}.}
+ \label{fig:file_ext2_dirs}
+\end{figure}
+
+L'utilizzo di raggruppamenti di blocchi ha inoltre degli effetti positivi nelle
+prestazioni dato che viene ridotta la distanza fra i dati e la tabella degli
+inode.
+
+Le directory sono implementate come una linked list con voci di dimensione
+variabile. Ciascuna voce della lista contiene il numero di inode, la sua
+lunghezza, il nome del file e la sua lunghezza, secondo lo schema in \curfig;
+in questo modo è possibile implementare nomi per i file anche molto lunghi
+(fino a 1024 caratteri) senza sprecare spazio disco.
+
+
+