Alcune correzioni ai font dei link, e una trattazione esplicita
[gapil.git] / fileadv.tex
index 797ecfbf9e4eccfeddc55ff2c59c4798b9121466..1ba5b9990692a8489fe8deefd1f9c54124dd4964 100644 (file)
@@ -107,10 +107,10 @@ Il primo kernel unix-like ad introdurre una interfaccia per l'\textit{I/O
     descriptor (anche nullo) che sono attivi, e -1 in caso di errore, nel qual
     caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
-  \item[\errcode{EBADF}] Si è specificato un file descriptor sbagliato in uno
+  \item[\errcode{EBADF}] si è specificato un file descriptor sbagliato in uno
     degli insiemi.
-  \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale.
-  \item[\errcode{EINVAL}] Si è specificato per \param{ndfs} un valore negativo
+  \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+  \item[\errcode{EINVAL}] si è specificato per \param{ndfs} un valore negativo
     o un valore non valido per \param{timeout}.
   \end{errlist}
   ed inoltre \errval{ENOMEM}.
@@ -267,10 +267,10 @@ precedenti, ed inoltre aggiunge a \func{select} una nuova funzione
     descriptor (anche nullo) che sono attivi, e -1 in caso di errore, nel qual
     caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
-  \item[\errcode{EBADF}] Si è specificato un file descriptor sbagliato in uno
+  \item[\errcode{EBADF}] si è specificato un file descriptor sbagliato in uno
     degli insiemi.
-  \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale.
-  \item[\errcode{EINVAL}] Si è specificato per \param{ndfs} un valore negativo
+  \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+  \item[\errcode{EINVAL}] si è specificato per \param{ndfs} un valore negativo
     o un valore non valido per \param{timeout}.
   \end{errlist}
   ed inoltre \errval{ENOMEM}.}
@@ -350,10 +350,10 @@ cui prototipo 
     in caso di successo, o 0 se c'è stato un timeout e -1 in caso di errore,
     ed in quest'ultimo caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
-  \item[\errcode{EBADF}] Si è specificato un file descriptor sbagliato in uno
+  \item[\errcode{EBADF}] si è specificato un file descriptor sbagliato in uno
     degli insiemi.
-  \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale.
-  \item[\errcode{EINVAL}] Il valore di \param{nfds} eccede il limite
+  \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+  \item[\errcode{EINVAL}] il valore di \param{nfds} eccede il limite
     \macro{RLIMIT\_NOFILE}.
   \end{errlist}
   ed inoltre \errval{EFAULT} e \errval{ENOMEM}.}
@@ -496,10 +496,10 @@ prototipo 
     in caso di successo, o 0 se c'è stato un timeout e -1 in caso di errore,
     ed in quest'ultimo caso \var{errno} assumerà uno dei valori:
   \begin{errlist}
-  \item[\errcode{EBADF}] Si è specificato un file descriptor sbagliato in uno
+  \item[\errcode{EBADF}] si è specificato un file descriptor sbagliato in uno
     degli insiemi.
-  \item[\errcode{EINTR}] La funzione è stata interrotta da un segnale.
-  \item[\errcode{EINVAL}] Il valore di \param{nfds} eccede il limite
+  \item[\errcode{EINTR}] la funzione è stata interrotta da un segnale.
+  \item[\errcode{EINVAL}] il valore di \param{nfds} eccede il limite
     \macro{RLIMIT\_NOFILE}.
   \end{errlist}
   ed inoltre \errval{EFAULT} e \errval{ENOMEM}.}
@@ -699,7 +699,7 @@ indicare quale tipo di evento relativo ad \param{fd} si vuole che sia tenuto
 sotto controllo.  L'argomento viene ignorato con l'operazione
 \const{EPOLL\_CTL\_DEL}.\footnote{fino al kernel 2.6.9 era comunque richiesto
   che questo fosse un puntatore valido, anche se poi veniva ignorato, a
-  partire dal 2.6.9 si può specificare anche anche un valore \texttt{NULL}.}
+  partire dal 2.6.9 si può specificare anche un valore \texttt{NULL}.}
 
 
 
