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