X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=blobdiff_plain;f=filedir.tex;h=514705b61e32b47f3b97ad09cbdb42b964d65c2e;hp=281f8180be103417987806f1fac5a754aed3aeae;hb=94b4d603807121b40eef06d22d2b6cd6e06ec7fd;hpb=2414addb7861eb72315a3de58b6f2cb5c83ab6ed diff --git a/filedir.tex b/filedir.tex index 281f818..514705b 100644 --- a/filedir.tex +++ b/filedir.tex @@ -19,12 +19,12 @@ illustrando le principali caratteristiche di un filesystem e le interfacce che consentono di controllarne il montaggio e lo smontaggio. Esamineremo poi le funzioni di libreria che si usano per copiare, spostare e -cambiare i nomi di file e directory ed esamineremo l'interfaccia che permette -la manipolazione dei loro attributi. Tratteremo inoltre la struttura di base -del sistema delle protezioni e del controllo dell'accesso ai file e le -successive estensioni (\textit{Extended Attributes}, ACL, quote disco, -\textit{capabilities}). Tutto quello che riguarda invece la manipolazione del -contenuto dei file è lasciato ai capitoli successivi. +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. @@ -35,8 +35,8 @@ In questa sezione tratteremo con maggiori dettagli rispetto a quanto visto in sez.~\ref{sec:file_arch_overview} il \textit{Virtual File System} di Linux e come il kernel può gestire diversi tipi di filesystem, descrivendo prima le caratteristiche generali di un filesystem di un sistema unix-like, per poi -trattare in maniera un po' più dettagliata il filesystem più usato con Linux, -l'\acr{ext2} (e derivati). +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} @@ -51,96 +51,237 @@ Come illustrato brevemente in sez.~\ref{sec:file_arch_overview} in Linux il concetto di \textit{everything is a file} è stato implementato attraverso il \textit{Virtual File System}, la cui struttura generale è illustrata in fig.~\ref{fig:file_VFS_scheme}. Il VFS definisce un insieme di funzioni che -tutti i filesystem devono implementare. L'interfaccia comprende tutte le -funzioni che riguardano i file e le operazioni sono suddivise su tre tipi di -oggetti: \textit{filesystem}, \itindex{inode} \textit{inode} e \textit{file}, -corrispondenti a tre apposite strutture definite nel kernel. +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 @@ -172,21 +313,30 @@ tab.~\ref{tab:file_file_operations}. 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} @@ -197,22 +347,24 @@ Come già accennato in sez.~\ref{sec:file_arch_overview} Linux (ed ogni sistema unix-like) organizza i dati che tiene su disco attraverso l'uso di un filesystem. Una delle caratteristiche di Linux rispetto agli altri Unix è quella di poter supportare, grazie al VFS, una enorme quantità di filesystem -diversi, ognuno dei quali ha una sua particolare struttura e funzionalità -proprie. Per questo per il momento non entreremo nei dettagli di un -filesystem specifico, ma daremo una descrizione a grandi linee che si adatta -alle caratteristiche comuni di qualunque filesystem di un sistema unix-like. +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 @@ -223,9 +375,9 @@ directory. \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}. @@ -248,11 +400,12 @@ particolare è opportuno ricordare sempre che: 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ù @@ -260,10 +413,10 @@ particolare è opportuno ricordare sempre che: 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 @@ -275,9 +428,10 @@ particolare è opportuno ricordare sempre che: 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 @@ -452,8 +606,9 @@ sulla directory \param{target}. \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 @@ -467,11 +622,11 @@ sulla directory \param{target}. \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 @@ -488,14 +643,15 @@ indicato uno dei filesystem virtuali, il contenuto di \param{source} viene ignorato. Dopo l'esecuzione della funzione il contenuto del filesystem viene resto -disponibile nella directory specificata come \textit{mount point}, il -precedente contenuto di detta directory viene mascherato dal contenuto della -directory radice del filesystem montato. +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 @@ -504,12 +660,12 @@ disponibili in ogni filesystem), e vengono specificate come opzioni di montaggio con l'argomento \param{mountflags}. In Linux \param{mountflags} deve essere un intero a 32 bit i cui 16 più -significativi sono un \textit{magic number}\footnote{cioè un numero speciale - usato come identificativo, che nel caso è \code{0xC0ED}; si può usare la - costante \const{MS\_MGC\_MSK} per ottenere la parte di \param{mountflags} - riservata al \textit{magic number}.} mentre i 16 meno significativi sono -usati per specificare le opzioni; essi sono usati come maschera binaria e -vanno impostati con un OR aritmetico della costante \const{MS\_MGC\_VAL} con i +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] @@ -586,14 +742,14 @@ montato e non il file o il dispositivo che è stato montato,\footnote{questo è 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 @@ -735,7 +891,8 @@ diretto, o \textit{hard link}. Il prototipo della funzione è il seguente: 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} @@ -765,9 +922,9 @@ supportare i collegamenti diretti (il meccanismo non è disponibile ad esempio 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 @@ -944,7 +1101,7 @@ nello stesso filesystem) si usa invece la funzione \funcd{rename},\footnote{la 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. @@ -2307,13 +2464,13 @@ riportato in tab.~\ref{tab:file_type_macro}. \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}).} @@ -5366,7 +5523,7 @@ casistica assai complessa. 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 @@ -5391,7 +5548,7 @@ tutti, compreso l'amministratore.\footnote{la qual cosa, visto il default 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}). @@ -5627,7 +5784,7 @@ che è opportuno dettagliare maggiormente. \begin{table}[!h!btp] \centering \footnotesize - \begin{tabular}{|l|p{11.9cm}|} + \begin{tabular}{|l|p{10.5cm}|} \hline \textbf{Capacità}&\textbf{Descrizione}\\ \hline @@ -5695,7 +5852,7 @@ che è opportuno dettagliare maggiormente. 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).\\ @@ -5827,7 +5984,7 @@ sez.~\ref{sec:socket_credential_xxx}), assegnare classi privilegiate (\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