@@ -741,7 +741,7 @@ si usa come valore lo stesso \param{fd}.
                           (analogo di \const{POLLIN}).\\
     \const{EPOLLOUT}    & Il file è pronto per le operazioni di scrittura
                           (analogo di \const{POLLOUT}).\\
-    \const{EPOLLRDHUP}  & l'altro capo di un socket di tipo
+    \const{EPOLLRDHUP}  & L'altro capo di un socket di tipo
                           \const{SOCK\_STREAM} (vedi sez.~\ref{sec:sock_type})
                           ha chiuso la connessione o il capo in scrittura
                           della stessa (vedi sez.~\ref{sec:TCP_shutdown}).\\
@@ -1248,7 +1248,7 @@ viene segnalata, ma poi 
 (operazione che può essere molto onerosa quando una directory contiene un gran
 numero di file).  Infine l'uso dei segnali come interfaccia di notifica
 comporta tutti i problemi di gestione visti in sez.~\ref{sec:sig_management} e
-sez.~\ref{sec:sig_control}.  Per tutta questa serie di motivi in generale
+sez.~\ref{sec:sig_adv_control}.  Per tutta questa serie di motivi in generale
 quella di \textit{dnotify} viene considerata una interfaccia di usabilità
 problematica.
 
@@ -1734,11 +1734,6 @@ raggruppati in un solo evento.
 \index{file!inotify|)}
 
 
