Grande ristrutturazione volta alla eliminazione del capitolo 4, i cui
[gapil.git] / filedir.tex
index b3d4e92fc4b20aa3cef7141384ad5f09e9c9bc70..281f8180be103417987806f1fac5a754aed3aeae 100644 (file)
 %% License".
 %%
 
-\chapter{File e directory}
+\chapter{La gestione di file e directory}
 \label{cha:files_and_dirs}
 
 In questo capitolo tratteremo in dettaglio le modalità con cui si gestiscono
-file e directory, iniziando dalle funzioni di libreria che si usano per
-copiarli, spostarli e cambiarne i nomi. Esamineremo poi l'interfaccia che
-permette la manipolazione dei vari attributi di file e directory ed alla fine
-prenderemo in esame la struttura di base del sistema delle protezioni e del
-controllo dell'accesso ai file e le successive estensioni (\textit{Extended
-  Attributes}, ACL, quote disco, \textit{capabilities}). Tutto quello che
-riguarda invece la manipolazione del contenuto dei file è lasciato ai capitoli
-successivi.
+file e directory, iniziando da un approfondimento dell'architettura del
+sistema illustrata a grandi linee in sez.~\ref{sec:file_arch_overview} ed
+illustrando le principali caratteristiche di un filesystem e le interfacce
+che consentono di controllarne il montaggio e lo smontaggio. 
+
+Esamineremo poi le funzioni di libreria che si usano per copiare, spostare e
+cambiare i nomi di file e directory ed esamineremo l'interfaccia che permette
+la manipolazione dei loro attributi. Tratteremo inoltre la struttura di base
+del sistema delle protezioni e del controllo dell'accesso ai file e le
+successive estensioni (\textit{Extended Attributes}, ACL, quote disco,
+\textit{capabilities}). Tutto quello che riguarda invece la manipolazione del
+contenuto dei file è lasciato ai capitoli successivi.
+
+
+
+\section{L'architettura della gestione dei file}
+\label{sec:file_arch_func}
+
+In questa sezione tratteremo con maggiori dettagli rispetto a quanto visto in
+sez.~\ref{sec:file_arch_overview} il \textit{Virtual File System} di Linux e
+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 più usato con Linux,
+l'\acr{ext2} (e derivati).
+
+
+\subsection{Il funzionamento del \textit{Virtual File System} di Linux}
+\label{sec:file_vfs_work}
+
+% articolo interessante:
+% http://www.ibm.com/developerworks/linux/library/l-virtual-filesystem-switch/index.html?ca=dgr-lnxw97Linux-VFSdth-LXdW&S_TACT=105AGX59&S_CMP=GRlnxw97
+
+\itindbeg{Virtual~File~System}
+
+Come illustrato brevemente in sez.~\ref{sec:file_arch_overview} in Linux il
+concetto di \textit{everything is a file} è stato implementato attraverso il
+\textit{Virtual File System}, la cui struttura generale è illustrata in
+fig.~\ref{fig:file_VFS_scheme}.  Il VFS definisce un insieme di funzioni che
+tutti i filesystem devono implementare. L'interfaccia comprende tutte le
+funzioni che riguardano i file e le operazioni sono suddivise su tre tipi di
+oggetti: \textit{filesystem}, \itindex{inode} \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
+\code{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 di qualunque altro dispositivo che può contenere un filesystem, il VFS può
+ricavare dalla citata tabella il puntatore alle funzioni da chiamare nelle
+operazioni di montaggio. Queste sono responsabili inizializzare tutte le
+variabili interne e restituire uno speciale descrittore dei filesystem montati
+al VFS; attraverso quest'ultimo diventa possibile accedere alle funzioni
+specifiche per l'uso di quel filesystem.
+
+Il primo oggetto usato dal VFS è il descrittore di filesystem (o
+\textit{filesystem descriptor}), 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 funzioni 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
+\itindex{inode} dell'\textit{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.
+
+La funzione più importante implementata dal VFS è la \textit{system call}
+\func{open} che permette di aprire un file. Dato un \itindex{pathname}
+\textit{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 \textit{pathname} a una specifica
+\textit{dentry}.
+
+Una singola \textit{dentry} contiene in genere il puntatore ad un
+\itindex{inode} \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
+\index{file!di~dispositivo} dispositivo, o una qualsiasi altra cosa che possa
+essere rappresentata dal VFS (i tipi di file riportati in
+tab.~\ref{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 \itindex{inode} \textit{inode} invece
+stanno su disco e vengono copiati in memoria quando serve, ed ogni cambiamento
+viene copiato all'indietro sul disco (aggiornando i cosiddetti
+\textsl{metadati} del file), gli \itindex{inode} inode che stanno in memoria
+sono \itindex{inode} 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
+\itindex{pathname} \textit{pathname} il VFS deve creare una nuova
+\textit{dentry} e caricare \itindex{inode} l'inode corrispondente in memoria.
+
+Questo procedimento viene eseguito dal metodo \code{lookup()} \itindex{inode}
+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
+\itindex{inode} dell'inode e passarli in user space.
+
+L'apertura di un file richiede comunque un'altra operazione, l'allocazione di
+una struttura di tipo \struct{file} in cui viene inserito un puntatore alla
+\textit{dentry} e una struttura \struct{f\_ops} che contiene i puntatori ai
+metodi che implementano le operazioni disponibili sul file. In questo modo i
+processi in \textit{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 sez.~\ref{sec:file_fd}). Un elenco
+delle operazioni previste dal kernel è riportato in
+tab.~\ref{tab:file_file_operations}.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{8cm}|}
+    \hline
+    \textbf{Funzione} & \textbf{Operazione} \\
+    \hline
+    \hline
+    \textsl{\code{open}}   & Apre il file (vedi sez.~\ref{sec:file_open}).\\
+    \textsl{\code{read}}   & Legge dal file (vedi sez.~\ref{sec:file_read}).\\
+    \textsl{\code{write}}  & Scrive sul file (vedi 
+                             sez.~\ref{sec:file_write}).\\
+    \textsl{\code{llseek}} & Sposta la posizione corrente sul file (vedi
+                             sez.~\ref{sec:file_lseek}).\\
+    \textsl{\code{ioctl}}  & Accede alle operazioni di controllo 
+                             (vedi sez.~\ref{sec:file_ioctl}).\\
+    \textsl{\code{readdir}}& Legge il contenuto di una directory (vedi 
+                             sez.~\ref{sec:file_dir_read}).\\
+    \textsl{\code{poll}}   & Usata nell'I/O multiplexing (vedi
+                             sez.~\ref{sec:file_multiplexing}).\\
+    \textsl{\code{mmap}}   & Mappa il file in memoria (vedi 
+                             sez.~\ref{sec:file_memory_map}).\\
+    \textsl{\code{release}}& Chiamata quando l'ultimo riferimento a un file 
+                             aperto è chiuso.\\
+    \textsl{\code{fsync}}  & Sincronizza il contenuto del file (vedi
+                             sez.~\ref{sec:file_sync}).\\
+    \textsl{\code{fasync}} & Abilita l'I/O asincrono (vedi
+                             sez.~\ref{sec:file_asyncronous_io}) sul 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 funzione dichiarata in \struct{f\_ops} appropriata al
+tipo di file in questione.
+
+Pertanto è possibile scrivere allo stesso modo sulla porta seriale come su un
+normale 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.
+\itindend{Virtual~File~System}
+
+
+\subsection{Il funzionamento di un filesystem Unix}
+\label{sec:file_filesystem}
+
+Come già accennato in sez.~\ref{sec:file_arch_overview} 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 un 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 fig.~\ref{fig:file_disk_filesys},
+in essa si fa riferimento alla struttura del filesystem \acr{ext2}, che
+prevede una separazione dei dati in \textit{block group} che replicano il
+cosiddetto \textit{superblock} (ma sulle caratteristiche di \acr{ext2} e
+derivati torneremo in sez.~\ref{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 \itindex{inode} inode e lo spazio a disposizione per i dati e le
+directory.
+
+\begin{figure}[!htb]
+  \centering
+  \includegraphics[width=14cm]{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
+fig.~\ref{fig:file_filesys_detail}.
+
+\begin{figure}[!htb]
+  \centering
+  \includegraphics[width=14cm]{img/filesys_struct}
+  \caption{Strutturazione dei dati all'interno di un filesystem.}
+  \label{fig:file_filesys_detail}
+\end{figure}
+
+Da fig.~\ref{fig:file_filesys_detail} 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} \itindex{inode} contiene tutte le informazioni (i
+  cosiddetti \textsl{metadati}) 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 \itindex{inode} dell'\textit{inode} ad esso
+  associato, cioè quella che da qui in poi chiameremo una \textsl{voce} (come
+  traduzione dell'inglese \textit{directory entry}, che non useremo anche per
+  evitare confusione con le \textit{dentry} del kernel di cui si parlava in
+  sez.~\ref{sec:file_vfs_work}).
+  
+\item Come mostrato in fig.~\ref{fig:file_filesys_detail} si possono avere più
+  voci che puntano allo stesso \textit{inode}. Ogni \textit{inode} ha un
+  contatore che contiene il numero di riferimenti che sono stati fatti ad esso
+  (il cosiddetto \textit{link count}); 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 \itindex{inode}
+  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 \itindex{inode} \textit{inode} 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 \itindex{inode} 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}). Questa operazione non modifica
+  minimamente neanche l'\textit{inode} del file dato che non si opera su
+  questo ma sulla directory che lo contiene.
+
+\item Gli \textit{inode} dei file, che contengono i \textsl{metadati} ed i
+  blocchi di spazio disco, che contengono i dati, sono risorse indipendenti ed
+  in genere vengono gestite come tali anche dai diversi filesystem; è pertanto
+  possibile sia esaurire lo spazio disco (caso più comune) che lo spazio per
+  gli \textit{inode}, nel primo caso non sarà possibile allocare ulteriore
+  spazio, ma si potranno creare file (vuoti), nel secondo non si potranno
+  creare nuovi file, ma si potranno estendere quelli che ci sono.
+
+\end{enumerate}
+
+Infine si noti che, essendo file pure loro, il numero di riferimenti esiste
+anche per le directory; per cui, se a partire dalla situazione mostrata in
+fig.~\ref{fig:file_filesys_detail} creiamo una nuova directory \file{img}
+nella directory \file{gapil}, avremo una situazione come quella in
+fig.~\ref{fig:file_dirs_link}, dove per chiarezza abbiamo aggiunto dei numeri
+di \itindex{inode} inode.
+
+\begin{figure}[!htb]
+  \centering 
+  \includegraphics[width=14cm]{img/dir_links}
+  \caption{Organizzazione dei \textit{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 \texttt{img}) e dalla voce ``\texttt{.}''  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 ``\texttt{..}'' di \texttt{img}.
+
+
+\subsection{I filesystem di uso comune}
+\label{sec:file_ext2}
+
+Il filesystem standard più usato con Linux è il cosiddetto \textit{third
+  extended filesystem}, identificato dalla sigla \acr{ext3}.\footnote{si fa
+  riferimento al momento della stesura di questo paragrafo, l'inizio del
+  2010.} Esso nasce come evoluzione del precedente \textit{second extended
+  filesystem}, o \acr{ext2}, di cui eredita gran parte delle caratteristiche
+di base, per questo motivo parleremo anzitutto di questo, dato che molto di
+quanto diremo si applica anche ad \acr{ext3}. A partire dal kernel 2.6.XX è
+stato dichiarato stabile il nuovo filsesystem \textit{ext4}, ulteriore
+evoluzione di \textit{ext3} dotato di molte caratteristiche avanzate, che sta
+iniziando a sostituirlo gradualmente.
+
+Il filesystem \acr{ext2} nasce come filesystem nativo di Linux a partire dalle
+prime versioni del kernel e supporta tutte le caratteristiche di un filesystem
+standard Unix: è in grado di gestire nomi di file lunghi (256 caratteri,
+estensibili a 1012) e supporta una dimensione massima dei file fino a 4~Tb. I
+successivi filesystem \acr{ext3} ed \acr{ext4} sono evoluzioni di questo
+filesystem, e sia pure con molti miglioramenti ed estensioni significative ne
+mantengono in sostanza le caratteristiche fondamentali.
+
+Oltre alle caratteristiche standard, \acr{ext2} fornisce alcune estensioni che
+non sono presenti su un classico filesystem di tipo 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 impostati 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} impostato (per una descrizione dettagliata del significato di
+  questi termini si veda sez.~\ref{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 \itindex{inode} 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 fig.~\ref{fig:file_filesys_detail}, in cui la partizione è divisa
+in gruppi di blocchi.\footnote{non si confonda questa definizione con
+  quella riportata in fig.~\ref{fig:file_dirent_struct}; in quel caso si fa
+  riferimento alla struttura usata in user space per riportare i dati
+  contenuti in una directory generica, questa fa riferimento alla struttura
+  usata dal kernel per un filesystem \acr{ext2}, definita nel file
+  \texttt{ext2\_fs.h} nella directory \texttt{include/linux} dei sorgenti del
+  kernel.}
+
+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. 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 \itindex{inode} inode.
+
+\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}
+
+Le directory sono implementate come una \itindex{linked~list} \textit{linked
+  list} con voci di dimensione variabile. Ciascuna voce della lista contiene
+il numero di inode \itindex{inode}, la sua lunghezza, il nome del file e la sua
+lunghezza, secondo lo schema in fig.~\ref{fig:file_ext2_dirs}; in questo modo
+è possibile implementare nomi per i file anche molto lunghi (fino a 1024
+caratteri) senza sprecare spazio disco.
+
+Con l'introduzione del filesystem \textit{ext3} sono state introdotte anche
+alcune modifiche strutturali, la principale di queste è quella che
+\textit{ext3} è un filesystem \textit{jounrnaled}, è cioè in grado di eseguire
+una registrazione delle operazioni di scrittura su un giornale (uno speciale
+file interno) in modo da poter garantire il ripristino della coerenza dei dati
+del filesystem\footnote{si noti bene che si è parlato di dati \textsl{del}
+  filesystem, non di dati \textsl{nel} filesystem, quello di cui viene
+  garantito un veloce ripristino è relativo ai dati della struttura interna
+  del filesystem, non di eventuali dati contenuti nei file che potrebbero
+  essere stati persi.} in brevissimo tempo in caso di interruzione improvvisa
+della corrente o di crollo del sistema che abbia causato una interruzione
+della scrittura dei dati sul disco.
+
+Oltre a questo \textit{ext3} introduce ulteriori modifiche volte a migliorare
+sia le prestazioni che la semplicità di gestione del filesystem, in
+particolare per le directory si è passato all'uso di alberi binari con
+indicizzazione tramite hash al posto delle \textit{linked list}, ottenendo un
+forte guadagno di prestazioni in caso di directory contenenti un gran numero
+di file. 
+
+% TODO portare a ext3, ext4 e btrfs ed illustrare le problematiche che si
+% possono incontrare (in particolare quelle relative alla perdita di contenuti
+% in caso di crash del sistema)
+
+
+\subsection{La gestione dei filesystem}
+\label{sec:sys_file_config}
+
+Come accennato in sez.~\ref{sec:file_arch_overview} per poter accedere ai file
+occorre prima rendere disponibile al sistema il filesystem su cui essi sono
+memorizzati; l'operazione di attivazione del filesystem è chiamata
+\textsl{montaggio}, per far questo in Linux\footnote{la funzione è specifica
+  di Linux e non è portabile.} si usa la funzione \funcd{mount} il cui
+prototipo è:
+\begin{prototype}{sys/mount.h}
+{mount(const char *source, const char *target, const char *filesystemtype, 
+  unsigned long mountflags, const void *data)}
+
+Monta il filesystem di tipo \param{filesystemtype} contenuto in \param{source}
+sulla directory \param{target}.
+  
+  \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di
+  fallimento, nel qual caso gli errori comuni a tutti i filesystem che possono
+  essere restituiti in \var{errno} sono:
+  \begin{errlist}
+  \item[\errcode{EPERM}] il processo non ha i privilegi di amministratore.
+  \item[\errcode{ENODEV}] \param{filesystemtype} non esiste o non è configurato
+    nel kernel.
+  \item[\errcode{ENOTBLK}] non si è usato un \textit{block device} per
+    \param{source} quando era richiesto.
+  \item[\errcode{EBUSY}] \param{source} è già montato, o non può essere
+    rimontato in read-only perché ci sono ancora file aperti in scrittura, o
+    \param{target} è ancora in uso.
+  \item[\errcode{EINVAL}] il device \param{source} presenta un
+    \textit{superblock} non valido, o si è cercato di rimontare un filesystem
+    non ancora montato, o di montarlo senza che \param{target} sia un
+    \textit{mount point} o di spostarlo quando \param{target} non è un
+    \textit{mount point} o è \file{/}.
+  \item[\errcode{EACCES}] non si ha il permesso di accesso su uno dei
+    componenti del \itindex{pathname} \textit{pathname}, o si è cercato
+    di montare un filesystem disponibile in sola lettura senza averlo
+    specificato o il device \param{source} è su un filesystem montato con
+    l'opzione \const{MS\_NODEV}.
+  \item[\errcode{ENXIO}] il \itindex{major~number} \textit{major number} del
+    device \param{source} è sbagliato.
+  \item[\errcode{EMFILE}] la tabella dei device \textit{dummy} è piena.
+  \end{errlist}
+  ed inoltre \errval{ENOTDIR}, \errval{EFAULT}, \errval{ENOMEM},
+  \errval{ENAMETOOLONG}, \errval{ENOENT} o \errval{ELOOP}.}
+\end{prototype}
+
+La funzione monta sulla directory \param{target}, detta \textit{mount point},
+il filesystem contenuto in \param{source}. In generale un filesystem è
+contenuto su un disco, e l'operazione di montaggio corrisponde a rendere
+visibile al sistema il contenuto del suddetto disco, identificato attraverso
+il file di dispositivo ad esso associato.
+
+Ma la struttura del \textit{Virtual File System} vista in
+sez.~\ref{sec:file_vfs_work} è molto più flessibile e può essere usata anche
+per oggetti diversi da un disco. Ad esempio usando il \textit{loop device} si
+può montare un file qualunque (come l'immagine di un CD-ROM o di un floppy)
+che contiene un filesystem, inoltre alcuni filesystem, come \file{proc} o
+\file{devfs} sono del tutto virtuali, i loro dati sono generati al volo ad
+ogni lettura, e passati al kernel ad ogni scrittura.
+
+Il tipo di filesystem è specificato da \param{filesystemtype}, che deve essere
+una delle stringhe riportate nel file \procfile{/proc/filesystems}, che
+contiene l'elenco dei filesystem supportati dal kernel; nel caso si sia
+indicato uno dei filesystem virtuali, il contenuto di \param{source} viene
+ignorato.
+
+Dopo l'esecuzione della funzione il contenuto del filesystem viene resto
+disponibile nella directory specificata come \textit{mount point}, il
+precedente contenuto di detta directory viene mascherato dal contenuto della
+directory radice del filesystem montato.
+
+Dal kernel 2.4.x inoltre è divenuto possibile sia spostare atomicamente un
+\textit{mount point} da una directory ad un'altra, sia montare in diversi
+\textit{mount point} lo stesso filesystem, sia montare più filesystem sullo
+stesso \textit{mount point} (nel qual caso vale quanto appena detto, e solo il
+contenuto dell'ultimo filesystem montato sarà visibile).
+
+Ciascun filesystem è dotato di caratteristiche specifiche che possono essere
+attivate o meno, alcune di queste sono generali (anche se non è detto siano
+disponibili in ogni filesystem), e vengono specificate come opzioni di
+montaggio con l'argomento \param{mountflags}.  
+
+In Linux \param{mountflags} deve essere un intero a 32 bit i cui 16 più
+significativi sono un \textit{magic number}\footnote{cioè un numero speciale
+  usato come identificativo, che nel caso è \code{0xC0ED}; si può usare la
+  costante \const{MS\_MGC\_MSK} per ottenere la parte di \param{mountflags}
+  riservata al \textit{magic number}.} mentre i 16 meno significativi sono
+usati per specificare le opzioni; essi sono usati come maschera binaria e
+vanno impostati con un OR aritmetico della costante \const{MS\_MGC\_VAL} con i
+valori riportati in tab.~\ref{tab:sys_mount_flags}.
+
+\begin{table}[htb]
+  \footnotesize
+  \centering
+  \begin{tabular}[c]{|l|r|l|}
+    \hline
+    \textbf{Parametro} & \textbf{Valore}&\textbf{Significato}\\
+    \hline
+    \hline
+    \const{MS\_RDONLY}     &  1 & Monta in sola lettura.\\
+    \const{MS\_NOSUID}     &  2 & Ignora i bit \itindex{suid~bit} \acr{suid} e
+                                  \itindex{sgid~bit} \acr{sgid}.\\ 
+    \const{MS\_NODEV}      &  4 & Impedisce l'accesso ai file di dispositivo.\\
+    \const{MS\_NOEXEC}     &  8 & Impedisce di eseguire programmi.\\
+    \const{MS\_SYNCHRONOUS}& 16 & Abilita la scrittura sincrona.\\
+    \const{MS\_REMOUNT}    & 32 & Rimonta il filesystem cambiando le opzioni.\\
+    \const{MS\_MANDLOCK}   & 64 & Consente il \textit{mandatory locking} 
+                                  \itindex{mandatory~locking} (vedi
+                                  sez.~\ref{sec:file_mand_locking}).\\
+    \const{S\_WRITE}      & 128 & Scrive normalmente.\\
+    \const{S\_APPEND}     & 256 & Consente la scrittura solo in
+                                  \itindex{append~mode} \textit{append mode} 
+                                  (vedi sez.~\ref{sec:file_sharing}).\\
+    \const{S\_IMMUTABLE}  & 512 & Impedisce che si possano modificare i file.\\
+    \const{MS\_NOATIME}   &1024 & Non aggiorna gli \textit{access time} (vedi
+                                  sez.~\ref{sec:file_file_times}).\\
+    \const{MS\_NODIRATIME}&2048 & Non aggiorna gli \textit{access time} delle
+                                  directory.\\
+    \const{MS\_BIND}      &4096 & Monta il filesystem altrove.\\
+    \const{MS\_MOVE}      &8192 & Sposta atomicamente il punto di montaggio.\\
+    \hline
+  \end{tabular}
+  \caption{Tabella dei codici dei flag di montaggio di un filesystem.}
+  \label{tab:sys_mount_flags}
+\end{table}
+
+% TODO aggiornare con i nuovi flag di man mount
+% gli S_* non esistono più come segnalato da Alessio...
+% verificare i readonly mount bind del 2.6.26
+
+Per l'impostazione delle caratteristiche particolari di ciascun filesystem si
+usa invece l'argomento \param{data} che serve per passare le ulteriori
+informazioni necessarie, che ovviamente variano da filesystem a filesystem.
+
+La funzione \func{mount} può essere utilizzata anche per effettuare il
+\textsl{rimontaggio} di un filesystem, cosa che permette di cambiarne al volo
+alcune delle caratteristiche di funzionamento (ad esempio passare da sola
+lettura a lettura/scrittura). Questa operazione è attivata attraverso uno dei
+bit di \param{mountflags}, \const{MS\_REMOUNT}, che se impostato specifica che
+deve essere effettuato il rimontaggio del filesystem (con le opzioni
+specificate dagli altri bit), anche in questo caso il valore di \param{source}
+viene ignorato.
+
+Una volta che non si voglia più utilizzare un certo filesystem è possibile
+\textsl{smontarlo} usando la funzione \funcd{umount}, il cui prototipo è:
+\begin{prototype}{sys/mount.h}{umount(const char *target)}
+  
+  Smonta il filesystem montato sulla directory \param{target}.
+  
+  \bodydesc{La funzione ritorna 0 in caso di successo e -1 in caso di
+    fallimento, nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+  \item[\errcode{EPERM}] il processo non ha i privilegi di amministratore.
+  \item[\errcode{EBUSY}]  \param{target} è la directory di lavoro di qualche
+  processo, o contiene dei file aperti, o un altro mount point.
+  \end{errlist}
+  ed inoltre \errval{ENOTDIR}, \errval{EFAULT}, \errval{ENOMEM},
+  \errval{ENAMETOOLONG}, \errval{ENOENT} o \errval{ELOOP}.}
+\end{prototype}
+\noindent la funzione prende il nome della directory su cui il filesystem è
+montato e non il file o il dispositivo che è stato montato,\footnote{questo è
+  vero a partire dal kernel 2.3.99-pre7, prima esistevano due chiamate
+  separate e la funzione poteva essere usata anche specificando il file di
+  dispositivo.} in quanto con il kernel 2.4.x è possibile montare lo stesso
+dispositivo in più punti. Nel caso più di un filesystem sia stato montato
+sullo stesso \textit{mount point} viene smontato quello che è stato montato
+per ultimo.
+
+Si tenga presente che la funzione fallisce quando il filesystem è
+\textsl{occupato}, questo avviene quando ci sono ancora file aperti sul
+filesystem, se questo contiene la directory di lavoro corrente di un qualunque
+processo o il mount point di un altro filesystem; in questo caso l'errore
+restituito è \errcode{EBUSY}.
+
+Linux provvede inoltre una seconda funzione, \funcd{umount2}, che in alcuni
+casi permette di forzare lo smontaggio di un filesystem, anche quando questo
+risulti occupato; il suo prototipo è:
+\begin{prototype}{sys/mount.h}{umount2(const char *target, int flags)}
+  
+  La funzione è identica a \func{umount} per comportamento e codici di errore,
+  ma con \param{flags} si può specificare se forzare lo smontaggio.
+\end{prototype}
+
+Il valore di \param{flags} è una maschera binaria, e al momento l'unico valore
+definito è il bit \const{MNT\_FORCE}; gli altri bit devono essere nulli.
+Specificando \const{MNT\_FORCE} la funzione cercherà di liberare il filesystem
+anche se è occupato per via di una delle condizioni descritte in precedenza. A
+seconda del tipo di filesystem alcune (o tutte) possono essere superate,
+evitando l'errore di \errcode{EBUSY}.  In tutti i casi prima dello smontaggio
+viene eseguita una sincronizzazione dei dati. 
+
+% TODO documentare MNT_DETACH e MNT_EXPIRE ...
+
+Altre due funzioni specifiche di Linux,\footnote{esse si trovano anche su BSD,
+  ma con una struttura diversa.} utili per ottenere in maniera diretta
+informazioni riguardo al filesystem su cui si trova un certo file, sono
+\funcd{statfs} e \funcd{fstatfs}, i cui prototipi sono:
+\begin{functions}
+  \headdecl{sys/vfs.h} 
+  \funcdecl{int statfs(const char *path, struct statfs *buf)} 
+
+  \funcdecl{int fstatfs(int fd, struct statfs *buf)} 
+  
+  Restituisce in \param{buf} le informazioni relative al filesystem su cui è
+  posto il file specificato.
+  
+  \bodydesc{Le funzioni ritornano 0 in caso di successo e -1 in caso di
+    errore, nel qual caso \var{errno} assumerà uno dei valori:
+  \begin{errlist}
+  \item[\errcode{ENOSYS}] il filesystem su cui si trova il file specificato non
+  supporta la funzione.
+  \end{errlist}
+  e \errval{EFAULT} ed \errval{EIO} per entrambe, \errval{EBADF} per
+  \func{fstatfs}, \errval{ENOTDIR}, \errval{ENAMETOOLONG}, \errval{ENOENT},
+  \errval{EACCES}, \errval{ELOOP} per \func{statfs}.}
+\end{functions}
+
+Queste funzioni permettono di ottenere una serie di informazioni generali
+riguardo al filesystem su cui si trova il file specificato; queste vengono
+restituite all'indirizzo \param{buf} di una struttura \struct{statfs} definita
+come in fig.~\ref{fig:sys_statfs}, ed i campi che sono indefiniti per il
+filesystem in esame sono impostati a zero.  I valori del campo \var{f\_type}
+sono definiti per i vari filesystem nei relativi file di header dei sorgenti
+del kernel da costanti del tipo \var{XXX\_SUPER\_MAGIC}, dove \var{XXX} in
+genere è il nome del filesystem stesso.
+
+\begin{figure}[!htb]
+  \footnotesize \centering
+  \begin{minipage}[c]{\textwidth}
+    \includestruct{listati/statfs.h}
+  \end{minipage}
+  \normalsize 
+  \caption{La struttura \structd{statfs}.} 
+  \label{fig:sys_statfs}
+\end{figure}
+
+
+Le \acr{glibc} provvedono infine una serie di funzioni per la gestione dei due
+file \conffile{/etc/fstab} ed \conffile{/etc/mtab}, che convenzionalmente sono
+usati in quasi tutti i sistemi unix-like per mantenere rispettivamente le
+informazioni riguardo ai filesystem da montare e a quelli correntemente
+montati. Le funzioni servono a leggere il contenuto di questi file in
+opportune strutture \struct{fstab} e \struct{mntent}, e, per
+\conffile{/etc/mtab} per inserire e rimuovere le voci presenti nel file.
+
+In generale si dovrebbero usare queste funzioni (in particolare quelle
+relative a \conffile{/etc/mtab}), quando si debba scrivere un programma che
+effettua il montaggio di un filesystem; in realtà in questi casi è molto più
+semplice invocare direttamente il programma \cmd{mount}, per cui ne
+tralasceremo la trattazione, rimandando al manuale delle \acr{glibc}
+\cite{glibc} per la documentazione completa.
+
+% TODO scrivere relativamente alle varie funzioni (getfsent e getmntent &C)
+% TODO documentare swapon e swapoff (man 2 ...)
+
+
 
 
 
@@ -48,9 +704,8 @@ chiamandolo con nomi diversi o accedendovi da directory diverse.
 
 Questo è possibile anche in ambiente Unix, dove tali collegamenti sono
 usualmente chiamati \textit{link}; ma data l'architettura del sistema riguardo
-la gestione dei file (ed in particolare quanto trattato in
-sez.~\ref{sec:file_arch_func}) ci sono due metodi sostanzialmente diversi per
-fare questa operazione.
+la gestione dei file ci sono due metodi sostanzialmente diversi per fare
+questa operazione.
 
 Come spiegato in sez.~\ref{sec:file_filesystem} l'accesso al contenuto di un
 file su disco avviene passando attraverso il suo \itindex{inode}
@@ -5808,16 +6463,16 @@ directory di lavoro, ha anche una directory \textsl{radice}\footnote{entrambe
   sono contenute in due campi (rispettivamente \var{pwd} e \var{root}) di
   \struct{fs\_struct}; vedi fig.~\ref{fig:proc_task_struct}.} che, pur essendo
 di norma corrispondente alla radice dell'albero di file e directory come visto
-dal kernel (ed illustrato in sez.~\ref{sec:file_organization}), ha per il
-processo il significato specifico di directory rispetto alla quale vengono
-risolti i \itindsub{pathname}{assoluto}\textit{pathname}
-assoluti.\footnote{cioè quando un processo chiede la risoluzione di un
-  \textit{pathname}, il kernel usa sempre questa directory come punto di
-  partenza.} Il fatto che questo valore sia specificato per ogni processo apre
-allora la possibilità di modificare le modalità di risoluzione dei
-\textit{pathname} assoluti da parte di un processo cambiando questa directory,
-così come si fa coi \itindsub{pathname}{relativo}\textit{pathname} relativi
-cambiando la directory di lavoro.
+dal kernel (ed illustrato in sez.~\ref{sec:file_pathname}), ha per il processo
+il significato specifico di directory rispetto alla quale vengono risolti i
+\itindsub{pathname}{assoluto}\textit{pathname} assoluti.\footnote{cioè quando
+  un processo chiede la risoluzione di un \textit{pathname}, il kernel usa
+  sempre questa directory come punto di partenza.} Il fatto che questo valore
+sia specificato per ogni processo apre allora la possibilità di modificare le
+modalità di risoluzione dei \textit{pathname} assoluti da parte di un processo
+cambiando questa directory, così come si fa coi
+\itindsub{pathname}{relativo}\textit{pathname} relativi cambiando la directory
+di lavoro.
 
 Normalmente la directory radice di un processo coincide anche con la radice
 del filesystem usata dal kernel, e dato che il suo valore viene ereditato dal