3 %% Copyright (C) 2000-2004 Simone Piccardi. Permission is granted to
4 %% copy, distribute and/or modify this document under the terms of the GNU Free
5 %% Documentation License, Version 1.1 or any later version published by the
6 %% Free Software Foundation; with the Invariant Sections being "Prefazione",
7 %% with no Front-Cover Texts, and with no Back-Cover Texts. A copy of the
8 %% license is included in the section entitled "GNU Free Documentation
11 \chapter{L'architettura dei file}
12 \label{cha:file_intro}
14 Uno dei concetti fondamentali dell'architettura di un sistema Unix è il
15 cosiddetto \textit{everything is a file}, cioè il fatto che l'accesso ai vari
16 dispositivi di input/output del computer viene effettuato attraverso
17 un'interfaccia astratta che tratta le periferiche allo stesso modo dei normali
20 Questo significa che si può accedere a qualunque periferica del computer,
21 dalla seriale, alla parallela, alla console, e agli stessi dischi attraverso i
22 cosiddetti file di dispositivo\index{file!di~dispositivo} (i \textit{device
23 file}). Questi sono dei file speciali agendo sui quali i programmi possono
24 leggere, scrivere e compiere operazioni direttamente sulle periferiche, usando
25 le stesse funzioni che si usano per i normali file di dati.
27 In questo capitolo forniremo una descrizione dell'architettura dei file in
28 Linux, iniziando da una panoramica sulle caratteristiche principali delle
29 interfacce con cui i processi accedono ai file (che tratteremo in dettaglio
30 nei capitoli seguenti), per poi passare ad una descrizione più dettagliata
31 delle modalità con cui detto accesso viene realizzato dal sistema.
35 \section{L'architettura generale}
36 \label{sec:file_access_arch}
38 Per poter accedere ai file, il kernel deve mettere a disposizione dei
39 programmi le opportune interfacce che consentano di leggerne il contenuto; il
40 sistema cioè deve provvedere ad organizzare e rendere accessibile in maniera
41 opportuna l'informazione tenuta sullo spazio grezzo disponibile sui dischi.
42 Questo viene fatto strutturando l'informazione sul disco attraverso quello che
43 si chiama un \textit{filesystem} (vedi sez.~\ref{sec:file_arch_func}), essa
44 poi viene resa disponibile ai processi attraverso quello che viene chiamato il
45 \textsl{montaggio} del \textit{filesystem}.
46 % (approfondiremo tutto ciò in sez.~\ref{sec:file_arch_func}).
48 In questa sezione faremo una panoramica generica su come il sistema presenta
49 i file ai processi, trattando l'organizzazione di file e directory, i tipi di
50 file ed introducendo le interfacce disponibili e le loro caratteristiche.
53 \subsection{L'organizzazione di file e directory}
54 \label{sec:file_organization}
57 In Unix, a differenza di quanto avviene in altri sistemi operativi, tutti i
58 file vengono tenuti all'interno di un unico albero la cui radice (quella che
59 viene chiamata \textit{root directory}) viene montata all'avvio. Un file
60 viene identificato dall'utente usando quello che viene chiamato
61 \textit{pathname}\footnote{il manuale della \acr{glibc} depreca questa
62 nomenclatura, che genererebbe confusione poiché \textit{path} indica anche
63 un insieme di directory su cui effettuare una ricerca (come quello in cui si
64 cercano i comandi). Al suo posto viene proposto l'uso di \textit{filename} e
65 di componente per il nome del file all'interno della directory. Non
66 seguiremo questa scelta dato che l'uso della parola \textit{pathname} è
67 ormai così comune che mantenerne l'uso è senz'altro più chiaro
68 dell'alternativa proposta.}, cioè il percorso che si deve fare per accedere
69 al file a partire dalla \textit{root directory}, che è composto da una serie
70 di nomi separati da una \file{/}.
72 All'avvio del sistema, completata la fase di inizializzazione, il kernel
73 riceve dal bootloader l'indicazione di quale dispositivo contiene il
74 filesystem da usare come punto di partenza e questo viene montato come radice
75 dell'albero (cioè nella directory \file{/}); tutti gli ulteriori filesystem
76 che possono essere su altri dispositivi dovranno poi essere inseriti
77 nell'albero montandoli su opportune directory del filesystem montato come
80 Alcuni filesystem speciali (come \file{/proc} che contiene un'interfaccia ad
81 alcune strutture interne del kernel) sono generati automaticamente dal kernel
82 stesso, ma anche essi devono essere montati all'interno dell'albero dei file.
84 Una directory, come vedremo in maggior dettaglio in
85 sez.~\ref{sec:file_vfs_work}, è anch'essa un file, solo che è un file
86 particolare che il kernel riconosce come tale. Il suo scopo è quello di
87 contenere una lista di nomi di file e le informazioni che associano ciascun
88 nome al contenuto. Dato che questi nomi possono corrispondere ad un qualunque
89 oggetto del filesystem, compresa un'altra directory, si ottiene naturalmente
90 un'organizzazione ad albero inserendo nomi di directory in altre directory.
92 Un file può essere indicato rispetto alla directory corrente semplicemente
93 specificandone il nome\footnote{Il manuale delle \acr{glibc} chiama i nomi
94 contenuti nelle directory \textsl{componenti} (in inglese \textit{file name
95 components}), noi li chiameremo più semplicemente \textsl{nomi} o
96 \textsl{voci}.} da essa contenuto. All'interno dello stesso albero si
97 potranno poi inserire anche tutti gli altri oggetti visti attraverso
98 l'interfaccia che manipola i file come le fifo, i link, i socket\index{socket}
99 e gli stessi file di dispositivo \index{file!di~dispositivo} (questi ultimi,
100 per convenzione, sono inseriti nella directory \file{/dev}).
102 Il nome completo di un file viene chiamato \textit{pathname} ed il
103 procedimento con cui si individua il file a cui esso fa riferimento è chiamato
104 risoluzione del nome (\textit{filename resolution} o \textit{pathname
105 resolution}). La risoluzione viene fatta esaminando il \textit{pathname} da
106 sinistra a destra e localizzando ogni nome nella directory indicata dal nome
107 precedente usando \texttt{/} come separatore\footnote{nel caso di nome vuoto,
108 il costrutto \file{//} viene considerato equivalente a \file{/}.}: ovviamente,
109 perché il procedimento funzioni, occorre che i nomi indicati come directory
110 esistano e siano effettivamente directory, inoltre i permessi (si veda
111 sez.~\ref{sec:file_access_control}) devono consentire l'accesso all'intero
114 Se il \textit{pathname} comincia per \texttt{/} la ricerca parte dalla
115 directory radice del processo; questa, a meno di un \func{chroot} (su cui
116 torneremo in sez.~\ref{sec:file_chroot}) è la stessa per tutti i processi ed
117 equivale alla directory radice dell'albero dei file: in questo caso si parla
118 di un \textsl{pathname assoluto} \itindsub{pathname}{assoluto}. Altrimenti la
119 ricerca parte dalla directory corrente (su cui torneremo in
120 sez.~\ref{sec:file_work_dir}) ed il pathname è detto \textsl{pathname
121 relativo} \itindsub{pathname}{relativo}.
123 I nomi \file{.} e \file{..} hanno un significato speciale e vengono inseriti
124 in ogni directory: il primo fa riferimento alla directory corrente e il
125 secondo alla directory \textsl{genitrice} (o \textit{parent directory}) cioè
126 la directory che contiene il riferimento alla directory corrente; nel caso la
127 directory corrente coincida con la directory radice, allora il riferimento è a
132 \subsection{I tipi di file}
133 \label{sec:file_file_types}
135 Come detto in precedenza, in Unix esistono vari tipi di file; in Linux questi
136 sono implementati come oggetti del \textit{Virtual File System} (vedi
137 sez.~\ref{sec:file_vfs_work}) e sono presenti in tutti i filesystem unix-like
138 utilizzabili con Linux. L'elenco dei vari tipi di file definiti dal
139 \textit{Virtual File System}\itindex{Virtual~File~System} è riportato in
140 tab.~\ref{tab:file_file_types}.
142 Si tenga ben presente che questa classificazione non ha nulla a che fare con
143 la classificazione dei file (che in questo caso sono sempre file di dati) in
144 base al loro contenuto, o tipo di accesso. Essa riguarda invece il tipo di
145 oggetti; in particolare è da notare la presenza dei cosiddetti file speciali.
146 Alcuni di essi, come le \textit{fifo} (che tratteremo in
147 sez.~\ref{sec:ipc_named_pipe}) ed i \textit{socket}\index{socket} (che
148 tratteremo in cap.~\ref{cha:socket_intro}) non sono altro che dei riferimenti
149 per utilizzare delle funzionalità di comunicazione fornite dal kernel. Gli
150 altri sono i \textsl{file di dispositivo}\index{file!di~dispositivo} (o
151 \textit{device file}) che costituiscono una interfaccia diretta per leggere e
152 scrivere sui dispositivi fisici; essi vengono suddivisi in due grandi
153 categorie, \textsl{a blocchi} e \textsl{a caratteri} a seconda delle modalità
154 in cui il dispositivo sottostante effettua le operazioni di I/O.\footnote{in
155 sostanza i dispositivi a blocchi (ad esempio i dischi) corrispondono a
156 periferiche per le quali è richiesto che l'I/O venga effettuato per blocchi
157 di dati di dimensioni fissate (ad esempio le dimensioni di un settore),
158 mentre nei dispositivi a caratteri l'I/O viene effettuato senza nessuna
159 particolare struttura.}
164 \begin{tabular}[c]{|l|l|p{7cm}|}
166 \multicolumn{2}{|c|}{\textbf{Tipo di file}} & \textbf{Descrizione} \\
169 \textit{regular file} & \textsl{file regolare} &
170 un file che contiene dei dati (l'accezione normale di file) \\
171 \textit{directory} & \textsl{cartella o direttorio} &
172 un file che contiene una lista di nomi associati a degli
173 \textit{inode}\index{inode} (vedi sez.~\ref{sec:file_vfs}). \\
174 \textit{symbolic link} & \textsl{collegamento simbolico} &
175 un file che contiene un riferimento ad un altro file/directory \\
176 \textit{char device} & \textsl{dispositivo a caratteri} &
177 un file che identifica una periferica ad accesso a caratteri \\
178 \textit{block device} & \textsl{dispositivo a blocchi} &
179 un file che identifica una periferica ad accesso a blocchi \\
180 \textit{fifo} & ``\textsl{coda}'' &
181 un file speciale che identifica una linea di comunicazione software
182 unidirezionale (vedi sez.~\ref{sec:ipc_named_pipe}).\\
183 \textit{socket}\index{socket} & ``\textsl{presa}''&
184 un file speciale che identifica una linea di comunicazione software
185 bidirezionale (vedi cap.~\ref{cha:socket_intro}) \\
188 \caption{Tipologia dei file definiti nel VFS}
189 \label{tab:file_file_types}
192 Una delle differenze principali con altri sistemi operativi (come il VMS o
193 Windows) è che per Unix tutti i file di dati sono identici e contengono un
194 flusso continuo di byte. Non esiste cioè differenza per come vengono visti dal
195 sistema file di diverso contenuto o formato (come nel caso di quella fra file
196 di testo e binari che c'è in Windows) né c'è una strutturazione a record per
197 il cosiddetto ``\textsl{accesso diretto}'' come nel caso del
198 VMS.\footnote{questo vale anche per i dispositivi a blocchi: la strutturazione
199 dell'I/O in blocchi di dimensione fissa avviene solo all'interno del kernel,
200 ed è completamente trasparente all'utente. Inoltre talvolta si parla di
201 \textsl{accesso diretto} riferendosi alla capacità, che non ha niente a che
202 fare con tutto ciò, di effettuare, attraverso degli appositi file di
203 dispositivo\index{file!di~dispositivo}, operazioni di I/O direttamente sui
204 dischi senza passare attraverso un filesystem (il cosiddetto \textit{raw
205 access}, introdotto coi kernel della serie 2.4.x).}
207 Una seconda differenza è nel formato dei file ASCII: in Unix la fine riga è
208 codificata in maniera diversa da Windows o Mac, in particolare il fine riga è
209 il carattere \texttt{LF} (o \verb|\n|) al posto del \texttt{CR} (\verb|\r|)
210 del Mac e del \texttt{CR LF} di Windows.\footnote{per questo esistono in Linux
211 dei programmi come \cmd{unix2dos} e \cmd{dos2unix} che effettuano una
212 conversione fra questi due formati di testo.} Questo può causare alcuni
213 problemi qualora nei programmi si facciano assunzioni sul terminatore della
216 Si ricordi infine che un kernel Unix non fornisce nessun supporto per la
217 tipizzazione dei file di dati e che non c'è nessun supporto del sistema per le
218 estensioni come parte del filesystem.\footnote{non è così ad esempio nel
219 filesystem HFS dei Mac, che supporta delle risorse associate ad ogni file,
220 che specificano fra l'altro il contenuto ed il programma da usare per
221 leggerlo. In realtà per alcuni filesystem, come l'XFS della SGI, esiste la
222 possibilità di associare delle risorse ai file, ma è una caratteristica
223 tutt'ora poco utilizzata, dato che non corrisponde al modello classico dei
224 file in un sistema Unix.} Ciò nonostante molti programmi adottano delle
225 convenzioni per i nomi dei file, ad esempio il codice C normalmente si mette
226 in file con l'estensione \file{.c}; un'altra tecnica molto usata è quella di
227 utilizzare i primi 4 byte del file per memorizzare un \textit{magic number}
228 che classifichi il contenuto; entrambe queste tecniche, per quanto usate ed
229 accettate in maniera diffusa, restano solo delle convenzioni il cui rispetto è
230 demandato alle applicazioni stesse.
233 \subsection{Le due interfacce ai file}
234 \label{sec:file_io_api}
236 In Linux le modalità di accesso ai file e le relative interfacce di
237 programmazione sono due, basate su due diversi meccanismi con cui è possibile
238 accedere al loro contenuto.
240 La prima è l'interfaccia standard di Unix, quella che il manuale delle
241 \textsl{glibc} chiama interfaccia dei descrittori di file (o \textit{file
242 descriptor}). È un'interfaccia specifica dei sistemi unix-like e fornisce
243 un accesso non bufferizzato; la tratteremo in dettaglio in
244 cap.~\ref{cha:file_unix_interface}.
246 L'interfaccia è primitiva ed essenziale, l'accesso viene detto non
247 bufferizzato in quanto la lettura e la scrittura vengono eseguite chiamando
248 direttamente le system call del kernel (in realtà il kernel effettua al suo
249 interno alcune bufferizzazioni per aumentare l'efficienza nell'accesso ai
250 dispositivi); i \textit{file descriptor}\index{file!descriptor} sono
251 rappresentati da numeri interi (cioè semplici variabili di tipo \ctyp{int}).
252 L'interfaccia è definita nell'header \file{unistd.h}.
254 La seconda interfaccia è quella che il manuale della \acr{glibc} chiama degli
255 \textit{stream}\index{file!stream}. Essa fornisce funzioni più evolute e un
256 accesso bufferizzato (controllato dalla implementazione fatta dalle
257 \acr{glibc}), la tratteremo in dettaglio nel
258 cap.~\ref{cha:files_std_interface}.
260 Questa è l'interfaccia standard specificata dall'ANSI C e perciò si trova
261 anche su tutti i sistemi non Unix. Gli \textit{stream}\index{file!stream} sono
262 oggetti complessi e sono rappresentati da puntatori ad un opportuna struttura
263 definita dalle librerie del C; si accede ad essi sempre in maniera indiretta
264 utilizzando il tipo \ctyp{FILE *}. L'interfaccia è definita nell'header
267 Entrambe le interfacce possono essere usate per l'accesso ai file come agli
268 altri oggetti del VFS (fifo, socket\index{socket}, device, sui quali torneremo
269 in dettaglio a tempo opportuno), ma per poter accedere alle operazioni di
270 controllo (descritte in sez.~\ref{sec:file_fcntl} e sez.~\ref{sec:file_ioctl})
271 su un qualunque tipo di oggetto del VFS occorre usare l'interfaccia standard
272 di Unix con i \textit{file descriptor}. Allo stesso modo devono essere usati i
273 \textit{file descriptor}\index{file!descriptor} se si vuole ricorrere a
274 modalità speciali di I/O come il \textit{file locking}\index{file!locking} o
275 l'I/O non-bloccante (vedi cap.~\ref{cha:file_advanced}).
277 Gli \textit{stream} forniscono un'interfaccia di alto livello costruita sopra
278 quella dei \textit{file descriptor}, che permette di poter scegliere tra
279 diversi stili di bufferizzazione. Il maggior vantaggio degli \textit{stream}
280 è che l'interfaccia per le operazioni di input/output è enormemente più ricca
281 di quella dei \textit{file descriptor}, che forniscono solo funzioni
282 elementari per la lettura/scrittura diretta di blocchi di byte. In
283 particolare gli \textit{stream}\index{file!stream} dispongono di tutte le
284 funzioni di formattazione per l'input e l'output adatte per manipolare anche i
285 dati in forma di linee o singoli caratteri.
287 In ogni caso, dato che gli stream sono implementati sopra l'interfaccia
288 standard di Unix, è sempre possibile estrarre il \textit{file descriptor} da
289 uno stream ed eseguirvi operazioni di basso livello, o associare in un secondo
290 tempo uno \textit{stream}\index{file!stream} ad un \textit{file
291 descriptor}\index{file!descriptor}.
293 In generale, se non necessitano specificatamente le funzionalità di basso
294 livello, è opportuno usare sempre gli \textit{stream}\index{file!stream} per
295 la loro maggiore portabilità, essendo questi ultimi definiti nello standard
296 ANSI C; l'interfaccia con i \textit{file descriptor}\index{file!descriptor}
297 infatti segue solo lo standard POSIX.1 dei sistemi Unix, ed è pertanto di
298 portabilità più limitata.
302 \section{L'architettura della gestione dei file}
303 \label{sec:file_arch_func}
305 %% Per capire fino in fondo le proprietà di file e directory in un sistema
306 %% unix-like ed il comportamento delle relative funzioni di manipolazione,
307 %% occorre una breve introduzione al funzionamento della gestione dei file da
308 %% parte del kernel e sugli oggetti su cui è basato un filesystem. In particolare
309 %% occorre tenere presente dov'è che si situa la divisione fondamentale fra
310 %% kernel space e user space che tracciavamo al cap.~\ref{cha:intro_unix}.
312 In questa sezione esamineremo come viene implementato l'accesso ai file in
313 Linux, come il kernel può gestire diversi tipi di filesystem, descrivendo
314 prima le caratteristiche generali di un filesystem di un sistema unix-like,
315 per poi trattare in maniera un po' più dettagliata il filesystem più usato con
318 % in particolare si riprenderà, approfondendolo sul piano dell'uso nelle
319 % funzioni di libreria, il concetto di \textit{inode} di cui abbiamo brevemente
320 % accennato le caratteristiche (dal lato dell'implementazione nel kernel) in
321 % sez.~\ref{sec:file_vfs}.
324 \subsection{Il \textit{Virtual File System} di Linux}
327 % Questa sezione riporta informazioni sui dettagli di come il kernel gestisce i
328 % file. L'argomento è abbastanza ``esoterico'' e questa sezione può essere
329 % saltata ad una prima lettura; è bene però tenere presente che vengono
330 % introdotti qui alcuni termini che potranno comparire in seguito, come
331 % \textit{inode}, \textit{dentry}, \textit{dcache}.
333 \itindbeg{Virtual~File~System}
334 In Linux il concetto di \textit{everything is a file} è stato implementato
335 attraverso il \textit{Virtual File System} (da qui in avanti VFS) che è uno
336 strato intermedio che il kernel usa per accedere ai più svariati filesystem
337 mantenendo la stessa interfaccia per i programmi in user space. Esso fornisce
338 un livello di indirezione che permette di collegare le operazioni di
339 manipolazione sui file alle operazioni di I/O, e gestisce l'organizzazione di
340 queste ultime nei vari modi in cui i diversi filesystem le effettuano,
341 permettendo la coesistenza di filesystem differenti all'interno dello stesso
342 albero delle directory.
344 Quando un processo esegue una system call che opera su un file, il kernel
345 chiama sempre una funzione implementata nel VFS; la funzione eseguirà le
346 manipolazioni sulle strutture generiche e utilizzerà poi la chiamata alle
347 opportune routine del filesystem specifico a cui si fa riferimento. Saranno
348 queste a chiamare le funzioni di più basso livello che eseguono le operazioni
349 di I/O sul dispositivo fisico, secondo lo schema riportato in
350 fig.~\ref{fig:file_VFS_scheme}.
354 \includegraphics[width=7cm]{img/vfs}
355 \caption{Schema delle operazioni del VFS.}
356 \label{fig:file_VFS_scheme}
359 Il VFS definisce un insieme di funzioni che tutti i filesystem devono
360 implementare. L'interfaccia comprende tutte le funzioni che riguardano i file;
361 le operazioni sono suddivise su tre tipi di oggetti: \textit{filesystem},
362 \textit{inode}\index{inode} e \textit{file}, corrispondenti a tre apposite
363 strutture definite nel kernel.
365 Il VFS usa una tabella mantenuta dal kernel che contiene il nome di ciascun
366 filesystem supportato: quando si vuole inserire il supporto di un nuovo
367 filesystem tutto quello che occorre è chiamare la funzione
368 \code{register\_filesystem} passandole un'apposita struttura
369 \code{file\_system\_type} che contiene i dettagli per il riferimento
370 all'implementazione del medesimo, che sarà aggiunta alla citata tabella.
372 In questo modo quando viene effettuata la richiesta di montare un nuovo disco
373 (o qualunque altro \textit{block device} che può contenere un filesystem), il
374 VFS può ricavare dalla citata tabella il puntatore alle funzioni da chiamare
375 nelle operazioni di montaggio. Quest'ultima è responsabile di leggere da disco
376 il superblock (vedi sez.~\ref{sec:file_ext2}), inizializzare tutte le variabili
377 interne e restituire uno speciale descrittore dei filesystem montati al VFS;
378 attraverso quest'ultimo diventa possibile accedere alle routine specifiche per
379 l'uso di quel filesystem.
381 Il primo oggetto usato dal VFS è il descrittore di filesystem, un puntatore ad
382 una apposita struttura che contiene vari dati come le informazioni comuni ad
383 ogni filesystem, i dati privati relativi a quel filesystem specifico, e i
384 puntatori alle funzioni del kernel relative al filesystem. Il VFS può così
385 usare le funzioni contenute nel \textit{filesystem descriptor} per accedere
386 alle routine specifiche di quel filesystem.
388 Gli altri due descrittori usati dal VFS sono relativi agli altri due oggetti
389 su cui è strutturata l'interfaccia. Ciascuno di essi contiene le informazioni
390 relative al file in uso, insieme ai puntatori alle funzioni dello specifico
391 filesystem usate per l'accesso dal VFS; in particolare il descrittore
392 dell'inode\index{inode} contiene i puntatori alle funzioni che possono essere
393 usate su qualunque file (come \func{link}, \func{stat} e \func{open}), mentre
394 il descrittore di file contiene i puntatori alle funzioni che vengono usate
398 \subsection{Il funzionamento del \textit{Virtual File System}}
399 \label{sec:file_vfs_work}
401 La funzione più importante implementata dal VFS è la system call \func{open}
402 che permette di aprire un file. Dato un \itindex{pathname}\textit{pathname}
403 viene eseguita una ricerca dentro la \textit{directory entry cache} (in breve
404 \textit{dcache}), una tabella che contiene tutte le \textit{directory entry}
405 (in breve \textit{dentry}) che permette di associare in maniera rapida ed
406 efficiente il \textit{pathname} a una specifica \textit{dentry}.
408 Una singola \textit{dentry} contiene in genere il puntatore ad un
409 \textit{inode}\index{inode}; quest'ultimo è la struttura base che sta sul
410 disco e che identifica un singolo oggetto del VFS sia esso un file ordinario,
411 una directory, un link simbolico, una FIFO, un file di
412 dispositivo\index{file!di~dispositivo}, o una qualsiasi altra cosa che possa
413 essere rappresentata dal VFS (i tipi di file riportati in
414 tab.~\ref{tab:file_file_types}). A ciascuno di essi è associata pure una
415 struttura che sta in memoria, e che, oltre alle informazioni sullo specifico
416 file, contiene anche il riferimento alle funzioni (i \textsl{metodi} del VFS)
417 da usare per poterlo manipolare.
419 Le \textit{dentry} ``vivono'' in memoria e non vengono mai salvate su disco,
420 vengono usate per motivi di velocità, gli \textit{inode}\index{inode} invece
421 stanno su disco e vengono copiati in memoria quando serve, ed ogni cambiamento
422 viene copiato all'indietro sul disco, gli inode\index{inode} che stanno in
423 memoria sono inode\index{inode} del VFS ed è ad essi che puntano le singole
426 La \textit{dcache} costituisce perciò una sorta di vista completa di tutto
427 l'albero dei file, ovviamente per non riempire tutta la memoria questa vista è
428 parziale (la \textit{dcache} cioè contiene solo le \textit{dentry} per i file
429 per i quali è stato richiesto l'accesso), quando si vuole risolvere un nuovo
430 \itindex{pathname}\textit{pathname} il VFS deve creare una nuova
431 \textit{dentry} e caricare l'inode\index{inode} corrispondente in memoria.
433 Questo procedimento viene eseguito dal metodo \code{lookup()}
434 dell'inode\index{inode} della directory che contiene il file; questo viene
435 installato nelle relative strutture in memoria quando si effettua il montaggio
436 lo specifico filesystem su cui l'inode va a vivere.
438 Una volta che il VFS ha a disposizione la \textit{dentry} (ed il relativo
439 \textit{inode}) diventa possibile accedere alle varie operazioni sul file come
440 la \func{open} per aprire il file o la \func{stat} per leggere i dati
441 dell'inode\index{inode} e passarli in user space.
443 L'apertura di un file richiede comunque un'altra operazione, l'allocazione di
444 una struttura di tipo \struct{file} in cui viene inserito un puntatore alla
445 \textit{dentry} e una struttura \struct{f\_ops} che contiene i puntatori ai
446 metodi che implementano le operazioni disponibili sul file. In questo modo i
447 processi in user space possono accedere alle operazioni attraverso detti
448 metodi, che saranno diversi a seconda del tipo di file (o dispositivo) aperto
449 (su questo torneremo in dettaglio in sez.~\ref{sec:file_fd}). Un elenco delle
450 operazioni previste dal kernel è riportato in
451 tab.~\ref{tab:file_file_operations}.
456 \begin{tabular}[c]{|l|p{8cm}|}
458 \textbf{Funzione} & \textbf{Operazione} \\
461 \textsl{\code{open}} & apre il file (vedi sez.~\ref{sec:file_open}). \\
462 \textsl{\code{read}} & legge dal file (vedi sez.~\ref{sec:file_read}).\\
463 \textsl{\code{write}} & scrive sul file (vedi
464 sez.~\ref{sec:file_write}).\\
465 \textsl{\code{llseek}} & sposta la posizione corrente sul file (vedi
466 sez.~\ref{sec:file_lseek}). \\
467 \textsl{\code{ioctl}} & accede alle operazioni di controllo
468 (vedi sez.~\ref{sec:file_ioctl}).\\
469 \textsl{\code{readdir}}& legge il contenuto di una directory \\
470 \textsl{\code{poll}} & usata nell'I/O multiplexing (vedi
471 sez.~\ref{sec:file_multiplexing}). \\
472 \textsl{\code{mmap}} & mappa il file in memoria (vedi
473 sez.~\ref{sec:file_memory_map}). \\
474 \textsl{\code{release}}& chiamata quando l'ultimo riferimento a un file
476 \textsl{\code{fsync}} & sincronizza il contenuto del file (vedi
477 sez.~\ref{sec:file_sync}). \\
478 \textsl{\code{fasync}} & abilita l'I/O asincrono (vedi
479 sez.~\ref{sec:file_asyncronous_io}) sul file. \\
482 \caption{Operazioni sui file definite nel VFS.}
483 \label{tab:file_file_operations}
486 In questo modo per ciascun file diventano possibili una serie di operazioni
487 (non è detto che tutte siano disponibili), che costituiscono l'interfaccia
488 astratta del VFS. Qualora se ne voglia eseguire una, il kernel andrà ad
489 utilizzare l'opportuna routine dichiarata in \struct{f\_ops} appropriata al
490 tipo di file in questione.
492 Pertanto è possibile scrivere allo stesso modo sulla porta seriale come su un
493 normale file di dati; ovviamente certe operazioni (nel caso della seriale ad
494 esempio la \code{seek}) non saranno disponibili, però con questo sistema
495 l'utilizzo di diversi filesystem (come quelli usati da Windows o MacOs) è
496 immediato e (relativamente) trasparente per l'utente ed il programmatore.
497 \itindend{Virtual~File~System}
500 \subsection{Il funzionamento di un filesystem Unix}
501 \label{sec:file_filesystem}
503 Come già accennato in sez.~\ref{sec:file_organization} Linux (ed ogni sistema
504 unix-like) organizza i dati che tiene su disco attraverso l'uso di un
505 filesystem. Una delle caratteristiche di Linux rispetto agli altri Unix è
506 quella di poter supportare, grazie al VFS, una enorme quantità di filesystem
507 diversi, ognuno dei quali ha una sua particolare struttura e funzionalità
508 proprie. Per questo per il momento non entreremo nei dettagli di un
509 filesystem specifico, ma daremo una descrizione a grandi linee che si adatta
510 alle caratteristiche comuni di qualunque filesystem di sistema unix-like.
512 Lo spazio fisico di un disco viene usualmente diviso in partizioni; ogni
513 partizione può contenere un filesystem. La strutturazione tipica
514 dell'informazione su un disco è riportata in fig.~\ref{fig:file_disk_filesys};
515 in essa si fa riferimento alla struttura del filesystem \acr{ext2}, che
516 prevede una separazione dei dati in \textit{block group} che replicano il
517 superblock (ma sulle caratteristiche di \acr{ext2} torneremo in
518 sez.~\ref{sec:file_ext2}). È comunque caratteristica comune di tutti i
519 filesystem per Unix, indipendentemente da come poi viene strutturata nei
520 dettagli questa informazione, prevedere una divisione fra la lista degli
521 inode\index{inode} e lo spazio a disposizione per i dati e le directory.
525 \includegraphics[width=14cm]{img/disk_struct}
526 \caption{Organizzazione dello spazio su un disco in partizioni e
528 \label{fig:file_disk_filesys}
531 Se si va ad esaminare con maggiore dettaglio la strutturazione
532 dell'informazione all'interno del singolo filesystem (tralasciando i dettagli
533 relativi al funzionamento del filesystem stesso come la strutturazione in
534 gruppi dei blocchi, il superblock e tutti i dati di gestione) possiamo
535 esemplificare la situazione con uno schema come quello esposto in
536 fig.~\ref{fig:file_filesys_detail}.
540 \includegraphics[width=14cm]{img/filesys_struct}
541 \caption{Strutturazione dei dati all'interno di un filesystem.}
542 \label{fig:file_filesys_detail}
545 Da fig.~\ref{fig:file_filesys_detail} si evidenziano alcune delle
546 caratteristiche di base di un filesystem, sulle quali è bene porre attenzione
547 visto che sono fondamentali per capire il funzionamento delle funzioni che
548 manipolano i file e le directory che tratteremo nel prossimo capitolo; in
549 particolare è opportuno ricordare sempre che:
553 \item L'\textit{inode}\index{inode} contiene tutte le informazioni riguardanti
554 il file: il tipo di file, i permessi di accesso, le dimensioni, i puntatori
555 ai blocchi fisici che contengono i dati e così via; le informazioni che la
556 funzione \func{stat} fornisce provengono dall'\textit{inode}; dentro una
557 directory si troverà solo il nome del file e il numero
558 dell'\textit{inode}\index{inode} ad esso associato, cioè quella che da qui
559 in poi chiameremo una \textsl{voce} (come traduzione dell'inglese
560 \textit{directory entry}, che non useremo anche per evitare confusione con
561 le \textit{dentry} del kernel di cui si parlava in sez.~\ref{sec:file_vfs}).
563 \item Come mostrato in fig.~\ref{fig:file_filesys_detail} si possono avere più
564 voci che puntano allo stesso \textit{inode}. Ogni \textit{inode} ha un
565 contatore che contiene il numero di riferimenti (\textit{link count}) che
566 sono stati fatti ad esso; solo quando questo contatore si annulla i dati del
567 file vengono effettivamente rimossi dal disco. Per questo la funzione per
568 cancellare un file si chiama \func{unlink}, ed in realtà non cancella
569 affatto i dati del file, ma si limita ad eliminare la relativa voce da una
570 directory e decrementare il numero di riferimenti
571 nell'\textit{inode}\index{inode}.
573 \item Il numero di \textit{inode} nella voce si riferisce ad un \textit{inode}
574 nello stesso filesystem e non ci può essere una directory che contiene
575 riferimenti ad \textit{inode}\index{inode} relativi ad altri filesystem.
576 Questo limita l'uso del comando \cmd{ln} (che crea una nuova voce per un
577 file esistente, con la funzione \func{link}) al filesystem corrente.
579 \item Quando si cambia nome ad un file senza cambiare filesystem, il contenuto
580 del file non viene spostato fisicamente, viene semplicemente creata una
581 nuova voce per l'\textit{inode}\index{inode} in questione e rimossa la
582 vecchia (questa è la modalità in cui opera normalmente il comando \cmd{mv}
583 attraverso la funzione \func{rename}).
587 Infine è bene avere presente che, essendo file pure loro, esiste un numero di
588 riferimenti anche per le directory; per cui, se a partire dalla situazione
589 mostrata in fig.~\ref{fig:file_filesys_detail} creiamo una nuova directory
590 \file{img} nella directory \file{gapil}, avremo una situazione come quella in
591 fig.~\ref{fig:file_dirs_link}, dove per chiarezza abbiamo aggiunto dei numeri
592 di inode\index{inode}.
596 \includegraphics[width=14cm]{img/dir_links}
597 \caption{Organizzazione dei link per le directory.}
598 \label{fig:file_dirs_link}
601 La nuova directory avrà allora un numero di riferimenti pari a due, in quanto
602 è referenziata dalla directory da cui si era partiti (in cui è inserita la
603 nuova voce che fa riferimento a \file{img}) e dalla voce \file{.}
604 che è sempre inserita in ogni directory; questo vale sempre per ogni directory
605 che non contenga a sua volta altre directory. Al contempo, la directory da
606 cui si era partiti avrà un numero di riferimenti di almeno tre, in quanto
607 adesso sarà referenziata anche dalla voce \file{..} di \file{img}.
610 \subsection{Il filesystem \textsl{ext2}}
611 \label{sec:file_ext2}
613 Il filesystem standard usato da Linux è il cosiddetto \textit{second extended
614 filesystem}, identificato dalla sigla \acr{ext2}. Esso supporta tutte le
615 caratteristiche di un filesystem standard Unix, è in grado di gestire nomi di
616 file lunghi (256 caratteri, estensibili a 1012) con una dimensione massima di
619 Oltre alle caratteristiche standard, \acr{ext2} fornisce alcune estensioni che
620 non sono presenti sugli altri filesystem Unix. Le principali sono le seguenti:
622 \item i \textit{file attributes} consentono di modificare il comportamento del
623 kernel quando agisce su gruppi di file. Possono essere impostati su file e
624 directory e in quest'ultimo caso i nuovi file creati nella directory
625 ereditano i suoi attributi.
626 \item sono supportate entrambe le semantiche di BSD e SVr4 come opzioni di
627 montaggio. La semantica BSD comporta che i file in una directory sono creati
628 con lo stesso identificatore di gruppo della directory che li contiene. La
629 semantica SVr4 comporta che i file vengono creati con l'identificatore del
630 gruppo primario del processo, eccetto il caso in cui la directory ha il bit
631 di \acr{sgid} impostato (per una descrizione dettagliata del significato di
632 questi termini si veda sez.~\ref{sec:file_access_control}), nel qual caso
633 file e subdirectory ereditano sia il \acr{gid} che lo \acr{sgid}.
634 \item l'amministratore può scegliere la dimensione dei blocchi del filesystem
635 in fase di creazione, a seconda delle sue esigenze (blocchi più grandi
636 permettono un accesso più veloce, ma sprecano più spazio disco).
637 \item il filesystem implementa link simbolici veloci, in cui il nome del file
638 non è salvato su un blocco, ma tenuto all'interno dell'inode\index{inode}
639 (evitando letture multiple e spreco di spazio), non tutti i nomi però
640 possono essere gestiti così per limiti di spazio (il limite è 60 caratteri).
641 \item vengono supportati i file immutabili (che possono solo essere letti) per
642 la protezione di file di configurazione sensibili, o file
643 \textit{append-only} che possono essere aperti in scrittura solo per
644 aggiungere dati (caratteristica utilizzabile per la protezione dei file di
648 La struttura di \acr{ext2} è stata ispirata a quella del filesystem di BSD: un
649 filesystem è composto da un insieme di blocchi, la struttura generale è quella
650 riportata in fig.~\ref{fig:file_filesys_detail}, in cui la partizione è divisa
651 in gruppi di blocchi.\footnote{non si confonda questa definizione con
652 quella riportata in fig.~\ref{fig:file_dirent_struct}; in quel caso si fa
653 riferimento alla struttura usata in user space per riportare i dati
654 contenuti in una directory generica, questa fa riferimento alla struttura
655 usata dal kernel per un filesystem \acr{ext2}, definita nel file
656 \texttt{ext2\_fs.h} nella directory \texttt{include/linux} dei sorgenti del
659 Ciascun gruppo di blocchi contiene una copia delle informazioni essenziali del
660 filesystem (superblock e descrittore del filesystem sono quindi ridondati) per
661 una maggiore affidabilità e possibilità di recupero in caso di corruzione del
662 superblock principale.
666 \includegraphics[width=9cm]{img/dir_struct}
667 \caption{Struttura delle directory nel \textit{second extented filesystem}.}
668 \label{fig:file_ext2_dirs}
671 L'utilizzo di raggruppamenti di blocchi ha inoltre degli effetti positivi nelle
672 prestazioni dato che viene ridotta la distanza fra i dati e la tabella degli
675 Le directory sono implementate come una \itindex{linked~list}\textit{linked
676 list} con voci di dimensione variabile. Ciascuna voce della lista contiene
677 il numero di inode\index{inode}, la sua lunghezza, il nome del file e la sua
678 lunghezza, secondo lo schema in fig.~\ref{fig:file_ext2_dirs}; in questo modo
679 è possibile implementare nomi per i file anche molto lunghi (fino a 1024
680 caratteri) senza sprecare spazio disco.
687 %%% TeX-master: "gapil"