-% TODO inserire anche eventfd (vedi http://lwn.net/Articles/233462/)
-% e le restanti signalfd e timerfd introdotte con il 2.6.22
-% o trovargli un posto migliore
-
-
 \subsection{L'interfaccia POSIX per l'I/O asincrono}
 \label{sec:file_asyncronous_io}
 
@@ -2356,7 +2351,7 @@ effettive del file o della sezione che si vuole mappare.
 
 \begin{figure}[!htb] 
   \centering
-  \includegraphics[width=13cm]{img/mmap_boundary}
+  \includegraphics[height=6cm]{img/mmap_boundary}
   \caption{Schema della mappatura in memoria di una sezione di file di
     dimensioni non corrispondenti al bordo di una pagina.}
   \label{fig:file_mmap_boundary}
@@ -2399,7 +2394,7 @@ che sono utilizzabili solo con questa interfaccia.
 
 \begin{figure}[htb]
   \centering
-  \includegraphics[width=13cm]{img/mmap_exceed}
+  \includegraphics[height=6cm]{img/mmap_exceed}
   \caption{Schema della mappatura in memoria di file di dimensioni inferiori
     alla lunghezza richiesta.}
   \label{fig:file_mmap_exceed}
@@ -2730,8 +2725,6 @@ mappatura che gi
 
 \itindend{memory~mapping}
 
-
-
 \subsection{I/O vettorizzato: \func{readv} e \func{writev}}
 \label{sec:file_multiple_io}
 
@@ -2917,7 +2910,7 @@ che anzi in certi casi si potevano avere anche dei peggioramenti.  Questo ha
 portato, per i kernel della serie 2.6,\footnote{per alcune motivazioni di
   questa scelta si può fare riferimento a quanto illustrato da Linus Torvalds
   in \href{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html}
-  {\texttt{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html}}.}
+  {\textsf{http://www.cs.helsinki.fi/linux/linux-kernel/2001-03/0200.html}}.}
 alla decisione di consentire l'uso della funzione soltanto quando il file da
 cui si legge supporta le operazioni di \textit{memory mapping} (vale a dire
 non è un socket) e quello su cui si scrive è un socket; in tutti gli altri
@@ -2944,13 +2937,15 @@ semplicemente un ``\textsl{dimezzamento}'' di \func{sendfile}.\footnote{nel
   sarebbe altro che la lettura degli stessi su un buffer seguita dalla
   relativa scrittura, cosa che in questo caso si dovrebbe eseguire con due
   chiamate a \func{splice}.} In realtà le due system call sono profondamente
-diverse nel loro meccanismo di funzionamento; \func{sendfile} infatti, come
-accennato, non necessita affatto di avere a disposizione un buffer interno,
-perché esegue un trasferimento diretto di dati; questo la rende in generale
-molto più efficiente, ma anche limitata nelle sue applicazioni, dato che
-questo tipo di trasferimento è possibile solo in casi specifici.\footnote{e
-  nel caso di Linux questi sono anche solo quelli in cui essa può essere
-  effettivamente utilizzata.}
+diverse nel loro meccanismo di funzionamento;\footnote{questo fino al kernel
+  2.6.23, dove \func{sendfile} è stata reimplementata in termini di
+  \func{splice}, pur mantenendo disponibile la stessa interfaccia verso l'user
+  space.} \func{sendfile} infatti, come accennato, non necessita di avere a
+disposizione un buffer interno, perché esegue un trasferimento diretto di
+dati; questo la rende in generale più efficiente, ma anche limitata nelle sue
+applicazioni, dato che questo tipo di trasferimento è possibile solo in casi
+specifici.\footnote{e nel caso di Linux questi sono anche solo quelli in cui
+  essa può essere effettivamente utilizzata.}
 
 Il concetto che sta dietro a \func{splice} invece è diverso,\footnote{in
   realtà la proposta originale di Larry Mc Voy non differisce poi tanto negli
@@ -2958,7 +2953,7 @@ Il concetto che sta dietro a \func{splice} invece 
   stata la reinterpretazione che ne è stata fatta nell'implementazione su
   Linux realizzata da Jens Anxboe, concetti che sono esposti sinteticamente
   dallo stesso Linus Torvalds in \href{http://kerneltrap.org/node/6505}
-  {\texttt{http://kerneltrap.org/node/6505}}.} si tratta semplicemente di una
+  {\textsf{http://kerneltrap.org/node/6505}}.} si tratta semplicemente di una
 funzione che consente di fare in maniera del tutto generica delle operazioni
 di trasferimento di dati fra un file e un buffer gestito interamente in kernel
 space. In questo caso il cuore della funzione (e delle affini \func{vmsplice}
@@ -3100,7 +3095,7 @@ descrizioni complete di tutti i valori possibili anche quando, come per
   meccanismi della memoria virtuale per eseguire i trasferimenti di dati (in
   maniera analoga a \func{mmap}), qualora le pagine non possano essere
   spostate dalla pipe o il buffer non corrisponda a pagine intere esse saranno
-  comunque comunque copiate.}
+  comunque copiate.}
 
 \footnotetext{questa opzione consente di utilizzare delle opzioni di gestione
   dei socket che permettono di ottimizzare le trasmissioni via rete, si veda
@@ -3138,8 +3133,7 @@ file destinazione. Il passo successivo 
 (\texttt{\small 18--22}), quello di destinazione (\texttt{\small 23--27}) ed
 infine (\texttt{\small 28--31}) la \textit{pipe} che verrà usata come buffer.
 
-
-\begin{figure}[!htbp]
+\begin{figure}[!phtb]
   \footnotesize \centering
   \begin{minipage}[c]{15cm}
     \includecodesample{listati/splicecp.c}
@@ -3207,7 +3201,7 @@ Come accennato con l'introduzione di \func{splice} sono state realizzate altre
 due system call, \func{vmsplice} e \func{tee}, che utilizzano la stessa
 infrastruttura e si basano sullo stesso concetto di manipolazione e
 trasferimento di dati attraverso un buffer in kernel space; benché queste non
-attengono strettamente ad operazioni di trasferiemento dati fra file
+attengono strettamente ad operazioni di trasferimento dati fra file
 descriptor, le tratteremo qui.
 
 La prima funzione, \funcd{vmsplice}, è la più simile a \func{splice} e come
@@ -3241,7 +3235,7 @@ corrispondente al suo capo aperto in scrittura (di nuovo si faccia riferimento
 a sez.~\ref{sec:ipc_unix}), mentre per indicare quali zone di memoria devono
 essere trasferita si deve utilizzare un vettore di strutture \struct{iovec}
 (vedi fig.~\ref{fig:file_iovec}), con le stesse con cui le si usano per l'I/O
-vettorizzato; le dimensioni del sudetto vettore devono essere passate
+vettorizzato; le dimensioni del suddetto vettore devono essere passate
 nell'argomento \param{nr\_segs} che indica il numero di segmenti di memoria da
 trasferire.  Sia per il vettore che per il valore massimo di \param{nr\_segs}
 valgono le stesse limitazioni illustrate in sez.~\ref{sec:file_multiple_io}.
@@ -3249,7 +3243,7 @@ valgono le stesse limitazioni illustrate in sez.~\ref{sec:file_multiple_io}.
 In caso di successo la funzione ritorna il numero di byte trasferiti sulla
 pipe, in generale (se i dati una volta creati non devono essere riutilizzati)
 è opportuno utilizzare il flag \const{SPLICE\_F\_GIFT}; questo fa si che il
-kernel possa rimuovere le relative pagine dallo spazio degli indifizzi del
+kernel possa rimuovere le relative pagine dallo spazio degli indirizzi del
 processo, e scaricarle nella cache, così che queste possono essere utilizzate
 immediatamente senza necessità di eseguire una copia dei dati che contengono.
 
@@ -3290,32 +3284,64 @@ comportamento delle \textit{pipe} si veda sez.~\ref{sec:ipc_unix}).
 
 La funzione restituisce il numero di byte copiati da una \textit{pipe}
 all'altra (o $-1$ in caso di errore), un valore nullo indica che non ci sono
-byte disponibili da copiare (la funzione in questo caso non si blocca, a
-differenza di quanto avverrebbe per una normale lettura). Un esempio di
-realizzazione del comando \texttt{tee} usando questa funzione, ripreso da
-quello fornito nella pagina di manuale, è riportato in fig..
-
+byte disponibili da copiare e che il capo in scrittura della pipe è stato
+chiuso.\footnote{si tenga presente però che questo non avviene se si è
+  impostato il flag \const{SPLICE\_F\_NONBLOCK}, in tal caso infatti si
+  avrebbe un errore di \errcode{EAGAIN}.} Un esempio di realizzazione del
+comando \texttt{tee} usando questa funzione, ripreso da quello fornito nella
+pagina di manuale e dall'esempio allegato al patch originale, è riportato in
+fig.~\ref{fig:tee_example}. Il programma consente di copiare il contenuto
+dello standard input sullo standard output e su un file specificato come
+argomento, il codice completo si trova nel file \texttt{tee.c} dei sorgenti
+allegati alla guida.
 
+\begin{figure}[!htbp]
+  \footnotesize \centering
+  \begin{minipage}[c]{15cm}
+    \includecodesample{listati/tee.c}
+  \end{minipage}
+  \normalsize
+  \caption{Esempio di codice che usa \func{tee} per copiare i dati dello
+    standard input sullo standard output e su un file.}
+  \label{fig:tee_example}
+\end{figure}
 
-Infine come nota finale riguardo \func{splice}, \func{vmsplice} e \func{tee}
-occorre sottolineare che benché si sia parlato finora di trasferimenti o copie
-di dati in realtà nella loro implementazione non è affatto detto che questi
-vengono effettivamente spostati o copiati, il kernel infatti realizza le
-\textit{pipe} come un insieme di puntatori\footnote{per essere precisi si
-  tratta di un semplice buffer circolare, un buon articolo sul tema si trova
-  su \href{http://lwn.net/Articles/118750/}
-  {\texttt{http://lwn.net/Articles/118750/}}.}  alle pagine di memoria interna
+La prima parte del programma (\texttt{\small 10--35}) si cura semplicemente di
+controllare (\texttt{\small 11--14}) che sia stato fornito almeno un argomento
+(il nome del file su cui scrivere), di aprirlo ({\small 15--19}) e che sia lo
+standard input (\texttt{\small 20--27}) che lo standard output (\texttt{\small
+  28--35}) corrispondano ad una \textit{pipe}.
+
+Il ciclo principale (\texttt{\small 37--58}) inizia con la chiamata a
+\func{tee} che duplica il contenuto dello standard input sullo standard output
+(\texttt{\small 39}), questa parte è del tutto analoga ad una lettura ed
+infatti come nell'esempio di fig.~\ref{fig:splice_example} si controlla il
+valore di ritorno della funzione in \var{len}; se questo è nullo significa che
+non ci sono più dati da leggere e si chiude il ciclo (\texttt{\small 40}), se
+è negativo c'è stato un errore, ed allora si ripete la chiamata se questo è
+dovuto ad una interruzione (\texttt{\small 42--44}) o si stampa un messaggio
+di errore e si esce negli altri casi (\texttt{\small 44--47}).
+
+Una volta completata la copia dei dati sullo standard output si possono
+estrarre dalla standard input e scrivere sul file, di nuovo su usa un ciclo di
+scrittura (\texttt{\small 50--58}) in cui si ripete una chiamata a
+\func{splice} (\texttt{\small 51}) fintanto che non si sono scritti tutti i
+\var{len} byte copiati in precedenza con \func{tee} (il funzionamento è
+identico all'analogo ciclo di scrittura del precedente esempio di
+fig.~\ref{fig:splice_example}).
+
+Infine una nota finale riguardo \func{splice}, \func{vmsplice} e \func{tee}:
+occorre sottolineare che benché finora si sia parlato di trasferimenti o copie
+di dati in realtà nella implementazione di queste system call non è affatto
+detto che i dati vengono effettivamente spostati o copiati, il kernel infatti
+realizza le \textit{pipe} come un insieme di puntatori\footnote{per essere
+  precisi si tratta di un semplice buffer circolare, un buon articolo sul tema
+  si trova su \href{http://lwn.net/Articles/118750/}
+  {\textsf{http://lwn.net/Articles/118750/}}.}  alle pagine di memoria interna
 che contengono i dati, per questo una volta che i dati sono presenti nella
 memoria del kernel tutto quello che viene fatto è creare i suddetti puntatori
-ed aumentare il numero di referenze, pertanto anche con \func{tee} non viene
-mai copiato nessun byte, vengono semplicemente copiati i puntatori.
-
-
-% TODO documentare le funzioni tee e splice
-% http://kerneltrap.org/node/6505 e http://lwn.net/Articles/178199/ e 
-% http://lwn.net/Articles/179492/ e http://lwn.net/Articles/181169
-% e http://en.wikipedia.org/wiki/Splice_(system_call)
-
+ed aumentare il numero di referenze; questo significa che anche con \func{tee}
+non viene mai copiato nessun byte, vengono semplicemente copiati i puntatori.
 
 
 
@@ -3335,18 +3361,207 @@ specifiche dei singoli programmi, che avendo una conoscenza diretta di come
 verranno usati i file, possono necessitare di effettuare delle ottimizzazioni
 specifiche, relative alle proprie modalità di I/O sugli stessi. Tratteremo in
 questa sezione una serie funzioni che consentono ai programmi di ottimizzare
-il loro accesso ai dati dei file.
+il loro accesso ai dati dei file e controllare la gestione del relativo
+\textit{caching}.
+
+Una prima funzione che può essere utilizzata per modificare la gestione
+ordinaria dell'I/O su un file è \funcd{readahead},\footnote{questa è una
+  funzione specifica di Linux, introdotta con il kernel 2.4.13, e non deve
+  essere usata se si vogliono scrivere programmi portabili.} che consente di
+richiedere una lettura anticipata del contenuto dello stesso in cache, così
+che le seguenti operazioni di lettura non debbano subire il ritardo dovuto
+all'accesso al disco; il suo prototipo è:
+\begin{functions}
+  \headdecl{fcntl.h}
+
+  \funcdecl{ssize\_t readahead(int fd, off64\_t *offset, size\_t count)}
+  
+  Esegue una lettura preventiva del contenuto di un file in cache.
+
+  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+    errore, nel qual caso \var{errno} assumerà uno dei valori:
+    \begin{errlist}
+    \item[\errcode{EBADF}] l'argomento \param{fd} non è un file descriptor
+      valido o non è aperto in lettura.
+    \item[\errcode{EINVAL}] l'argomento \param{fd} si riferisce ad un tipo di
+      file che non supporta l'operazione (come una pipe o un socket).
+    \end{errlist}
+  }
+\end{functions}
+
+La funzione richiede che venga letto in anticipo il contenuto del file
+\param{fd} a partire dalla posizione \param{offset} e per un ammontare di
+\param{count} byte, in modo da portarlo in cache.  La funzione usa la
+\index{memoria~virtuale} memoria virtuale ed il meccanismo della
+\index{paginazione} paginazione per cui la lettura viene eseguita in blocchi
+corrispondenti alle dimensioni delle pagine di memoria, ed i valori di
+\param{offset} e \param{count} arrotondati di conseguenza.
+
+La funzione estende quello che è un comportamento normale del
+kernel\footnote{per ottimizzare gli accessi al disco il kernel quando si legge
+  un file, aspettandosi che l'accesso prosegua, esegue sempre una lettura
+  anticipata di una certa quantità di dati; questo meccanismo viene chiamato
+  \textit{readahead}, da cui deriva il nome della funzione.} effettuando la
+lettura in cache della sezione richiesta e bloccandosi fintanto che questa non
+viene completata.  La posizione corrente sul file non viene modificata ed
+indipendentemente da quanto indicato con \param{count} la lettura dei dati si
+interrompe una volta raggiunta la fine del file.
+
+Si può utilizzare questa funzione per velocizzare le operazioni di lettura
+all'interno del programma tutte le volte che si conosce in anticipo quanti
+dati saranno necessari in seguito. Si potrà così concentrare in un unico
+momento (ad esempio in fase di inizializzazione) la lettura, così da ottenere
+una migliore risposta nelle operazioni successive.
+
+Il concetto di \func{readahead} viene generalizzato nello standard
+POSIX.1-2001 dalla funzione \funcd{posix\_fadvise},\footnote{anche se
+  l'argomento \param{len} è stato modificato da \ctyp{size\_t} a \ctyp{off\_t}
+  nella revisione POSIX.1-2003 TC5.} che consente di ``\textsl{avvisare}'' il
+kernel sulle modalità con cui si intende accedere nel futuro ad una certa
+porzione di un file,\footnote{la funzione però è stata introdotta su Linux
+  solo a partire dal kernel 2.5.60.} così che esso possa provvedere le
+opportune ottimizzazioni; il suo prototipo, che può è disponibile solo se si
+definisce la macro \macro{\_XOPEN\_SOURCE} ad almeno 600, è:
+\begin{functions}  
+  \headdecl{fcntl.h} 
+
+  \funcdecl{int posix\_fadvise(int fd, off\_t offset, off\_t len, int advice)}
+  
+  Dichiara al kernel le future modalità di accesso ad un file.
+
+  \bodydesc{La funzione restituisce 0 in caso di successo e $-1$ in caso di
+    errore, nel qual caso \var{errno} assumerà uno dei valori:
+    \begin{errlist}
+    \item[\errcode{EBADF}] l'argomento \param{fd} non è un file descriptor
+      valido.
+    \item[\errcode{EINVAL}] il valore di \param{advice} non è valido o
+      \param{fd} si riferisce ad un tipo di file che non supporta l'operazione
+      (come una pipe o un socket).
+    \item[\errcode{ESPIPE}] previsto dallo standard se \param{fd} è una pipe o
+      un socket (ma su Linux viene restituito \errcode{EINVAL}).
+    \end{errlist}
+  }
+\end{functions}
+
+La funzione dichiara al kernel le modalità con cui intende accedere alla
+regione del file indicato da \param{fd} che inizia alla posizione
+\param{offset} e si estende per \param{len} byte. Se per \param{len} si usa un
+valore nullo la regione coperta sarà da \param{offset} alla fine del
+file.\footnote{questo è vero solo per le versioni più recenti, fino al kernel
+  2.6.6 il valore nullo veniva interpretato letteralmente.} Le modalità sono
+indicate dall'argomento \param{advice} che è una maschera binaria dei valori
+illustrati in tab.~\ref{tab:posix_fadvise_flag}. Si tenga presente comunque
+che la funzione dà soltanto un avvertimento, non esiste nessun vincolo per il
+kernel, che utilizza semplicemente l'informazione.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{10cm}|}
+    \hline
+    \textbf{Valore} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{POSIX\_FADV\_NORMAL}  & Non ci sono avvisi specifici da fare
+                                   riguardo le modalità di accesso, il
+                                   comportamento sarà identico a quello che si
+                                   avrebbe senza nessun avviso.\\ 
+    \const{POSIX\_FADV\_SEQUENTIAL}& L'applicazione si aspetta di accedere di
+                                   accedere ai dati specificati in maniera
+                                   sequenziale, a partire dalle posizioni più
+                                   basse.\\ 
+    \const{POSIX\_FADV\_RANDOM}  & I dati saranno letti in maniera
+                                   completamente causale.\\
+    \const{POSIX\_FADV\_NOREUSE} & I dati saranno acceduti una sola volta.\\ 
+    \const{POSIX\_FADV\_WILLNEED}& I dati saranno acceduti a breve.\\ 
+    \const{POSIX\_FADV\_DONTNEED}& I dati non saranno acceduti a breve.\\ 
+    \hline
+  \end{tabular}
+  \caption{Valori dei bit dell'argomento \param{advice} di
+    \func{posix\_fadvise} che indicano la modalità con cui si intende accedere
+    ad un file.}
+  \label{tab:posix_fadvise_flag}
+\end{table}
+
+Anche \func{posix\_fadvise} si appoggia al sistema della memoria virtuale ed
+al meccanismo standard del \textit{readahead} utilizzato dal kernel; in
+particolare con \const{POSIX\_FADV\_SEQUENTIAL} si raddoppia la dimensione
+dell'ammontare di dati letti preventivamente rispetto al default, aspettandosi
+appunto una lettura sequenziale che li utilizzerà, mentre con
+\const{POSIX\_FADV\_RANDOM} si disabilita del tutto il suddetto meccanismo,
+dato che con un accesso del tutto casuale è inutile mettersi a leggere i dati
+immediatamente successivi gli attuali; infine l'uso di
+\const{POSIX\_FADV\_NORMAL} consente di riportarsi al comportamento di
+default.
+
+Le due modalità \const{POSIX\_FADV\_NOREUSE} e \const{POSIX\_FADV\_WILLNEED}
+danno invece inizio ad una lettura in cache della regione del file indicata.
+La quantità di dati che verranno letti è ovviamente limitata in base al carico
+che si viene a creare sul sistema della memoria virtuale, ma in genere una
+lettura di qualche megabyte viene sempre soddisfatta (ed un valore superiore è
+solo raramente di qualche utilità). In particolare l'uso di
+\const{POSIX\_FADV\_WILLNEED} si può considerare l'equivalente POSIX di
+\func{readahead}.
+
+Infine con \const{POSIX\_FADV\_DONTNEED} si dice al kernel di liberare le
+pagine di cache occupate dai dati presenti nella regione di file indicata.
+Questa è una indicazione utile che permette di alleggerire il carico sulla
+cache, ed un programma può utilizzare periodicamente questa funzione per
+liberare pagine di memoria da dati che non sono più utilizzati per far posto a
+nuovi dati utili.\footnote{la pagina di manuale riporta l'esempio dello
+  streaming di file di grosse dimensioni, dove le pagine occupate dai dati già
+  inviati possono essere tranquillamente scartate.}
+
+Sia \func{posix\_fadvise} che \func{readahead} attengono alla ottimizzazione
+dell'accesso in lettura; lo standard POSIX.1-2001 prevede anche una funzione
+specifica per le operazioni di scrittura, \func{posix\_fallocate},\footnote{la
+  funzione è stata introdotta a partire dalle glibc 2.1.94.} che consente di
+preallocare dello spazio disco per assicurarsi che una seguente scrittura non
+fallisca, il suo prototipo, anch'esso disponibile solo se si definisce la
+macro \macro{\_XOPEN\_SOURCE} ad almeno 600, è:
+\begin{functions}  
+  \headdecl{fcntl.h} 
+
+  \funcdecl{int posix\_fallocate(int fd, off\_t offset, off\_t len)}
+  
+  Richiede la allocazione di spazio disco per un file.
 
+  \bodydesc{La funzione restituisce 0 in caso di successo e direttamente un
+    codice di errore, in caso di fallimento, in questo caso \var{errno} non
+    viene impostata, ma sarà restituito direttamente uno dei valori:
+    \begin{errlist}
+    \item[\errcode{EBADF}] l'argomento \param{fd} non è un file descriptor
+      valido o non è aperto in scrittura.
+    \item[\errcode{EINVAL}] o \param{offset} o \param{len} sono minori di
+      zero.
+    \item[\errcode{EFBIG}] il valore di (\param{offset} + \param{len}) eccede
+      la dimensione massima consentita per un file.
+    \item[\errcode{ENODEV}] l'argomento \param{fd} non fa riferimento ad un
+      file regolare.
+    \item[\errcode{ENOSPC}] non c'è sufficiente spazio disco per eseguire
+      l'operazione. 
+    \item[\errcode{ESPIPE}] l'argomento \param{fd} è una pipe.
+  \end{errlist}
+  }
+\end{functions}
 
-% TODO documentare \func{madvise}
-% TODO documentare \func{mincore}
+La funzione si assicura che venga allocato sufficiente spazio disco perché sia
+possibile scrivere sul file indicato dall'argomento \param{fd} nella regione
+che inizia dalla posizione \param{offset} e si estende per \param{len} byte;
+se questa si estende oltre la fine del file le dimensioni di quest'ultimo
+saranno incrementate di conseguenza. Dopo aver eseguito con successo la
+funzione è garantito che una scrittura nella regione indicata non fallirà per
+mancanza di spazio disco.
+
+
 % TODO documentare \func{posix\_fadvise}
 % vedi http://insights.oetiker.ch/linux/fadvise.html
 % questo tread? http://www.ussg.iu.edu/hypermail/linux/kernel/0703.1/0032.html
 
 % TODO documentare \func{fallocate}, introdotta con il 2.6.23
 % vedi http://lwn.net/Articles/226710/ e http://lwn.net/Articles/240571/
-
+% http://kernelnewbies.org/Linux_2_6_23
 
 %\subsection{L'utilizzo delle porte di I/O}
 %\label{sec:file_io_port}
@@ -3378,7 +3593,7 @@ in cui diversi processi scrivono, mescolando in maniera imprevedibile il loro
 output sul file.
 
 In tutti questi casi il \textit{file locking} è la tecnica che permette di
-evitare le \textit{race condition} \itindex{race~condition}, attraverso una
+evitare le \itindex{race~condition} \textit{race condition}, attraverso una
 serie di funzioni che permettono di bloccare l'accesso al file da parte di
 altri processi, così da evitare le sovrapposizioni, e garantire la atomicità
 delle operazioni di scrittura.
@@ -4251,12 +4466,14 @@ possibilit
 % LocalWords:  EPOLLHUP EPOLLET EPOLLONESHOT shot maxevents ctlv ALL DONT HPUX
 % LocalWords:  FOLLOW ONESHOT ONLYDIR FreeBSD EIO caching sysctl instances name
 % LocalWords:  watches IGNORED ISDIR OVERFLOW overflow UNMOUNT queued cookie ls
-% LocalWords:  NUL sizeof casting printevent nread limits sysconf SC wrapper
+% LocalWords:  NUL sizeof casting printevent nread limits sysconf SC wrapper Di
 % LocalWords:  splice result argument DMA controller zerocopy Linus Larry Voy
-% LocalWords:  Jens Anxboe vmsplice seek ESPIPE GIFT TCP CORK MSG splicecp
+% LocalWords:  Jens Anxboe vmsplice seek ESPIPE GIFT TCP CORK MSG splicecp nr
+% LocalWords:  nwrite segs patch readahead posix fadvise TC advice FADV NORMAL
 
 
 %%% Local Variables: 
 %%% mode: latex
 %%% TeX-master: "gapil"
 %%% End: 
+% LocalWords:  SEQUENTIAL NOREUSE WILLNEED DONTNEED streaming fallocate EFBIG