Altre indicizzazioni e recupero dei pezzi tagliati per sbaglio
[gapil.git] / fileio.tex
index c5f805e9da412961fcf45878acc9347cd0cfd8b5..9e7e960569f0ebc65beb52717d5c8601a10daade 100644 (file)
@@ -64,32 +64,34 @@ file viene aperto la funzione \func{open} restituisce questo numero, tutte le
 ulteriori operazioni dovranno essere compiute specificando questo stesso
 numero come argomento alle varie funzioni dell'interfaccia.
 
+\itindbeg{process~table}
+\itindbeg{file~table}
+
 Per capire come funziona il meccanismo occorre spiegare a grandi linee come il
 kernel gestisce l'interazione fra processi e file.  Abbiamo già accennato in
 sez.~\ref{sec:proc_hierarchy} come il kernel mantenga un elenco di tutti
-processi nella cosiddetta \itindex{process~table} \textit{process table}. Lo
-stesso, come accennato in sez.~\ref{sec:file_vfs_work}, vale anche per tutti i
-file aperti, il cui elenco viene mantenuto nella cosiddetta
-\itindex{file~table} \textit{file table}.
-
-La \itindex{process~table} \textit{process table} è una tabella che contiene
-una voce per ciascun processo attivo nel sistema. Ciascuna voce è costituita
-dal puntatore a una struttura di tipo \kstruct{task\_struct} nella quale sono
-raccolte tutte le informazioni relative al processo, fra queste informazioni
-c'è anche il puntatore ad una ulteriore struttura di tipo
+processi nella cosiddetta \textit{process table}. Lo stesso, come accennato in
+sez.~\ref{sec:file_vfs_work}, vale anche per tutti i file aperti, il cui
+elenco viene mantenuto nella cosiddetta \textit{file table}.
+
+La \textit{process table} è una tabella che contiene una voce per ciascun
+processo attivo nel sistema. Ciascuna voce è costituita dal puntatore a una
+struttura di tipo \kstruct{task\_struct} nella quale sono raccolte tutte le
+informazioni relative al processo, fra queste informazioni c'è anche il
+puntatore ad una ulteriore struttura di tipo
 \kstruct{files\_struct},\footnote{la definizione corrente di questa struttura
   si trova nel file \texttt{include/linux/fdtable.h} dei sorgenti del kernel,
   quella mostrata in fig.~\ref{fig:file_proc_file} è una versione pesantemente
   semplificata.} che contiene le informazioni relative ai file che il processo
 ha aperto.
 
-La \itindex{file~table} \textit{file table} è una tabella che contiene una
-voce per ciascun file che è stato aperto nel sistema. Come accennato in
-sez.~\ref{sec:file_vfs_work} per ogni file aperto viene allocata una struttura
-\kstruct{file} e la \textit{file table} è costituita da un elenco di puntatori
-a ciascuna di queste strutture, che, come illustrato in
-fig.~\ref{fig:kstruct_file}, contengono le informazioni necessarie per la
-gestione dei file, ed in particolare:
+La \textit{file table} è una tabella che contiene una voce per ciascun file
+che è stato aperto nel sistema. Come accennato in sez.~\ref{sec:file_vfs_work}
+per ogni file aperto viene allocata una struttura \kstruct{file} e la
+\textit{file table} è costituita da un elenco di puntatori a ciascuna di
+queste strutture, che, come illustrato in fig.~\ref{fig:kstruct_file},
+contengono le informazioni necessarie per la gestione dei file, ed in
+particolare:
 \begin{itemize*}
 \item i flag di stato \itindex{file~status~flag} del file nel campo
   \var{f\_flags}.
@@ -115,9 +117,9 @@ gestione dei file, ed in particolare:
 
 In fig.~\ref{fig:file_proc_file} si è riportato uno schema semplificato in cui
 è illustrata questa architettura, ed in cui si sono evidenziate le
-interrelazioni fra la \itindex{file~table} \textit{file table}, la
-\itindex{process~table} \textit{process table} e le varie strutture di dati
-che il kernel mantiene per ciascun file e ciascun processo.
+interrelazioni fra la \textit{file table}, la \textit{process table} e le
+varie strutture di dati che il kernel mantiene per ciascun file e ciascun
+processo.
 
 Come si può notare alla fine il collegamento che consente di porre in
 relazione i file ed i processi è effettuato attraverso i dati mantenuti nella
@@ -134,11 +136,14 @@ essenziali come:
 In questa infrastruttura un \textit{file descriptor} non è altro che l'intero
 positivo che indicizza quest'ultima tabella, e che consente di recuperare il
 puntatore alla struttura \kstruct{file} corrispondente al file aperto dal
-processo a cui era stato assegnato questo indice. Una volta ottenuta grazie
-al \textit{file descriptor} la struttura \kstruct{file} corrispondente al file
-voluto nella \itindex{file~table} \textit{file table}, il kernel potrà usare
-le funzioni messe disposizione dal VFS per eseguire sul file tutte le
-operazioni necessarie.
+processo a cui era stato assegnato questo indice. Una volta ottenuta grazie al
+\textit{file descriptor} la struttura \kstruct{file} corrispondente al file
+voluto nella \textit{file table}, il kernel potrà usare le funzioni messe
+disposizione dal VFS per eseguire sul file tutte le operazioni necessarie.
+
+\itindend{process~table}
+\itindend{file~table}
+
 
 Il meccanismo dell'apertura dei file prevede che venga sempre fornito il primo
 \textit{file descriptor} libero nella tabella, e per questo motivo essi
@@ -467,11 +472,11 @@ sez.~\ref{sec:ipc_file_lock}). Si tenga presente che questa opzione è
 supportata su NFS solo a partire da NFSv3 e con il kernel 2.6, nelle versioni
 precedenti la funzionalità viene emulata controllando prima l'esistenza del
 file per cui usarla per creare \index{file!di lock} un file di lock potrebbe
-dar luogo a una \itindex{race~condition} \textit{race condition}.\footnote{un
-  file potrebbe venir creato fra il controllo la successiva apertura con
-  \const{O\_CREAT}, la cosa si può risolvere comunque creando un file con un
-  nome univoco ed usando la funzione \func{link} per creare il \index{file!di
-    lock} file di lock, (vedi sez.~\ref{sec:ipc_file_lock}).}
+dar luogo a una \textit{race condition}.\footnote{un file potrebbe venir
+  creato fra il controllo la successiva apertura con \const{O\_CREAT}, la cosa
+  si può risolvere comunque creando un file con un nome univoco ed usando la
+  funzione \func{link} per creare il \index{file!di lock} file di lock, (vedi
+  sez.~\ref{sec:ipc_file_lock}).}
 
 Se si usa \const{O\_EXCL} senza \const{O\_CREAT} il comportamento è
 indefinito.  Nella creazione di un file con \const{O\_CREAT} occorre sempre
@@ -500,9 +505,9 @@ si tronca il file con \const{O\_TRUNC} verranno impostati soltanto il
                            viene sempre aggiunto al contenuto precedente. Con
                            NFS questa funzionalità non è supportata 
                            e viene emulata, per questo possono verificarsi
-                           \itindex{race~condition} \textit{race 
-                             condition} con una sovrapposizione dei dati se
-                           più di un processo scrive allo stesso tempo.\\
+                           \textit{race condition} con una sovrapposizione dei
+                           dati se più di un processo scrive allo stesso
+                           tempo.\\ 
       \const{O\_ASYNC}   & Apre il file per l'I/O in modalità asincrona (vedi
                            sez.~\ref{sec:signal_driven_io}). Quando è
                            impostato viene generato il segnale \signal{SIGIO}
@@ -518,11 +523,11 @@ si tronca il file con \const{O\_TRUNC} verranno impostati soltanto il
                            sez.~\ref{sec:proc_exec}) sul file. Il flag è 
                            previsto dallo standard POSIX.1-2008, ed è stato
                            introdotto con il kernel 2.6.23 per evitare una
-                           \itindex{race~condition} \textit{race condition}
-                           che si potrebbe verificare con i \textit{thread}
-                           fra l'apertura del file e l'impostazione della
-                           suddetta modalità con \func{fcntl} (vedi
-                           sez.~\ref{sec:file_fcntl_ioctl}).\\
+                           \textit{race condition} che si potrebbe verificare
+                           con i \textit{thread} fra l'apertura del file e
+                           l'impostazione della suddetta modalità con
+                           \func{fcntl} (vedi
+                           sez.~\ref{sec:file_fcntl_ioctl}).\\ 
       \const{O\_DIRECT}  & Esegue l'I/O direttamente dalla memoria in
                            \textit{user space} in maniera sincrona, in modo da
                            scavalcare i meccanismi di bufferizzazione del
