Passaggio a UTF-8 dei sorgenti
[gapil.git] / fileintro.tex
index fde074723bc71dfa7ec6464a5e29d99638d52e8b..a195c7a4907246acd061982838c3f66abea9f8f8 100644 (file)
-\chapter{I files: introduzione}
-\label{cha:files_intro}
-Uno dei concetti fondamentali della architettura di unix è il cosiddetto
-\textit{everything is a file}, cioè il fatto che l'accesso ai vari dispositivi
-di input/output del computer viene effettuato attraverso un'interfaccia
-astratta che tratta le periferiche allo stesso modo degli usuali file di
+%% fileintro.tex
+%%
+%% Copyright (C) 2000-2011 Simone Piccardi.  Permission is granted to
+%% copy, distribute and/or modify this document under the terms of the GNU Free
+%% Documentation License, Version 1.1 or any later version published by the
+%% Free Software Foundation; with the Invariant Sections being "Prefazione",
+%% with no Front-Cover Texts, and with no Back-Cover Texts.  A copy of the
+%% license is included in the section entitled "GNU Free Documentation
+%% License".
+%%
+
+\chapter{L'architettura dei file}
+\label{cha:file_intro}
+
+Uno dei concetti fondamentali dell'architettura di un sistema Unix è il
+cosiddetto \textit{everything is a file}, cioè il fatto che l'accesso ai vari
+dispositivi di input/output del computer viene effettuato attraverso
+un'interfaccia astratta che tratta le periferiche allo stesso modo dei normali
+file di dati.
+
+Questo significa che si può accedere a qualunque periferica del computer,
+dalla seriale, alla parallela, alla console, e agli stessi dischi attraverso i
+cosiddetti \index{file!di~dispositivo} file di dispositivo (i cosiddetti
+\textit{device file}). Questi sono dei file speciali agendo sui quali i
+programmi possono leggere, scrivere e compiere operazioni direttamente sulle
+periferiche, usando le stesse funzioni che si usano per i normali file di
 dati.
 
-Questo significa che si può accedere cioè a qualunque periferica del computer,
-dalla seriale, alla parallela, alla console, e agli stessi dischi attraverso i
-cosiddetti file di dispositivo (i \textit{device files}). Questi sono dei file
-speciali agendo sui quali i programmi possono leggere, scrivere e compiere
-operazioni direttamente sulle periferiche, usando le stesse funzioni che si
-usano per i normali file di dati.
-
-In questo capitolo forniremo un'introduzione alle principali caratteristiche
-di questa interfaccia, su come essa viene implementata in Linux e su come sono
-organizzati i file nel sistema.
-
-
-\section{I file in un sistema unix-like}
-\label{sec:fileintr_overview}
-
-Visto il ruolo fondamentale che i files vengono ad assumere in un sistema
-unix, è anzitutto opportuno fornire un'introduzione dettagliata su come essi
-vengono trattati dal sistema. In particolare occorre tenere presente dov'è che
-si situa il limite fondamentale fra kernel space e user space che tracciavamo
-al \capref{cha:intro_unix}.
-
-Partiamo allora da come viene strutturata nel sistema la disposizione dei
-file: per potervi accedere il kernel usa una apposita interfaccia che permetta
-di strutturare l'informazione tenuta sullo spazio grezzo disponibile sui
-dischi, cioè quello che si chiama un \textit{filesystem} (useremo per brevità
-questo nome al posto della più prolissa traduzione italiana sistema di file). 
-
-Sarà attraverso quest'ultimo che il kernel andrà a gestire l'accesso ai dati
-memorizzati all'interno del disco stesso, strutturando l'informazione in files
-e directory (su questo aspetto torneremo con maggiori dettagli in
-\secref{sec:filedir_filesystem}).  Per poter accedere ai file contenuti in un
-disco occorrerà perciò attivare il filesystem, questo viene fatto
-\textsl{montando} il disco (o la partizione del disco).
-
-%In generale un filesystem piazzerà opportunamente sul disco dei blocchi di
-%informazioni riservate che tengono conto degli inodes allocati, di quelli
-%liberi, e delle posizioni fisiche su disco dei dati contenuti nei files, per
-
-In unix, a differenza di quanto avviene in altri sistemi operativi, tutti i
-file vengono tenuti all'interno di un unico albero la cui radice (la directory
-di \textit{root}) viene montata all'avvio. Pertanto un file viene identificato
-dall'utente usando quello che viene chiamato \textit{pathname}, cioè il
-percorso che si deve fare per accedere al file.
-
-Dopo la fase di inizializzazione il kernel riceve dal boot loader
-l'indicazione di quale dispositivo contiene il filesystem da usare come punto
-di partenza e questo viene montato come radice dell'albero (cioè nella
-directory \texttt{/}); tutti gli ulteriori dischi devono poi essere inseriti
-nell'albero utilizzando opportune subdirectory.
-
-Alcuni filesystem speciali (come \texttt{/proc} che contiene un'interfaccia ad
+In questo capitolo forniremo una descrizione dell'architettura dei file in
+Linux, iniziando da una panoramica sulle caratteristiche principali delle
+interfacce con cui i processi accedono ai file (che tratteremo in dettaglio
+nei capitoli seguenti), per poi passare ad una descrizione più dettagliata
+delle modalità con cui detto accesso viene realizzato dal sistema.
+
+
+
+\section{L'architettura generale}
+\label{sec:file_access_arch}
+
+Per poter accedere ai file, il kernel deve mettere a disposizione dei
+programmi le opportune interfacce che consentano di leggerne il contenuto; il
+sistema cioè deve provvedere ad organizzare e rendere accessibile in maniera
+opportuna l'informazione tenuta sullo spazio grezzo disponibile sui dischi.
+Questo viene fatto strutturando l'informazione sul disco attraverso quello che
+si chiama un \textit{filesystem} (vedi sez.~\ref{sec:file_arch_func}), essa
+poi viene resa disponibile ai processi attraverso quello che viene chiamato il
+\textsl{montaggio} del \textit{filesystem}.
+
+In questa sezione faremo una panoramica generica su come il sistema presenta
+i file ai processi, trattando l'organizzazione di file e directory, i tipi di
+file ed introducendo le interfacce disponibili e le loro caratteristiche.
+
+
+\subsection{L'organizzazione di file e directory}
+\label{sec:file_organization}
+
+\itindbeg{pathname}
+In Unix, a differenza di quanto avviene in altri sistemi operativi, tutti i
+file vengono tenuti all'interno di un unico albero la cui radice (quella che
+viene chiamata \textit{root directory}) viene montata all'avvio.  Un file
+viene identificato dall'utente usando quello che viene chiamato
+\textit{pathname}\footnote{il manuale della \acr{glibc} depreca questa
+  nomenclatura, che genererebbe confusione poiché \textit{path} indica anche
+  un insieme di directory su cui effettuare una ricerca (come quello in cui si
+  cercano i comandi). Al suo posto viene proposto l'uso di \textit{filename} e
+  di componente per il nome del file all'interno della directory. Non
+  seguiremo questa scelta dato che l'uso della parola \textit{pathname} è
+  ormai così comune che mantenerne l'uso è senz'altro più chiaro
+  dell'alternativa proposta.}, cioè il percorso che si deve fare per accedere
+al file a partire dalla \textit{root directory}, che è composto da una serie
+di nomi separati da una ``\file{/}''.
+
+All'avvio del sistema, completata la fase di inizializzazione, il kernel
+riceve dal bootloader l'indicazione di quale dispositivo contiene il
+filesystem da usare come punto di partenza e questo viene montato come radice
+dell'albero (cioè nella directory \file{/}); tutti gli ulteriori filesystem
+che possono essere su altri dispositivi dovranno poi essere inseriti
+nell'albero montandoli su opportune directory del filesystem montato come
+radice.
+
+Alcuni filesystem speciali (come \file{/proc} che contiene un'interfaccia ad
 alcune strutture interne del kernel) sono generati automaticamente dal kernel
-stesso, ma anche essi devono essere montati all'interno dell'albero.
-
-All'interno dello stesso albero si potranno poi inserire anche gli altri
-oggetti visti attraverso l'interfaccia che manipola i files come le FIFO, i
-link, i socket e gli stessi i file di dispositivo (questi ultimi, per
-convenzione, sono inseriti nella directory \texttt{/dev}).
-
-\subsection{Il \textit{virtual filesystem} di Linux}
-\label{sec:fileintr_vfs}
-
-Esamineremo adesso come viene implementato l'accesso ai files in Linux. Questa
-sezione riporta informazioni sui dettagli di come il kernel gestisce i files,
-ed è basata sul documento di Richard Goochs distribuito coi sorgenti del
-kernel (nella directory \texttt{linux/Documentation/vfs.txt}).
-
-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 è
-l'interfaccia astratta che il kernel rende disponibile ai programmi in user
-space attraverso la quale vengono manipolati i files; esso provvede anche
-un'astrazione delle operazioni di manipolazione sui files che permette la
-coesistenza di diversi filesystem all'interno dello stesso albero.
-
-La funzione più importante implementata dal VFS è la system call \texttt{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 di hash 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 dentry.
-
-Una singola 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, una FIFO, un file
-di dispositivo, o una qualsiasi altra cosa che possa essere rappresentata dal
-VFS (sui tipi di ``files'' possibili torneremo in seguito). A ciascuno di essi
-è associata pure una struttura che sta in memoria, e che oltre alle
-informazioni sullo specifico file contiene pure il riferimento alle funzioni
-(i \textsl{metodi}) da usare per poterlo manipolare.
-
-Le dentries ``vivono'' in memoria e non vengono mai salvate su disco, vengono
-usate per motivi di velocità, gli inodes invece stanno su disco e vengono
-copiati in memoria quando serve, ed ogni cambiamento viene copiato
-all'indietro sul disco, gli inodes che stanno in memoria sono inodes del VFS
-ed è ad essi che puntano le singole dentry.
-
-La dcache costituisce perciò una sorta di vista completa di tutto l'albero dei
-files, ovviamente per non riempire tutta la memoria questa vista è parziale
-(la dcache cioè contiene solo le dentry per i file per i quali è stato
-richiesto l'accesso), quando si vuole risolvere un nuovo pathname il VFS deve
-creare una nuova dentry e caricare l'inode corrispondente in memoria. 
-
-Questo procedimento viene eseguito dal metodo \texttt{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 dentry (ed il relativo inode)
-diventa possibile accedere alle varie operazioni sul file come la
-\texttt{open} per aprire il file o la \texttt{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 \texttt{file} in cui viene inserito un puntatore alla
-dentry e una struttura \verb|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:fileunix_fd}). Un elenco delle operazioni
-previste dal kernel è riportato in \ntab.
+stesso, ma anche essi devono essere montati all'interno dell'albero dei file.
+
+Una directory, come vedremo in maggior dettaglio in
+sez.~\ref{sec:file_vfs_work}, è anch'essa un file, solo che è un file
+particolare che il kernel riconosce come tale. Il suo scopo è quello di
+contenere una lista di nomi di file e le informazioni che associano ciascun
+nome al contenuto. Dato che questi nomi possono corrispondere ad un qualunque
+oggetto del filesystem, compresa un'altra directory, si ottiene naturalmente
+un'organizzazione ad albero inserendo nomi di directory in altre directory.
+
+Un file può essere indicato rispetto alla directory corrente semplicemente
+specificandone il nome\footnote{il manuale delle \acr{glibc} chiama i nomi
+  contenuti nelle directory \textsl{componenti} (in inglese \textit{file name
+    components}), noi li chiameremo più semplicemente \textsl{nomi} o
+  \textsl{voci}.}  da essa contenuto.  All'interno dello stesso albero si
+potranno poi inserire anche tutti gli altri oggetti visti attraverso
+l'interfaccia che manipola i file come le fifo, i link, i socket e gli stessi
+\index{file!di~dispositivo} file di dispositivo (questi ultimi, per
+convenzione, sono inseriti nella directory \file{/dev}).
+
+Il nome completo di un file viene chiamato \textit{pathname} ed il
+procedimento con cui si individua il file a cui esso fa riferimento è chiamato
+risoluzione del nome (\textit{filename resolution} o \textit{pathname
+  resolution}).  La risoluzione viene fatta esaminando il \textit{pathname} da
+sinistra a destra e localizzando ogni nome nella directory indicata dal nome
+precedente usando il carattere ``\texttt{/}'' come separatore\footnote{nel
+  caso di nome vuoto, il costrutto \file{//} viene considerato equivalente a
+  \file{/}.}: ovviamente, perché il procedimento funzioni, occorre che i nomi
+indicati come directory esistano e siano effettivamente directory, inoltre i
+permessi (si veda sez.~\ref{sec:file_access_control}) devono consentire
+l'accesso all'intero \textit{pathname}.
+
+Se il \textit{pathname} comincia con il carattere ``\texttt{/}'' la ricerca
+parte dalla directory radice del processo; questa, a meno di un \func{chroot}
+(su cui torneremo in sez.~\ref{sec:file_chroot}) è la stessa per tutti i
+processi ed equivale alla directory radice dell'albero dei file: in questo
+caso si parla di un \textsl{pathname assoluto} \itindsub{pathname}{assoluto}.
+Altrimenti la ricerca parte dalla directory corrente (su cui torneremo in
+sez.~\ref{sec:file_work_dir}) ed il pathname è detto
+\itindsub{pathname}{relativo} \textsl{pathname relativo}.
+
+I nomi ``\file{.}'' e ``\file{..}'' hanno un significato speciale e vengono
+inseriti in ogni directory: il primo fa riferimento alla directory corrente e
+il secondo alla directory \textsl{genitrice} (o \textit{parent directory})
+cioè la directory che contiene il riferimento alla directory corrente; nel
+caso la directory corrente coincida con la directory radice, allora il
+riferimento è a se stessa.  
+
+\itindend{pathname}
+
+
+\subsection{I tipi di file}
+\label{sec:file_file_types}
+
+Come detto in precedenza, in Unix esistono vari tipi di file; in Linux questi
+sono implementati come oggetti del \textit{Virtual File System} (vedi
+sez.~\ref{sec:file_vfs_work}) e sono presenti in tutti i filesystem unix-like
+utilizzabili con Linux. L'elenco dei vari tipi di file definiti dal
+\itindex{Virtual~File~System} \textit{Virtual File System} è riportato in
+tab.~\ref{tab:file_file_types}.
+
+Si tenga ben presente che questa classificazione non ha nulla a che fare con
+la classificazione dei file (che in questo caso sono sempre file di dati) in
+base al loro contenuto, o tipo di accesso. Essa riguarda invece il tipo di
+oggetti; in particolare è da notare la presenza dei cosiddetti file speciali.
+Alcuni di essi, come le \textit{fifo} (che tratteremo in
+sez.~\ref{sec:ipc_named_pipe}) ed i \textit{socket} (che tratteremo in
+cap.~\ref{cha:socket_intro}) non sono altro che dei riferimenti per utilizzare
+delle funzionalità di comunicazione fornite dal kernel. Gli altri sono i
+\index{file!di~dispositivo} \textsl{file di dispositivo} (o \textit{device
+  file}) che costituiscono una interfaccia diretta per leggere e scrivere sui
+dispositivi fisici; essi vengono suddivisi in due grandi categorie, \textsl{a
+  blocchi} e \textsl{a caratteri} a seconda delle modalità in cui il
+dispositivo sottostante effettua le operazioni di I/O.\footnote{in sostanza i
+  dispositivi a blocchi (ad esempio i dischi) corrispondono a periferiche per
+  le quali è richiesto che l'I/O venga effettuato per blocchi di dati di
+  dimensioni fissate (ad esempio le dimensioni di un settore), mentre nei
+  dispositivi a caratteri l'I/O viene effettuato senza nessuna particolare
+  struttura.}
 
 \begin{table}[htb]
+  \footnotesize
   \centering
-  \begin{tabular}[c]{c p{7cm}}
-    \textbf{funzione} & \textbf{operazione} \\
+    \begin{tabular}[c]{|l|l|p{7cm}|}
     \hline
-    \textit{open}    & apre il file \\
-    \textit{read}    & legge dal file \\
-    \textit{write}   & scrive sul file \\ 
-    \textit{llseek}  & sposta la posizione corrente sul file \\
-    \textit{ioctl}   & accede alle operazioni di controllo 
-                       (tramite la \texttt{ioctl})\\
-    \textit{readdir} & per leggere il contenuto di una directory \\
-    \textit{poll}    & \\
-    \textit{mmap}    & chiamata dalla system call \texttt{mmap}. 
-                       mappa il file in memoria\\
-    \textit{release} & chiamata quando l'ultima referenza a un file 
-                       aperto è chiusa\\
-    \textit{fsync}   & chiamata dalla system call \texttt{fsync} \\
-    \textit{fasync}  & chiamate da \texttt{fcntl} quando è abilitato 
-                       il modo asincrono per l'I/O su file. \\
+    \multicolumn{2}{|c|}{\textbf{Tipo di file}} & \textbf{Descrizione} \\
     \hline
-  \end{tabular}
-  \caption{Operazioni sui file definite nel VFS.}
-  \label{tab:fileintr_file_operations}
-\end{table}
-
-In questo modo per ciascun file diventano utilizzabili una serie di operazioni
-(non è dette che tutte siano disponibili), che costituiscono l'interfaccia
-astratta del VFS, e qualora se ne voglia eseguire una il kernel andrà ad
-utilizzare la opportuna routine dichiarata in \verb|f_ops| appropriata al tipo
-di file in questione. 
-
-Così sarà possibile scrivere sulla porta seriale come su un file di dati
-normale; ovviamente certe operazioni (nel caso della seriale ad esempio la
-\textit{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 controllo di accesso}
-\label{sec:fileintr_access_ctrl}
-
-In unix è implementata da qualunque filesystem standard una forma elementare
-(ma adatta alla maggior parte delle esigenze) di controllo di accesso ai
-files. Torneremo sull'argomento in dettaglio più avanti (vedi
-\secref{sec:filedir_access_control}), qui ci limitiamo ad una introduzione dei
-concetti essenziali.
-
-Si tenga conto poi che quanto diremo è vero solo per filesystem di tipo Unix,
-e non è detto che sia applicabile (ed infatti non è vero per il filesystem di
-Windows) a un filesystem qualunque. Esistono inoltre estensioni che permettono
-di implementare le ACL (\textit{Access Control List}) che sono un meccanismo
-di controllo di accesso molto più sofisticato.
-
-Ad ogni file Unix associa sempre l'utente che ne è proprietario (il cosiddetto
-\textit{owner}) e il gruppo di appartenenza, secondo il meccanismo degli uid e
-gid accennato in \secref{sec:intro_usergroup}, e un insieme di permessi che
-sono divisi in tre classi, e cioè attribuiti rispettivamente al proprietario,
-a qualunque utente faccia parte del gruppo cui appartiene il file, e a tutti
-gli altri utenti.
-
-I permessi sono espressi da un insieme di 12 bit: di questi i nove meno
-significativi sono usati a gruppi di tre per indicare i permessi base di
-lettura, scrittura ed esecuzione (indicati rispettivamente con le lettere
-\textit{w}, \textit{r} \textit{x}) applicabili rispettivamente al
-proprietario, al gruppo, a tutti (una descrizione più dettagliata dei vari
-permessi associati ai file è riportata in \secref{sec:filedir_suid_sgid}).  I
-restanti tre bit sono usati per indicare alcune caratteristiche più complesse
-(\textit{suid}, \textit{sgid}, e \textit{sticky}) su cui pure torneremo in
-seguito (vedi \secref{sec:filedir_suid_sgid} e \secref{sec:filedir_sticky}).
-
-Tutte queste informazioni sono tenute per ciascun file nell'inode. Quando un
-processo cerca l'accesso al file esso controlla i propri uid e gid
-confrontandoli con quelli del file e se l'operazione richiesta è compatibile
-con i permessi associati al file essa viene eseguita, altrimenti viene
-bloccata ed è restituito un errore di \texttt{EPERM}. Questo procedimento non
-viene eseguito per l'amministratore di sistema (il cui uid è zero) il quale ha
-pertanto accesso senza restrizione a qualunque file del sistema.
-
-In realtà il procedimento è più complesso di quanto descritto in maniera
-elementare qui; inoltre ad un processo sono associati diversi identificatori,
-torneremo su questo in maggiori dettagli in seguito in \secref{sec:proc_perms}.
-
-\subsection{I tipi di files}
-\label{sec:fileintr_file_types}
-
-Come detto in precedenza esistono vari tipi di oggetti implementati del VFS
-per i quali è disponibile l'interfaccia astratta da esso provveduta. Un elenco
-dei vari tipi di file definiti nel VFS è il seguente:
-\begin{table}[htb]
-  \begin{center}
-    \begin{tabular}[c]{l l p{7cm}}
-    \multicolumn{2}{c}{\textbf{Nome}} & \textbf{Descrizione} \\
     \hline
-      \textit{regular file} & \textsl{file normale} &
-      un file che contiene dei dati (l'accezione normale di file) \\
+      \textit{regular file} & \textsl{file regolare} &
+      Un file che contiene dei dati (l'accezione normale di file).\\
       \textit{directory} & \textsl{cartella o direttorio} &
-      un file che contiene una lista di nomi associati a degli inodes \\
+      Un file che contiene una lista di nomi associati a degli
+      \index{inode} \textit{inode} (vedi sez.~\ref{sec:file_vfs}).\\
       \textit{symbolic link} & \textsl{collegamento simbolico} &
-      un file che contiene un riferimento ad un altro file/directory \\
+      Un file che contiene un riferimento ad un altro file/directory.\\
       \textit{char device} & \textsl{dispositivo a caratteri} &
-      un file che identifica una periferica ad accesso sequenziale \\
+      Un file che identifica una periferica ad accesso a caratteri.\\
       \textit{block device} & \textsl{dispositivo a blocchi} &
-      un file che identifica una periferica ad accesso diretto \\
-      \textit{fifo} & \textsl{tubo} &
-      un file speciale che identifica una linea di comunicazione software
-      (unidirezionale) \\
-      \textit{socket} & \textsl{manicotto} &
-      un file speciale che identifica una linea di comunicazione software
-      (bidirezionale) \\
+      Un file che identifica una periferica ad accesso a blocchi.\\
+      \textit{fifo} & ``\textsl{coda}'' &
+      Un file speciale che identifica una linea di comunicazione software
+      unidirezionale (vedi sez.~\ref{sec:ipc_named_pipe}).\\
+      \textit{socket} & ``\textsl{presa}''&
+      Un file speciale che identifica una linea di comunicazione software
+      bidirezionale (vedi cap.~\ref{cha:socket_intro}).\\
     \hline
     \end{tabular}
     \caption{Tipologia dei file definiti nel VFS}
-    \label{tab:fileintr_file_types}
-  \end{center}
+    \label{tab:file_file_types}
 \end{table}
 
-Tutto ciò non ha ovviamente nulla a che fare con la classificazione sui tipi
-di file (in questo caso file di dati) in base al loro contenuto, o tipo di
-accesso.  Una delle differenze principali con altri sistemi operativi (come il
-VMS o Windows) è che per Unix tutti i file di dati sono identici e contengono
-un flusso continuo di bytes; non esiste cioè differenza per come vengono visti
-dal sistema file di diverso contenuto o formato (come nel caso di quella fra
-file di testo e binari che c'è in Windows) né c'è una strutturazione a record
-per il cosiddetto ``accesso diretto'' come nel caso del VMS.
-%  (con i kernel
-% della serie 2.4 è disponibile una forma di accesso diretto ai dischi il
-% \textit{raw access} che però non ha nulla a che fare con questo).
-
-Una seconda differenza è nel formato dei file ASCII; in Unix la fine riga è
-codificata in maniera diversa da Windows o MacIntosh, in particolare il fine
-riga è il carattere \texttt{LF} (o \verb|\n|) al posto del \texttt{CR}
-(\verb|\r|) del mac e del \texttt{CR LF} di Windows. Questo può causare alcuni
-problemi qualora nei programmi si facciano assunzioni sul terminatore della
-riga.
-
-
-\section{Una panoramica sull'uso dei file}
-\label{sec:fileintr_io_overview}
-
-Per poter accedere al contenuto dei file occorre anzitutto aprirlo. Questo
-crea un canale di comunicazione che permette di eseguire una serie di
-operazioni. Una volta terminate le operazioni, il file dovrà essere chiuso, e
-questo chiuderà il canale di comunicazione impedendo ogni ulteriore
-operazione.
+Una delle differenze principali con altri sistemi operativi (come il VMS o
+Windows) è che per Unix tutti i file di dati sono identici e contengono un
+flusso continuo di byte. Non esiste cioè differenza per come vengono visti dal
+sistema file di diverso contenuto o formato (come nel caso di quella fra file
+di testo e binari che c'è in Windows) né c'è una strutturazione a record per
+il cosiddetto ``\textsl{accesso diretto}'' come nel caso del
+VMS.\footnote{questo vale anche per i dispositivi a blocchi: la strutturazione
+  dell'I/O in blocchi di dimensione fissa avviene solo all'interno del kernel,
+  ed è completamente trasparente all'utente. Inoltre talvolta si parla di
+  \textsl{accesso diretto} riferendosi alla capacità, che non ha niente a che
+  fare con tutto ciò, di effettuare, attraverso degli appositi
+  \index{file!di~dispositivo} file di dispositivo, operazioni di I/O
+  direttamente sui dischi senza passare attraverso un filesystem, il
+  cosiddetto \textit{raw access}, introdotto coi kernel della serie 2.4.x ed
+  in sostanziale disuso.}
+
+Una seconda differenza è nel formato dei file di testo: in Unix la fine riga è
+codificata in maniera diversa da Windows o dal vecchio MacOS, in particolare
+il fine riga è il carattere \texttt{LF} (o \verb|\n|) al posto del \texttt{CR}
+(\verb|\r|) del vecchio MacOS e del \texttt{CR LF} di Windows.\footnote{per
+  questo esistono in Linux dei programmi come \cmd{unix2dos} e \cmd{dos2unix}
+  che effettuano una conversione fra questi due formati di testo.} Questo può
+causare alcuni problemi qualora nei programmi si facciano assunzioni sul
+terminatore della riga.
+
+Si ricordi infine che un kernel Unix non fornisce nessun supporto per la
+tipizzazione dei file di dati e che non c'è nessun supporto del sistema per le
+estensioni come parte del filesystem.\footnote{non è così ad esempio nel
+  filesystem HFS dei Mac, che supporta delle risorse associate ad ogni file,
+  che specificano fra l'altro il contenuto ed il programma da usare per
+  leggerlo. In realtà per alcuni filesystem esiste la possibilità di
+  associare delle risorse ai file con gli \textit{extended attributes} (vedi
+  sez.~\ref{sec:file_xattr}), ma è una caratteristica tutt'ora poco
+  utilizzata, dato che non corrisponde al modello classico dei file in un
+  sistema Unix.} Ciò nonostante molti programmi adottano delle convenzioni per
+i nomi dei file, ad esempio il codice C normalmente si mette in file con
+l'estensione \file{.c}; un'altra tecnica molto usata è quella di utilizzare i
+primi 4 byte del file per memorizzare un \textit{magic number} che classifichi
+il contenuto; entrambe queste tecniche, per quanto usate ed accettate in
+maniera diffusa, restano solo delle convenzioni il cui rispetto è demandato
+alle applicazioni stesse.
+
 
 \subsection{Le due interfacce ai file}
-\label{sec:fileintr_io_api}
+\label{sec:file_io_api}
 
-In unix le modalità di accesso ai file e le relative interfacce di
-programmazione sono due, basate su due diversi meccanismi di connessione. 
+In Linux le modalità di accesso ai file e le relative interfacce di
+programmazione sono due, basate su due diversi meccanismi con cui è possibile
+accedere al loro contenuto.
 
-La prima è l'interfaccia standard di unix, quella che il manuale delle glibc
-chiama interfaccia dei descrittore di file (o \textit{file descriptor}).  È
-un'interfaccia specifica di unix e provvede un accesso non bufferizzato.
-L'interfaccia è primitiva ed essenziale, l'accesso viene detto non
+La prima è l'interfaccia standard di Unix, quella che il manuale delle
+\textsl{glibc} chiama interfaccia dei descrittori di file (o \textit{file
+  descriptor}).  È un'interfaccia specifica dei sistemi unix-like e fornisce
+un accesso non bufferizzato; la tratteremo in dettaglio in
+cap.~\ref{cha:file_unix_interface}.
+
+L'interfaccia è primitiva ed essenziale, l'accesso viene detto non
 bufferizzato in quanto la lettura e la scrittura vengono eseguite chiamando
-direttamente le system call del kernel (in realtà il kernel effettua al suo
+direttamente le system call del kernel (in realtà il kernel effettua al suo
 interno alcune bufferizzazioni per aumentare l'efficienza nell'accesso ai
-dispositivi); i file descriptors sono rappresentati da numeri interi (cioè
-semplici variabili di tipo \texttt{int}).  L'interfaccia è definita
-nell'header \texttt{unistd.h}.
-
-La seconda interfaccia è quella che il manuale della glibc chiama degli
-\textit{stream}, essa provvede funzioni più evolute e un accesso bufferizzato
-(controllato dalla implementazione fatta dalle librerie del C).  Questa è
-l'interfaccia standard usata dal linguaggio C e perciò si trova anche su tutti
-i sistemi non Unix. Gli stream sono oggetti complessi e sono rappresentati da
-puntatori ad un opportuna struttura definita dalle librerie del C, si accede
-ad essi sempre in maniera indiretta utilizzando il tipo \texttt{FILE *}.
-L'interfaccia è definita nell'header \texttt{stdio.h}.
+dispositivi); i \index{file!descriptor} \textit{file descriptor} sono
+rappresentati da numeri interi (cioè semplici variabili di tipo \ctyp{int}).
+L'interfaccia è definita nell'header \file{unistd.h}.
+
+La seconda interfaccia è quella che il manuale della \acr{glibc} chiama degli
+\index{file!stream} \textit{stream}.\footnote{in realtà una interfaccia con lo
+  stesso nome è stata introdotta a livello di kernel negli Unix derivati da
+  \textit{System V}, come strato di astrazione per file e socket; in Linux
+  questa interfaccia, che comunque ha avuto poco successo, non esiste, per cui
+  facendo riferimento agli \index{file!stream} \textit{stream} useremo il
+  significato adottato dal manuale delle \acr{glibc}.} Essa fornisce funzioni
+più evolute e un accesso bufferizzato (controllato dalla implementazione fatta
+dalle \acr{glibc}), la tratteremo in dettaglio nel
+cap.~\ref{cha:files_std_interface}.
+
+Questa è l'interfaccia standard specificata dall'ANSI C e perciò si trova
+anche su tutti i sistemi non Unix. Gli \index{file!stream} \textit{stream}
+sono oggetti complessi e sono rappresentati da puntatori ad un opportuna
+struttura definita dalle librerie del C; si accede ad essi sempre in maniera
+indiretta utilizzando il tipo \ctyp{FILE *}.  L'interfaccia è definita
+nell'header \file{stdio.h}.
 
 Entrambe le interfacce possono essere usate per l'accesso ai file come agli
-altri oggetti del VFS (pipes, socket, device), ma per poter accedere alle
-operazioni di controllo sul particolare tipo di oggetto del VFS scelto occorre
-usare l'interfaccia standard di unix coi file descriptors. Allo stesso modo
-devono essere usati i file descriptor se si vuole ricorrere a modalità
-speciali di I/O come il polling o il non-bloccante (vedi
-\secref{sec:file_xxx}).
-
-Gli stream forniscono un'interfaccia di alto livello costruita sopra quella
-dei file descriptor, che tratta tutti i file nello stesso modo, con
-l'eccezione di poter scegliere tra diversi stili di bufferizzazione.  Il
-maggior vantaggio degli stream è che l'interfaccia per le operazioni di
-input/output è enormemente più ricca di quella dei file descriptor, che
-provvedono solo funzioni elementari per la lettura/scrittura diretta di
-blocchi di bytes.  In particolare gli stream dispongono di tutte le funzioni
-di formattazione per l'input e l'output adatte per manipolare anche i dati in
-forma di linee o singoli caratteri.
+altri oggetti del VFS (fifo, socket, dispositivi, sui quali torneremo in
+dettaglio a tempo opportuno), ma per poter accedere alle operazioni di
+controllo (descritte in sez.~\ref{sec:file_fcntl} e sez.~\ref{sec:file_ioctl})
+su un qualunque tipo di oggetto del VFS occorre usare l'interfaccia standard
+di Unix con i \textit{file descriptor}. Allo stesso modo devono essere usati i
+\index{file!descriptor} \textit{file descriptor} se si vuole ricorrere a
+modalità speciali di I/O come il \index{file!locking} \textit{file locking} o
+l'I/O non-bloccante (vedi cap.~\ref{cha:file_advanced}).
+
+Gli \textit{stream} forniscono un'interfaccia di alto livello costruita sopra
+quella dei \textit{file descriptor}, che permette di poter scegliere tra
+diversi stili di bufferizzazione.  Il maggior vantaggio degli \textit{stream}
+è che l'interfaccia per le operazioni di input/output è enormemente più ricca
+di quella dei \textit{file descriptor}, che forniscono solo funzioni
+elementari per la lettura/scrittura diretta di blocchi di byte.  In
+particolare gli \index{file!stream} \textit{stream} dispongono di tutte le
+funzioni di formattazione per l'input e l'output adatte per manipolare anche i
+dati in forma di linee o singoli caratteri.
 
 In ogni caso, dato che gli stream sono implementati sopra l'interfaccia
-standard di unix, è sempre possibile estrarre il file descriptor da uno stream
-ed eseguirvi operazioni di basso livello, o associare in un secondo tempo uno
-stream ad un file descriptor.
-
-In generale, se non necessitano specificatamente le funzionalità di basso
-livello, è opportuno usare sempre gli stream per la loro maggiore portabilità
-essendo questi ultimi definiti nello standard ANSI C; l'interfaccia con i file
-descriptor invece 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 Unix 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
-bytes 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:filedir_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, quando tratteremo l'input/output sui file,
-esaminando in dettaglio come tutto ciò viene realizzato.
-
-Si ricordi infine che in unix non esistono i tipi di file e che non c'è nessun
-supporto per le estensioni come parte del filesystem. Ciò non ostante molti
-programmi adottano delle convenzioni per i nomi dei file, ad esempio il codice
-C normalmente si mette in file con l'estensione .c, ma questa è, appunto, solo
-una convenzione.
+standard di Unix, è sempre possibile estrarre il \textit{file descriptor} da
+uno stream ed eseguirvi operazioni di basso livello, o associare in un secondo
+tempo uno \index{file!stream} \textit{stream} ad un \index{file!descriptor}
+\textit{file descriptor}.
+
+In generale, se non necessitano specificatamente le funzionalità di basso
+livello, è opportuno usare sempre gli \index{file!stream} \textit{stream} per
+la loro maggiore portabilità, essendo questi ultimi definiti nello standard
+ANSI C; l'interfaccia con i \index{file!descriptor} \textit{file descriptor}
+infatti segue solo lo standard POSIX.1 dei sistemi Unix, ed è pertanto di
+portabilità più limitata.
+
+
+
+\section{L'architettura della gestione dei file}
+\label{sec:file_arch_func}
+
+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 più usato con
+Linux, l'\acr{ext2} (e derivati).
+
+
+\subsection{Il \textit{Virtual File System} di Linux}
+\label{sec:file_vfs}
+
+% 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}
 
+In Linux il concetto di \textit{everything is a file} è stato implementato
+attraverso il \textit{Virtual File System} (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 funzioni 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
+fig.~\ref{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},
+\index{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 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 sez.~\ref{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 funzioni 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 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
+\index{inode} 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 \textit{Virtual File System}}
+\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 \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
+\index{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 \index{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 \index{inode} inode che stanno in memoria
+sono \index{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 \index{inode} l'inode corrispondente in memoria.
+
+Questo procedimento viene eseguito dal metodo \code{lookup()} \index{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
+\index{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 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_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 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
+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
+\index{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} \index{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 \index{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}).
+  
+\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 \index{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 \index{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 \index{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 \index{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 \index{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 \index{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 \index{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)
+
+
+% LocalWords:  everything is device kernel filesystem sez pathname root glibc
+% LocalWords:  path filename bootloader proc name components fifo socket dev LF
+% LocalWords:  resolution chroot parent Virtual System like tab cap l'I regular
+% LocalWords:  inode symbolic char block VFS VMS Windows dell'I raw access Mac
+% LocalWords:  CR dos HFS l'XFS SGI magic number descriptor system call int ext
+% LocalWords:  nell'header unistd stream dall'ANSI stdio locking POSIX fig type
+% LocalWords:  register superblock dell'inode stat entry cache dcache dentry ln
+% LocalWords:  l'inode lookup ops read write llseek ioctl readdir poll nell'I
+% LocalWords:  multiplexing mmap fsync fasync seek group dall' dell' img
+% LocalWords:  count unlink nell' rename gapil second Tb attributes BSD SVr gid
+% LocalWords:  sgid append only log fs linux extented linked list third MacOS
+
+
+%%% Local Variables: 
+%%% mode: latex
+%%% TeX-master: "gapil"
+%%% End: