\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 \ref{sec:file_arch_func}), essa poi viene resa
-disponibile ai processi attraverso quello che viene chiamato il
+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 \ref{sec:file_arch_func}), essa poi
+viene resa disponibile ai processi attraverso quello che viene chiamato il
\textsl{montaggio} del \textit{filesystem}.
% (approfondiremo tutto ciò in \secref{sec:file_arch_func}).
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{anche se il manuale della \acr{glibc} depreca
- questa nomenclatura, poiché genererebbe confusione, dato che con
- \textit{path} si indica anche un insieme di directory su cui effettuare una
- ricerca (come quello in cui si cercano i comandi) 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, comletata 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 \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.
+\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 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 \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
\subsection{I tipi di file}
\label{sec:file_file_types}
-Come detto in precedenza in Unix esistono vari tipi di file; in Linux questi
+Come detto in precedenza, in Unix esistono vari tipi di file; in Linux questi
sono implementati come oggetti del \textit{Virtual File System} (vedi
\secref{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
\multicolumn{2}{|c|}{\textbf{Tipo di file}} & \textbf{Descrizione} \\
\hline
\hline
- \textit{regular file} & \textsl{file normale} &
+ \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 \textit{inodes}
\textit{symbolic link} & \textsl{collegamento simbolico} &
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 \\
+ 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) \\
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.\footnote{con i
- kernel della serie 2.4 è disponibile una forma di accesso diretto ai dischi
- (il \textit{raw access}) attraverso dei device file appositi, che però non
- ha nulla a che fare con questo.}
+ kernel della serie 2.4 è disponibile, attraverso dei device file appositi,
+ una forma di accesso diretto ai dischi (il \textit{raw access}) che però non
+ ha nulla a che fare con questo, trattandosi solo di operazioni fatte senza
+ passare attraverso un filesystem.}
-Una seconda differenza è nel formato dei file ASCII; in Unix la fine riga è
+Una seconda differenza è nel formato dei file ASCII: in Unix la fine riga è
codificata in maniera diversa da Windows o Mac, 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.\footnote{per questo esistono in Linux
La prima è l'interfaccia standard di Unix, quella che il manuale delle
\acr{glibc} chiama interfaccia dei descrittori di file (o \textit{file
- descriptor}). È un'interfaccia specifica dei sistemi unix-like e provvede
+ descriptor}). È un'interfaccia specifica dei sistemi unix-like e fornisce
un accesso non bufferizzato; la tratteremo in dettaglio in
\capref{cha:file_unix_interface}.
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 \textit{file descriptor}\index{file descriptor} sono
-rappresentati da numeri interi (cioè semplici variabili di tipo \type{int}).
+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
-\textit{stream}\index{stream}. Essa provvede funzioni più evolute e un accesso
+\textit{stream}\index{stream}. Essa fornisce funzioni più evolute e un accesso
bufferizzato (controllato dalla implementazione fatta dalle \acr{glibc}), la
tratteremo in dettaglio nel \capref{cha:files_std_interface}.
anche su tutti i sistemi non Unix. Gli \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 \type{FILE *}. L'interfaccia è definita nell'header \type{stdio.h}.
+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 (pipe, socket, device, sui quali torneremo in dettaglio
-a tempo opportuno), ma per poter accedere alle operazioni di controllo 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
-\textit{file descriptor} se si vuole ricorrere a modalità speciali di I/O come
-il polling o il non-bloccante (vedi \capref{cha:file_advanced}).
+altri oggetti del VFS (fifo, socket, device, sui quali torneremo in dettaglio
+a tempo opportuno), ma per poter accedere alle operazioni di controllo
+(descritte in \ref{sec:file_fcntl} e \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 \textit{file
+ descriptor} se si vuole ricorrere a modalità speciali di I/O come il polling
+o il non-bloccante (vedi \capref{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 provvedono solo funzioni
+di quella dei \textit{file descriptor}, che forniscono solo funzioni
elementari per la lettura/scrittura diretta di blocchi di byte. In
particolare gli \textit{stream} dispongono di tutte le funzioni di
formattazione per l'input e l'output adatte per manipolare anche i dati in
In Linux il concetto di \textit{everything is a file} è stato implementato
attraverso il \textit{Virtual Filesystem} (da qui in avanti VFS) che è uno
strato intermedio che il kernel usa per accedere ai più svariati filesystem
-mantenendo la stessa interfaccia per i programmi in user space. Esso provvede
+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 diversi filesystem le effettuano,
+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
+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 alla
+manipolazioni sulle strutture generiche e utilizzerà poi la chiamata alle
opportune routine del filesystem specifico a cui si fa riferimento. Saranno
queste a chiamare le funzioni di più basso livello che eseguono le operazioni
-di I/O sul dispositivo fisico, secondo lo schema riportato in \nfig.
+di I/O sul dispositivo fisico, secondo lo schema riportato in
+\figref{fig:file_VFS_scheme}.
\begin{figure}[htb]
\centering
\includegraphics[width=7cm]{img/vfs}
- \caption{Schema delle operazioni del VFS}
+ \caption{Schema delle operazioni del VFS.}
\label{fig:file_VFS_scheme}
\end{figure}
\begin{table}[htb]
\centering
\footnotesize
- \begin{tabular}[c]{|l|p{7cm}|}
+ \begin{tabular}[c]{|l|p{8cm}|}
\hline
\textbf{Funzione} & \textbf{Operazione} \\
\hline
\hline
- \textsl{\code{open}} & apre il file \\
- \textsl{\code{read}} & legge dal file \\
- \textsl{\code{write}} & scrive sul file \\
- \textsl{\code{llseek}} & sposta la posizione corrente sul file \\
+ \textsl{\code{open}} & apre il file (vedi \secref{sec:file_open}). \\
+ \textsl{\code{read}} & legge dal file (vedi \secref{sec:file_read}).\\
+ \textsl{\code{write}} & scrive sul file (vedi \secref{sec:file_write}).\\
+ \textsl{\code{llseek}} & sposta la posizione corrente sul file (vedi
+ \secref{sec:file_lseek}). \\
\textsl{\code{ioctl}} & accede alle operazioni di controllo
- (tramite la \func{ioctl})\\
- \textsl{\code{readdir}}& per leggere il contenuto di una directory \\
- \textsl{\code{poll}} & \\
- \textsl{\code{mmap}} & chiamata dalla system call \func{mmap}.
- mappa il file in memoria\\
+ (vedi \secref{sec:file_ioctl}).\\
+ \textsl{\code{readdir}}& legge il contenuto di una directory \\
+ \textsl{\code{poll}} & usata nell'I/O multiplexing (vedi
+ \secref{sec:file_multiplexing}). \\
+ \textsl{\code{mmap}} & mappa il file in memoria (vedi
+ \secref{sec:file_memory_map}). \\
\textsl{\code{release}}& chiamata quando l'ultima referenza a un file
- aperto è chiusa\\
- \textsl{\code{fsync}} & chiamata dalla system call \func{fsync} \\
- \textsl{\code{fasync}} & chiamate da \func{fcntl} quando è abilitato
- il modo asincrono per l'I/O su file. \\
+ aperto è chiusa. \\
+ \textsl{\code{fsync}} & sincronizza il contenuto del file (vedi
+ \secref{sec:file_sync}). \\
+ \textsl{\code{fasync}} & abilita l'I/O asincrono (vedi
+ \secref{sec:file_asyncronous_io}) sul file. \\
\hline
\end{tabular}
\caption{Operazioni sui file definite nel VFS.}
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 la opportuna routine dichiarata in \var{f\_ops} appropriata al tipo
+astratta del VFS. Qualora se ne voglia eseguire una, il kernel andrà ad
+utilizzare l'opportuna routine dichiarata in \var{f\_ops} appropriata al tipo
di file in questione.
In questo modo è possibile scrivere allo stesso modo sulla porta seriale come
-su un file di dati normale; ovviamente certe operazioni (nel caso della
+su normale un file di dati; ovviamente certe operazioni (nel caso della
seriale ad esempio la \code{seek}) non saranno disponibili, però con questo
sistema l'utilizzo di diversi filesystem (come quelli usati da Windows o
MacOs) è immediato e (relativamente) trasparente per l'utente ed il
Come già accennato in \secref{sec:file_organization} Linux (ed ogni sistema
unix-like) organizza i dati che tiene su disco attraverso l'uso di un
filesystem. Una delle caratteristiche di Linux rispetto agli altri Unix è
-quella di poter supportare grazie al VFS una enorme quantità di filesystem
+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
+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.
\begin{figure}[htb]
\centering
\includegraphics[width=12cm]{img/disk_struct}
- \caption{Organizzazione dello spazio su un disco in partizioni e filesystem}
+ \caption{Organizzazione dello spazio su un disco in partizioni e
+ filesystem.}
\label{fig:file_disk_filesys}
\end{figure}
\begin{figure}[htb]
\centering
\includegraphics[width=12cm]{img/filesys_struct}
- \caption{Strutturazione dei dati all'interno di un filesystem}
+ \caption{Strutturazione dei dati all'interno di un filesystem.}
\label{fig:file_filesys_detail}
\end{figure}
fisici che contengono i dati e così via; le informazioni che la funzione
\func{stat} fornisce provengono dall'\textit{inode}; dentro una directory si
troverà solo il nome del file e il numero dell'\textit{inode} ad esso
- associato, cioè quella che da qui in poi chiameremo una \textsl{voce}
- (traduzione approssimata dell'inglese \textit{directory entry}, che non
- useremo anche per evitare confusione con le \textit{dentry} del kernel di
- cui si parlava in \secref{sec:file_vfs}).
+ 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
+ \secref{sec:file_vfs}).
\item Come mostrato in \curfig\ si possono avere più voci che puntano allo
stesso \textit{inode}. Ogni \textit{inode} ha un contatore che contiene il
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 a eliminare la relativa voce da una directory e
+ file, ma si limita ad eliminare la relativa voce da una directory e
decrementare il numero di riferimenti nell'\textit{inode}.
\item Il numero di \textit{inode} nella voce si riferisce ad un \textit{inode}
riferimenti ad \textit{inodes} relativi ad altri filesystem. Questo limita
l'uso del comando \cmd{ln} (che crea una nuova voce per un file
esistente, con la funzione \func{link}) al filesystem corrente.
-
-\item Quando si cambia nome ad un file senza cambiare filesystem il contenuto
- del file non deve essere spostato, viene semplicemente creata una nuova voce
- per l'\textit{inode} in questione e rimossa la vecchia (questa è la modalità
- in cui opera normalmente il comando \cmd{mv} attraverso la funzione
- \func{rename}).
+
+\item Quando si cambia nome ad un file senza cambiare filesystem, il contenuto
+ del file non viene spostato fisicamente, viene semplicemente creata una
+ nuova voce per l'\textit{inode} in questione e rimossa la vecchia (questa è
+ la modalità in cui opera normalmente il comando \cmd{mv} attraverso la
+ funzione \func{rename}).
\end{enumerate}
Infine è bene avere presente che, essendo file pure loro, esiste un numero di
-riferimenti anche per le directory; per cui se a partire dalla situazione
+riferimenti anche per le directory; per cui, se a partire dalla situazione
mostrata in \curfig\ creiamo una nuova directory \file{img} nella directory
-\file{gapil}: avremo una situazione come quella in \nfig, dove per chiarezza
+\file{gapil}, avremo una situazione come quella in \nfig, dove per chiarezza
abbiamo aggiunto dei numeri di inode.
\begin{figure}[htb]
\centering
\includegraphics[width=12cm]{img/dir_links}
- \caption{Organizzazione dei link per le directory}
+ \caption{Organizzazione dei link per le directory.}
\label{fig:file_dirs_link}
\end{figure}
è referenziata dalla directory da cui si era partiti (in cui è inserita la
nuova voce che fa riferimento a \file{img}) e dalla voce \file{.}
che è sempre inserita in ogni directory; questo vale sempre per ogni directory
-che non contenga a sua volta altre directory. Al contempo la directory da
-cui si era partiti avrà un numero di riferiementi di almeno tre, in quanto
+che non contenga a sua volta altre directory. Al contempo, la directory da
+cui si era partiti avrà un numero di riferimenti di almeno tre, in quanto
adesso sarà referenziata anche dalla voce \file{..} di \file{img}.
Il filesystem standard usato da Linux è il cosiddetto \textit{second extended
filesystem}, identificato dalla sigla \acr{ext2}. Esso supporta tutte le
caratteristiche di un filesystem standard Unix, è in grado di gestire nomi di
-file lunghi (256 caratteri, estendibili a 1012), una dimensione fino a 4~Tb.
+file lunghi (256 caratteri, estendibili a 1012) con una dimensione massima di
+4~Tb.
-Oltre alle caratteristiche standard \acr{ext2} fornisce alcune estensioni che
-non sono presenti sugli altri filesystem Unix, le cui principali sono le
-seguenti:
+Oltre alle caratteristiche standard, \acr{ext2} fornisce alcune estensioni che
+non sono presenti sugli altri filesystem Unix. Le principali sono le seguenti:
\begin{itemize}
\item i \textit{file attributes} consentono di modificare il comportamento del
- kernel quando agisce su gruppi di file. Possono essere settati su file e
+ 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
con lo stesso identificatore di gruppo della directory che li contiene. La
semantica SVr4 comporta che i file vengono creati con l'identificatore del
gruppo primario del processo, eccetto il caso in cui la directory ha il bit
- di \acr{sgid} settato (per una descrizione dettagliata del significato di
+ di \acr{sgid} impostato (per una descrizione dettagliata del significato di
questi termini si veda \secref{sec:file_access_control}), nel qual caso file
e subdirectory ereditano sia il \acr{gid} che lo \acr{sgid}.
\item l'amministratore può scegliere la dimensione dei blocchi del filesystem