@@ -1236,13 +1241,12 @@ meccanismi di sincronizzazione espliciti come il \itindex{file~locking}
 Un caso tipico di necessità di accesso condiviso in scrittura è quello in cui
 vari processi devono scrivere alla fine di un file (ad esempio un file di
 log). Come accennato in sez.~\ref{sec:file_lseek} impostare la posizione alla
-fine del file e poi scrivere può condurre ad una \itindex{race~condition}
-\textit{race condition}l infatti può succedere che un secondo processo scriva
-alla fine del file fra la \func{lseek} e la \func{write}. In questo caso, come
-abbiamo appena visto, il file sarà esteso, ma il primo processo, che avrà la
-posizione corrente che aveva impostato con la \func{lseek} che non corrisponde
-più alla fine del file, e la sua successiva \func{write} sovrascriverà i dati
-del secondo processo.
+fine del file e poi scrivere può condurre ad una \textit{race condition};
+infatti può succedere che un secondo processo scriva alla fine del file fra la
+\func{lseek} e la \func{write}. In questo caso, come abbiamo appena visto, il
+file sarà esteso, ma il primo processo, avrà una posizione corrente che aveva
+impostato con la \func{lseek} che non corrisponde più alla fine del file, e la
+sua successiva \func{write} sovrascriverà i dati del secondo processo.
 
 Il problema deriva dal fatto che usare due \textit{system call} in successione
 non è mai un'operazione atomica dato che il kernel può interrompere
@@ -1350,8 +1354,8 @@ file descriptor che si vuole ottenere come duplicato; il suo prototipo è:
   \begin{errlist}
   \item[\errcode{EBADF}] \param{oldfd} non è un file aperto o \param{newfd} ha
     un valore fuori dall'intervallo consentito per i file descriptor.
-  \item[\errcode{EBUSY}] si è rilevata la possibilità di una
-    \itindex{race~condition} \textit{race condition}.
+  \item[\errcode{EBUSY}] si è rilevata la possibilità di una \textit{race
+      condition}.
   \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
   \item[\errcode{EMFILE}] si è raggiunto il numero massimo consentito di file
     descriptor aperti.
@@ -1369,24 +1373,23 @@ e si limita a restituire \param{newfd}.
 L'uso di \func{dup2} ha vari vantaggi rispetto alla combinazione di
 \func{close} e \func{dup}; anzitutto se \param{oldfd} è uguale \param{newfd}
 questo verrebbe chiuso e \func{dup} fallirebbe, ma soprattutto l'operazione è
-atomica e consente di evitare una \itindex{race~condition} \textit{race
-  condition} in cui dopo la chiusura del file si potrebbe avere la ricezione
-di un segnale il cui gestore (vedi sez.~\ref{sec:sig_signal_handler}) potrebbe
-a sua volta aprire un file, per cui alla fine \func{dup} restituirebbe un file
-descriptor diverso da quello voluto.
+atomica e consente di evitare una \textit{race condition} in cui dopo la
+chiusura del file si potrebbe avere la ricezione di un segnale il cui gestore
+(vedi sez.~\ref{sec:sig_signal_handler}) potrebbe a sua volta aprire un file,
+per cui alla fine \func{dup} restituirebbe un file descriptor diverso da
+quello voluto.
 
 Con Linux inoltre la funzione prevede la possibilità di restituire l'errore
 \errcode{EBUSY}, che non è previsto dallo standard, quando viene rilevata la
