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.
+cambiare i nomi di file e directory e 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 gestione dell'I/O
+sui file è lasciato al capitolo successivo.
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).
+fare una panoramica sul filesystem più usato con Linux, l'\acr{ext2} ed i suoi
+successori.
\subsection{Il funzionamento del \textit{Virtual File System} di Linux}
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.
+tutti i filesystem devono implementare per l'accesso ai file che contengono e
+l'interfaccia che consente di eseguire l'I/O sui file, che questi siano di
+dati o dispositivi.
+
+L'interfaccia fornita dal VFS comprende in sostanza tutte le funzioni che
+riguardano i file, le operazioni implementate dal VFS sono realizzate con una
+astrazione che prevede quattro tipi di oggetti strettamente correlati: i
+filesystem, le \textit{dentry}, gli \textit{inode} ed i file. A questi oggetti
+corrispondono una serie di apposite strutture definite dal kernel che
+contengono come campi le funzioni di gestione e realizzano l'infrastruttura
+del VFS. L'interfaccia è estremamente complessa, ne faremo pertanto una
+trattazione estremamente semplificata che consenta di comprenderne i principi
+difunzionamento.
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 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
+\code{register\_filesystem} passando come argomento la struttura
+\kstruct{file\_system\_type} (la cui definizione è riportata in
+fig.~\ref{fig:kstruct_file_system_type}) relativa a quel filesystem. Questa
+verrà inserita nella tabella, ed il nuovo filesystem comparirà in
+\procfile{/proc/filesystems}.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\textwidth}
+ \includestruct{listati/file_system_type.h}
+ \end{minipage}
+ \normalsize
+ \caption{Estratto della struttura \kstructd{file\_system\_type} usata dal
+ VFS (da \texttt{include/linux/fs.h}).}
+ \label{fig:kstruct_file_system_type}
+\end{figure}
+
+La struttura \kstruct{file\_system\_type}, oltre ad una serie di dati interni,
+come il nome del tipo di filesystem nel campo \var{name},\footnote{quello che
+ viene riportato in \procfile{/proc/filesystems} e che viene usato come
+ parametro dell'opzione \texttt{-t} del comando \texttt{mount}.} contiene i
+riferimenti alle funzioni di base che consentono l'utilizzo di quel
+filesystem. In particolare la funzione \code{mount} del quarto campo è quella
+che verrà invocata tutte le volte che si dovrà effettuare il montaggio di un
+filesystem di quel tipo. Per ogni nuovo filesystem si dovrà allocare una di
+queste strutture ed inizializzare i relativi campi con i dati specifici diquel
+filesystem, ed in particolare si dovra creare anche la relativa versione della
+funzione \code{mount}.
+
+Come illustrato in fig.~\ref{fig:kstruct_file_system_type} questa funzione
+restituisce una \textit{dentry}, abbreviazione che sta per \textit{directory
+ entry}. Le \textit{dentry} sono gli oggetti che il kernel usa per eseguire
+la \textit{pathname resolution}, ciascuna di esse corrisponde ad un
+\textit{pathname} e contiene il riferimento ad un \textit{inode}, che come
+vedremo a breve è l'oggetto usato dal kernel per identificare un un
+file.\footnote{in questo caso si parla di file come di un qualunque oggetto
+ generico che sta sul filesystem.} La \textit{dentry} ottenuta dalla chiamata
+alla funzione \code{mount} sarà inserita in corrispondenza al
+\textit{pathname} della directory in cui il filesystem è stato montato.
+
+% NOTA: struct dentry è dichiarata in include/linux/dcache.h
+
+Le \textit{dentry} sono oggetti del VFS che vivono esclusivamente in memoria,
+nella cosiddetta \textit{directory entry cache} (spesso chiamata in breve
+\textit{dcache}). Ogni volta che una \textit{system call} specifica un
+\textit{pathname} viene effettuata una ricerca nella \textit{dcache} per
+ottenere immediatamente la \textit{dentry} corrispondente,\footnote{il buon
+ funzionamento della \textit{dcache} è in effetti di una delle parti più
+ critiche per le prestazioni del sistema.} che a sua ci darà, tramite
+l'\textit{inode}, il riferimento al file.
+
+Dato che normalmente non è possibile mantenere nella \textit{dcache} le
+informazioni relative a tutto l'albero dei file la procedura della
+\textit{pathname resolution} richiede un meccanismo con cui riempire gli
+eventuali vuoti. Il meccanismo prevede che tutte le volte che si arriva ad una
+\textit{dentry} mancante venga invocata la funzione \texttt{lookup} dell'inode
+associato alla \textit{dentry} precedente nella risoluzione del
+\textit{pathname},\footnote{che a questo punto è una directory, per cui si può
+ cercare al suo interno il nome di un file.} il cui scopo è risolvere il nome
+mancante e fornire la sua \textit{dentry} che a questo punto verrà inserita
+nella cache.
+
+Dato che tutte le volte che si monta un filesystem la funzione \texttt{mount}
+della corrispondente \kstruct{file\_system\_type} inserisce la \textit{dentry}
+iniziale nel \itindex{mount~point} \textit{mount point} dello stesso si avrà
+comunque un punto di partenza. Inoltre essendo questa \textit{dentry} relativa
+a quel tipo di filesystem essa farà riferimento ad un \textit{inode} di quel
+filesystem, e come vedremo questo farà sì che venga eseguita una
+\texttt{lookup} adatta per effettuare la risoluzione dei nomi per 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}.
+% Un secondo effetto della chiamata funzione \texttt{mount} di
+% \kstruct{file\_system\_type} è quello di allocare una struttura
+% \kstruct{super\_block} per ciascuna istanza montata, che contiene le
+% informazioni generali di un qualunque filesystem montato, come le opzioni di
+% montaggio, le dimensioni dei blocchi, quando il filesystem è stato montato
+% ecc. Fra queste però viene pure inserta, nel campo \var{s\_op}, una ulteriore
+% struttura \kstruct{super\_operations}, il cui contenuto sono i puntatori
+% alle funzioni di gestione di un filesystem, anche inizializzata in modo da
+% utilizzare le versioni specifiche di quel filesystem.
+
+L'oggetto più importante per il funzionamento del VFS è probabilmente
+l'\textit{inode}, ma con questo nome si può fare riferimento a due cose
+diverse. La prima è la struttura su disco (su cui torneremo anche in
+sez.~\ref{sec:file_filesystem}) che fa parte della organizzazione dei dati
+realizzata dal filesystem e che contiene le informazioni relative alle
+proprietà (i cosiddetti \textsl{metadati}) di ogni oggetto presente su di esso
+(si intende al solito uno qualunque dei tipi di file di
+tab.~\ref{tab:file_file_types}).
+
+La seconda è la corrispondente struttura \kstruct{inode}, della cui
+definizione si è riportato un estratto in
+fig.~\ref{fig:kstruct_inode}.\footnote{l'estratto fa riferimento alla versione
+ del kernel 2.6.37.} Questa struttura viene mantenuta in memoria ed è a
+questa che facevamo riferimento quando parlavamo dell'\textit{inode} associato
+a ciascuna \textit{dentry}. Nella struttura in memoria sono presenti gli
+stessi \textsl{metadati} memorizzati su disco, che vengono letti quando questa
+struttura viene allocata e trascritti all'indietro se modificati.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\textwidth}
+ \includestruct{listati/inode.h}
+ \end{minipage}
+ \normalsize
+ \caption{Estratto della struttura \kstructd{inode} del kernel (da
+ \texttt{include/linux/fs.h}).}
+ \label{fig:kstruct_inode}
+\end{figure}
+
+Il fatto che la struttura \kstruct{inode} sia mantenuta in memoria,
+direttamente associata ad una \textit{dentry}, rende sostanzialmente immediate
+le operazioni che devono semplicemente effettuare un accesso ai dati in essa
+contenuti: è così ad esempio che viene realizzata la \textit{system call}
+\func{stat} che vedremo in sez.~\ref{sec:file_stat}. Rispetto ai dati salvati
+sul disco questa struttura contiene però anche quanto necessario alla
+implementazione del VFS, ed in particolare è importante il campo \var{i\_op}
+che, come illustrato in fig.~\ref{fig:kstruct_inode}, contiene il puntatore ad
+una struttura di tipo \kstruct{inode\_operation}, la cui definizione si può
+trovare nel file \texttt{include/kernel/fs.h} dei sorgenti del kernel.
+
+Questa struttura non è altro che una tabella di funzioni, ogni suo membro cioè
+è un puntatore ad una funzione, e, come suggerisce il nome della struttura
+stessa, queste funzioni, le principali delle quali sono riportate in
+tab.~\ref{tab:file_inode_operations}) sono quelle che definiscono le
+operazioni che il VFS può compiere su un \textit{inode}.
+
+\begin{table}[htb]
+ \centering
+ \footnotesize
+ \begin{tabular}[c]{|l|l|}
+ \hline
+ \textbf{Funzione} & \textbf{Operazione} \\
+ \hline
+ \hline
+ \textsl{\code{create}} & Chiamata per creare un nuovo file (vedi
+ sez.~\ref{sec:file_open}).\\
+ \textsl{\code{link}} & Crea un \textit{hard link} (vedi
+ sez.~\ref{sec:file_link}).\\
+ \textsl{\code{unlink}} & Cancella un \textit{hard link} (vedi
+ sez.~\ref{sec:file_link}).\\
+ \textsl{\code{symlink}}& Crea un link simbolico (vedi
+ sez.~\ref{sec:file_symlink}).\\
+ \textsl{\code{mkdir}} & Crea una directory (vedi
+ sez.~\ref{sec:file_dir_creat_rem}).\\
+ \textsl{\code{rmdir}} & Rimuove una directory (vedi
+ sez.~\ref{sec:file_dir_creat_rem}).\\
+ \textsl{\code{mknod}} & Crea un file speciale (vedi
+ sez.~\ref{sec:file_mknod}).\\
+ \textsl{\code{rename}} & Cambia il nome di un file (vedi
+ sez.~\ref{sec:file_remove}).\\
+ \textsl{\code{lookup}}& Risolve il nome di un file.\\
+ \hline
+ \end{tabular}
+ \caption{Le principali operazioni sugli \textit{inode} definite tramite
+ \kstruct{inode\_operation}.}
+ \label{tab:file_inode_operations}
+\end{table}
+
+Possiamo notare come molte di queste funzioni abbiano nomi sostanzialmente
+identici alle varie \textit{system call} con le quali si gestiscono file e
+directory che tratteremo nel resto del capitolo. Quello che succede è che
+tutte le volte che deve essere eseguita una \textit{system call}, o una
+qualunque altra operazione su un \textit{inode} (come \texttt{lookup}) il VFS
+andrà ad utilizzare la funzione corrispondente attraverso il puntatore
+\var{i\_op}.
+
+Sarà allora sufficiente che nella realizzazione di un filesystem si crei una
+opportuna istanza di \kstruct{inode\_operation} contenente i puntatori alla
+implementazione di queste funzioni per quel filesystem e quel punto le
+strutture \kstruct{inode} usate per gli oggetti di quel filesystem otterranno
+il puntatore a detta istanza di \kstruct{inode\_operation} e verranno
+automaticamente usate le funzioni corrette.
+
+Si noti però come in tab.~\ref{tab:file_inode_operations} non sia presente la
+funzione \texttt{open} che invece è citata in
+tab.~\ref{tab:file_file_operations}.\footnote{essa può essere comunque
+ invocata dato che nella struttura \kstruct{inode} è presente anche il
+ puntatore \func{i\_fop} alla struttura \kstruct{file\_operation} che
+ fornisce detta funzione.} Questo avviene perché su Linux l'apertura di un
+file richiede comunque un'altra operazione: l'allocazione di una struttura di
+tipo \kstruct{file} che viene associata ad ogni file aperto nel sistema.
+
+I motivi per cui viene usata una struttura a parte sono diversi, anzitutto,
+come illustrato in sez.~\ref{sec:file_fd}, questa è necessaria per le
+operazioni eseguite dai processi con l'interfaccia dei file descriptor; ogni
+processo infatti mantiene il riferimento ad una struttura \kstruct{file} per
+ogni file che ha aperto, ed è tramite essa che esegue le operazioni di I/O.
+
+Inoltre se le operazioni relative agli \textit{inode} fanno riferimento ad
+oggetti posti all'interno di un filesystem e vi si applicano quindi le
+funzioni fornite nell'implementazione di quest'ultimo, quando si apre un file
+questo può essere anche un file di dispositivo, ed in questo caso il VFS
+invece di usare le operazioni fornite dal filesystem (come farebbe per un file
+di dati) dovrà invece ricorrere a quelle fornite dal driver del dispositivo.
+
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{\textwidth}
+ \includestruct{listati/file.h}
+ \end{minipage}
+ \normalsize
+ \caption{Estratto della struttura \kstructd{file} del kernel (da
+ \texttt{include/linux/fs.h}).}
+ \label{fig:kstruct_file}
+\end{figure}
+
+Come si può notare dall'estratto di fig.~\ref{fig:kstruct_file}, la struttura
+contiene, oltre ad alcune informazioni usate dall'interfaccia dei file
+descriptor il cui significato emergerà più avanti, il puntatore \struct{f\_op}
+ad una struttura \kstruct{file\_operation}. Questa è l'analoga per i file di
+\kstruct{inode\_operation}, e definisce le operazioni generiche fornite dal
+VFS per i file. Si sono riportate in tab.~\ref{tab:file_file_operations} le
+più significative.
\begin{table}[htb]
\centering
sez.~\ref{sec:file_asyncronous_io}) sul file.\\
\hline
\end{tabular}
- \caption{Operazioni sui file definite nel VFS.}
+ \caption{Operazioni sui file definite tramite \kstruct{file\_operation}.}
\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.
+Anche in questo caso tutte le volte che deve essere eseguita una
+\textit{system call} o una qualunque altra operazione sul file il VFS andrà ad
+utilizzare la funzione corrispondente attraverso il puntatore
+\var{f\_op}. Dato che è cura del VFS quando crea la struttura all'apertura del
+file, assegnare a \var{f\_op} il puntatore alla versione di
+\kstruct{file\_operation} corretta per quel file, sarà possibile scrivere allo
+stesso modo sulla porta seriale come su un normale file di dati, e lavorare
+sui file allo stesso modo indipendentemente dal filesystem.
+
+Il VFS realizza la quasi totalità delle operazioni relative ai file grazie
+alle funzioni presenti nelle due strutture \kstruct{inode\_operation}
+\kstruct{file\_operation}. Ovviamente non è detto che tutte le operazioni
+possibili siano poi disponibili in tutti i casi, ad esempio una \code{seek}
+non è realizzabile per un dispositivo come la porta seriale o per una fifo,
+mentre sui file del filesystem \texttt{vfat} non sono disponibili i permessi,
+ma resta il fatto che grazie al VFS le \textit{system call} per le operazioni
+sui file restano sempre le stesse nonostante le enormi differenze che possono
+esserci negli oggetti a cui si applicano.
+
+
\itindend{Virtual~File~System}
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.
+diversi, ognuno dei quali avrà una sua particolare struttura e funzionalità
+proprie. Per questo 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
+partizione può contenere un filesystem. Una possibile strutturazione
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.
+in essa per semplicità si è fatto riferimento alla struttura del filesystem
+\acr{ext2}, che prevede una separazione dei dati in \textit{block group} che
+replicano il cosiddetto \textit{superblock} (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} \textit{inode} e lo spazio a
+disposizione per i dati e le directory.\footnote{questo non è del tutto vero
+ per filesystem evoluti come \textsl{btrfs}, ma per il momento limitiamoci
+ alla implementazione classica.}
\begin{figure}[!htb]
\centering
\end{figure}
Se si va ad esaminare con maggiore dettaglio la strutturazione
-dell'informazione all'interno del singolo filesystem (tralasciando i dettagli
+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
+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}.
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
+ (vedi sez.~\ref{sec:file_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ù
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}.
+ funzione per cancellare un file si chiama \func{unlink} (vedi
+ sez.~\ref{sec:file_link}), 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
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.
+ attraverso la funzione \func{rename}, vedi
+ sez.~\ref{sec:file_remove}). 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
\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{/}.
+ \itindex{mount~point} \textit{mount point} o di spostarlo
+ quando \param{target} non è un \itindex{mount~point} \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
\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.
+La funzione monta sulla directory \param{target}, detta \itindex{mount~point}
+\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
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.
+disponibile nella directory specificata come \itindex{mount~point}
+\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
+\itindex{mount~point} \textit{mount point} da una directory ad un'altra, sia
+montare in diversi \itindex{mount~point} \textit{mount point} lo stesso
+filesystem, sia montare più filesystem sullo stesso \itindex{mount~point}
+\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
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
+significativi sono un \itindex{magic~number} \textit{magic
+ number}\footnote{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]
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.
+sullo stesso \itindex{mount~point} \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}.
+processo o il \itindex{mount~point} \textit{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
errore nel qual caso \var{errno} viene impostata ai valori:
\begin{errlist}
\item[\errcode{EXDEV}] i file \param{oldpath} e \param{newpath} non fanno
- riferimento ad un filesystem montato sullo stesso \textit{mount point}.
+ riferimento ad un filesystem montato sullo stesso \itindex{mount~point}
+ \textit{mount point}.
\item[\errcode{EPERM}] il filesystem che contiene \param{oldpath} e
\param{newpath} non supporta i link diretti o è una directory.
\item[\errcode{EEXIST}] un file (o una directory) di nome \param{newpath}
con il filesystem \acr{vfat} di Windows). In realtà la funzione ha un
ulteriore requisito, e cioè che non solo che i due file siano sullo stesso
filesystem, ma anche che si faccia riferimento ad essi sullo stesso
-\textit{mount point}.\footnote{si tenga presente infatti (vedi
- sez.~\ref{sec:sys_file_config}) che a partire dal kernel 2.4 uno stesso
- filesystem può essere montato più volte su directory diverse.}
+\itindex{mount~point} \textit{mount point}.\footnote{si tenga presente infatti
+ (vedi sez.~\ref{sec:sys_file_config}) che a partire dal kernel 2.4 uno
+ stesso filesystem può essere montato più volte su directory diverse.}
La funzione inoltre opera sia sui file ordinari che sugli altri oggetti del
filesystem, con l'eccezione delle directory. In alcune versioni di Unix solo
non vuota.
\item[\errcode{EBUSY}] o \param{oldpath} o \param{newpath} sono in uso da
parte di qualche processo (come directory di lavoro o come radice) o del
- sistema (come mount point).
+ sistema (come \itindex{mount~point} \textit{mount point}).
\item[\errcode{EINVAL}] \param{newpath} contiene un prefisso di
\param{oldpath} o più in generale si è cercato di creare una directory come
sotto-directory di se stessa.
\textbf{Macro} & \textbf{Tipo del file} \\
\hline
\hline
- \macro{S\_ISREG(m)} & file normale.\\
- \macro{S\_ISDIR(m)} & directory.\\
- \macro{S\_ISCHR(m)} & dispositivo a caratteri.\\
- \macro{S\_ISBLK(m)} & dispositivo a blocchi.\\
- \macro{S\_ISFIFO(m)} & fifo.\\
- \macro{S\_ISLNK(m)} & link simbolico.\\
- \macro{S\_ISSOCK(m)} & socket.\\
+ \macro{S\_ISREG}\texttt{(m)} & file normale.\\
+ \macro{S\_ISDIR}\texttt{(m)} & directory.\\
+ \macro{S\_ISCHR}\texttt{(m)} & dispositivo a caratteri.\\
+ \macro{S\_ISBLK}\texttt{(m)} & dispositivo a blocchi.\\
+ \macro{S\_ISFIFO}\texttt{(m)} & fifo.\\
+ \macro{S\_ISLNK}\texttt{(m)} & link simbolico.\\
+ \macro{S\_ISSOCK}\texttt{(m)} & socket.\\
\hline
\end{tabular}
\caption{Macro per i tipi di file (definite in \texttt{sys/stat.h}).}
Per i kernel fino al 2.6.25, o se non si attiva il supporto per le
\textit{file capabilities}, il \textit{capabilities bounding set} è un
parametro generale di sistema, il cui valore viene riportato nel file
-\procfile{/proc/sys/kernel/cap-bound}. Il suo valore iniziale è definito in
+\sysctlfile{kernel/cap-bound}. Il suo valore iniziale è definito in
sede di compilazione del kernel, e da sempre ha previsto come default la
presenza di tutte le \textit{capabilities} eccetto \const{CAP\_SETPCAP}. In
questa situazione solo il primo processo eseguito nel sistema (quello con
Con il kernel 2.6.25 e le \textit{file capabilities} il \textit{bounding set}
è diventato una proprietà di ciascun processo, che viene propagata invariata
sia attraverso una \func{fork} che una \func{exec}. In questo caso il file
-\procfile{/proc/sys/kernel/cap-bound} non esiste e \texttt{init} non ha nessun
+\sysctlfile{kernel/cap-bound} non esiste e \texttt{init} non ha nessun
ruolo speciale, inoltre in questo caso all'avvio il valore iniziale prevede la
presenza di tutte le capacità (compresa \const{CAP\_SETPCAP}).
\begin{table}[!h!btp]
\centering
\footnotesize
- \begin{tabular}{|l|p{11.9cm}|}
+ \begin{tabular}{|l|p{10.5cm}|}
\hline
\textbf{Capacità}&\textbf{Descrizione}\\
\hline
intercomunicazione fra processi (vedi
sez.~\ref{sec:ipc_sysv}).\\
\const{CAP\_LEASE} & La capacità di creare dei \textit{file lease}
- \index{file!lease} (vedi
+ \itindex{file~lease} (vedi
sez.~\ref{sec:file_asyncronous_lease})
pur non essendo proprietari del file (dal kernel
2.4).\\
(\const{IOPRIO\_CLASS\_RT} e prima del kernel 2.6.25 anche
\const{IOPRIO\_CLASS\_IDLE}) per lo scheduling dell'I/O (vedi
sez.~\ref{sec:io_priority}), superare il limite di sistema sul numero massimo
-di file aperti,\footnote{quello indicato da \procfile{/proc/sys/fs/file-max}.}
+di file aperti,\footnote{quello indicato da \sysctlfile{fs/file-max}.}
effettuare operazioni privilegiate sulle chiavi mantenute dal kernel (vedi
sez.~\ref{sec:keyctl_management}), usare la funzione \func{lookup\_dcookie},
usare \const{CLONE\_NEWNS} con \func{unshare} e \func{clone}, (vedi