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