-possibilità di una \itindex{race~condition} \textit{race condition} interna in
-cui si cerca di duplicare un file descriptor che è stato allocato ma per il
-quale non sono state completate le operazioni di apertura.\footnote{la
-  condizione è abbastanza peculiare e non attinente al tipo di utilizzo
-  indicato, quanto piuttosto ad un eventuale tentativo di duplicare file
-  descriptor non ancora aperti, la condizione di errore non è prevista dallo
-  standard, ma in condizioni simili FreeBSD risponde con un errore di
-  \errval{EBADF}, mentre OpenBSD elimina la possibilità di una \textit{race
-    condition} al costo di una perdita di prestazioni.} In tal caso occorre
-ritentare l'operazione.
+possibilità di una \textit{race condition} interna in cui si cerca di
+duplicare un file descriptor che è stato allocato ma per il quale non sono
+state completate le operazioni di apertura.\footnote{la condizione è
+  abbastanza peculiare e non attinente al tipo di utilizzo indicato, quanto
+  piuttosto ad un eventuale tentativo di duplicare file descriptor non ancora
+  aperti, la condizione di errore non è prevista dallo standard, ma in
+  condizioni simili FreeBSD risponde con un errore di \errval{EBADF}, mentre
+  OpenBSD elimina la possibilità di una \textit{race condition} al costo di
+  una perdita di prestazioni.} In tal caso occorre ritentare l'operazione.
 
 La duplicazione dei file descriptor può essere effettuata anche usando la
 funzione di controllo dei file \func{fcntl} (che esamineremo in
@@ -1562,10 +1565,9 @@ come per le altre funzioni che prendono come argomenti dei
 quando un \textit{pathname} relativo non fa riferimento ad un file posto
 direttamente nella directory di lavoro corrente, che alcuni dei componenti del
 \textit{pathname} vengano modificati in parallelo alla chiamata a \func{open},
-cosa che lascia aperta la possibilità di una \itindex{race~condition}
-\textit{race condition} in cui c'è spazio per un \itindex{symlink~attack}
-\textit{symlink attack} (si ricordi quanto visto per \func{access} in
-sez.~\ref{sec:file_perm_management}).
+cosa che lascia aperta la possibilità di una \textit{race condition} in cui
+c'è spazio per un \itindex{symlink~attack} \textit{symlink attack} (si ricordi
+quanto visto per \func{access} in sez.~\ref{sec:file_perm_management}).
 
 Inoltre come già accennato, la directory di lavoro corrente è una proprietà
 del singolo processo; questo significa che quando si lavora con i
@@ -1600,14 +1602,13 @@ directory come punto di partenza per la risoluzione. In questo modo, anche
 quando si lavora con i \itindex{thread} \textit{thread}, si può mantenere una
 directory di lavoro diversa per ciascuno di essi.
 
-Questo metodo, oltre a risolvere i problemi di \itindex{race~condition}
-\textit{race condition}, consente anche di ottenere aumenti di prestazioni
-significativi quando si devono eseguire molte operazioni su sezioni
-dell'albero dei file che prevedono delle gerarchie di sottodirectory molto
-profonde. Infatti in questo caso basta eseguire la risoluzione del
-\textit{pathname} della directory di partenza una sola volta (nell'apertura
-iniziale) e non tutte le volte che si deve accedere a ciascun file che essa
-contiene.
+Questo metodo, oltre a risolvere i problemi di \textit{race condition},
+consente anche di ottenere aumenti di prestazioni significativi quando si
+devono eseguire molte operazioni su sezioni dell'albero dei file che prevedono
+delle gerarchie di sottodirectory molto profonde. Infatti in questo caso basta
+eseguire la risoluzione del \textit{pathname} della directory di partenza una
+sola volta (nell'apertura iniziale) e non tutte le volte che si deve accedere
+a ciascun file che essa contiene.
 
 La sintassi generale di queste nuove funzioni è che esse prevedono come primo
 argomento il file descriptor della directory da usare come base per la
@@ -3093,9 +3094,8 @@ rispettivi prototipi sono:
 
 La funzione \func{getc} legge un byte da \param{stream} e lo restituisce come
 intero, ed in genere è implementata come una macro per cui può avere
-\itindex{side~effects} \textit{side effects}, mentre \func{fgetc} è assicurato
-essere sempre una funzione. Infine \func{getchar} è equivalente a
-\code{getc(stdin)}.
+\textit{side effects}, mentre \func{fgetc} è assicurato essere sempre una
+funzione. Infine \func{getchar} è equivalente a \code{getc(stdin)}.
 
 A parte \func{getchar}, che si usa in genere per leggere un carattere da
 tastiera, le altre due funzioni sono sostanzialmente equivalenti. La