Aggiunte varie e correzioni
[gapil.git] / fileadv.tex
index 7c3734c3da82a21225f1522445187fa28be20b07..97249198be36d745d604947117032ff1c642b114 100644 (file)
@@ -192,7 +192,7 @@ bloccher
 ritornerà subito con un errore di \errcode{EWOULDBLOCK}. Per rilasciare un
 \textit{file lock} si dovrà invece usare \const{LOCK\_UN}.
 
-Si tenga presente che non esite una modalità per eseguire atomicamente un
+Si tenga presente che non esiste una modalità per eseguire atomicamente un
 cambiamento del tipo di blocco (da \textit{shared lock} a \textit{esclusive
   lock}), il blocco deve essere prima rilasciato e poi richiesto, ed è sempre
 possibile che nel frattempo abbia successo un'altra richiesta pendente,
@@ -1775,7 +1775,7 @@ anche con il fatto che sono stati restituiti meno dati di quelli richiesti.
 
 Come già per \func{select} e \func{poll} anche per l'interfaccia di
 \textit{epoll} si pone il problema di gestire l'attesa di segnali e di dati
-contemponeamente, per far questo di nuovo è necessaria una variante della
+contemporaneamente, per far questo di nuovo è necessaria una variante della
 funzione di attesa che consenta di reimpostare all'uscita una maschera di
 segnali, analoga alle precedenti estensioni \func{pselect} e \func{ppoll}; in
 questo caso la funzione si chiama \funcd{epoll\_pwait}\footnote{introdotta a
@@ -3134,7 +3134,6 @@ partire da \param{offset} per \param{lenght} byte, preferibilmente
 all'indirizzo \param{start}. Il valore di \param{offset} deve essere un
 multiplo della dimensione di una pagina di memoria. 
 
-
 \begin{table}[htb]
   \centering
   \footnotesize
@@ -3280,7 +3279,7 @@ effettive del file o della sezione che si vuole mappare.
 
 \begin{figure}[!htb] 
   \centering
-  \includegraphics[height=6.5cm]{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}
@@ -3363,7 +3362,7 @@ del tutto imprevedibile il risultato della modifica di un file nei confronti
 del contenuto della memoria su cui è mappato.
 
 Per questo, è sempre sconsigliabile eseguire scritture su file attraverso
-l'interfaccia standard, quando lo si è mappato in memoria, è invece possibile
+l'interfaccia standard quando lo si è mappato in memoria, è invece possibile
 usare l'interfaccia standard per leggere un file mappato in memoria, purché si
 abbia una certa cura; infatti l'interfaccia dell'I/O mappato in memoria mette
 a disposizione la funzione \funcd{msync} per sincronizzare il contenuto della
@@ -3395,34 +3394,37 @@ relativi tempi di modifica. In questo modo si 
 di \func{msync} le funzioni dell'interfaccia standard troveranno un contenuto
 del file aggiornato.
 
+
 \begin{table}[htb]
   \centering
   \footnotesize
-  \begin{tabular}[c]{|l|l|}
+  \begin{tabular}[c]{|l|p{11cm}|}
     \hline
     \textbf{Valore} & \textbf{Significato} \\
     \hline
     \hline
-    \const{MS\_ASYNC}     & Richiede la sincronizzazione.\\
-    \const{MS\_SYNC}      & Attende che la sincronizzazione si eseguita.\\
-    \const{MS\_INVALIDATE}& Richiede che le altre mappature dello stesso file
-                            siano invalidate.\\
-    \hline    
+    \const{MS\_SYNC}       & richiede una sincronizzazione e ritorna soltanto
+                             quando questa è stata completata.\\
+    \const{MS\_ASYNC}      & richiede una sincronizzazione, ma ritorna subito 
+                             non attendendo che questa sia finita.\\
+    \const{MS\_INVALIDATE} & invalida le pagine per tutte le mappature
+                             in memoria così da rendere necessaria una
+                             rilettura immediata delle stesse.\\
+    \hline
   \end{tabular}
-  \caption{Le costanti che identificano i bit per la maschera binaria
-    dell'argomento \param{flag} di \func{msync}.}
-  \label{tab:file_mmap_rsync}
+  \caption{Valori possibili dell'argomento \param{flag} di \func{msync}.}
+  \label{tab:file_mmap_msync}
 \end{table}
 
 L'argomento \param{flag} è specificato come maschera binaria composta da un OR
-dei valori riportati in tab.~\ref{tab:file_mmap_rsync}, di questi però
+dei valori riportati in tab.~\ref{tab:file_mmap_msync}, di questi però
 \const{MS\_ASYNC} e \const{MS\_SYNC} sono incompatibili; con il primo valore
 infatti la funzione si limita ad inoltrare la richiesta di sincronizzazione al
 meccanismo della memoria virtuale, ritornando subito, mentre con il secondo
 attende che la sincronizzazione sia stata effettivamente eseguita. Il terzo
-flag fa invalidare le pagine di cui si richiede la sincronizzazione per tutte
-le mappature dello stesso file, così che esse possano essere immediatamente
-aggiornate ai nuovi valori.
+flag fa sì che vengano invalidate, per tutte le mappature dello stesso file,
+le pagine di cui si è richiesta la sincronizzazione, così che esse possano
+essere immediatamente aggiornate con i nuovi valori.
 
 Una volta che si sono completate le operazioni di I/O si può eliminare la
 mappatura della memoria usando la funzione \funcd{munmap}, il suo prototipo è:
@@ -3667,25 +3669,122 @@ le opportune strategie di ottimizzazione. Il suo prototipo 
 \begin{functions}  
   \headdecl{sys/mman.h} 
 
-  \funcdecl{int madvise(void *start, size\_t length, int advise)}
+  \funcdecl{int madvise(void *start, size\_t length, int advice)}
   
-  Fornisci indicazioni sull'uso di un \textit{memory mapping}.
+  Fornisce indicazioni sull'uso previsto di un \textit{memory mapping}.
 
   \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{EAGAIN}] .
-    \item[\errcode{EBADF}] .
-    \item[\errcode{EINVAL}] .
-    \item[\errcode{EIO}] .
-    \item[\errcode{ENOMEM}] .
+    \item[\errcode{EBADF}] la mappatura esiste ma non corrisponde ad un file.
+    \item[\errcode{EINVAL}] \param{start} non è allineato alla dimensione di
+      una pagina, \param{length} ha un valore negativo, o \param{advice} non è
+      un valore valido, o si è richiesto il rilascio (con
+      \const{MADV\_DONTNEED}) di pagine bloccate o condivise.
+    \item[\errcode{EIO}] la paginazione richiesta eccederebbe i limiti (vedi
+      sez.~\ref{sec:sys_resource_limit}) sulle pagine residenti in memoria del
+      processo (solo in caso di \const{MADV\_WILLNEED}).
+    \item[\errcode{ENOMEM}] gli indirizzi specificati non sono mappati, o, in
+      caso \const{MADV\_WILLNEED}, non c'è sufficiente memoria per soddisfare
+      la richiesta.
     \end{errlist}
+    ed inoltre \errval{EAGAIN} e \errval{ENOSYS}.
   }
 \end{functions}
 
+La sezione di memoria sulla quale si intendono fornire le indicazioni deve
+essere indicata con l'indirizzo iniziale \param{start} e l'estensione
+\param{lenght}, il valore di \param{start} deve essere allineato,
+mentre \param{length} deve essere un numero positivo.\footnote{la versione di
+  Linux consente anche un valore nullo per \param{lenght}, inoltre se una
+  parte dell'intervallo non è mappato in memoria l'indicazione viene comunque
+  applicata alle restanti parti, anche se la funzione ritorna un errore di
+  \errval{ENOMEM}.} L'indicazione viene espressa dall'argomento \param{advice}
+che deve essere specificato con uno dei valori\footnote{si tenga presente che
+  gli ultimi tre valori sono specifici di Linux (introdotti a partire dal
+  kernel 2.6.16) e non previsti dallo standard POSIX.1b.} riportati in
+tab.~\ref{tab:madvise_advice_values}.
+
+\begin{table}[htb]
+  \centering
+  \footnotesize
+  \begin{tabular}[c]{|l|p{10 cm}|}
+    \hline
+    \textbf{Valore} & \textbf{Significato} \\
+    \hline
+    \hline
+    \const{MADV\_NORMAL}  & nessuna indicazione specifica, questo è il valore
+                            di default usato quando non si è chiamato
+                            \func{madvise}.\\
+    \const{MADV\_RANDOM}  & ci si aspetta un accesso casuale all'area
+                            indicata, pertanto l'applicazione di una lettura
+                            anticipata con il meccanismo del
+                            \itindex{read-ahead} \textit{read-ahead} (vedi
+                            sez.~\ref{sec:file_fadvise}) è di
+                            scarsa utilità e verrà disabilitata.\\
+    \const{MADV\_SEQUENTIAL}& ci si aspetta un accesso sequenziale al file,
+                            quindi da una parte sarà opportuno eseguire una
+                            lettura anticipata, e dall'altra si potranno
+                            scartare immediatamente le pagine una volta che
+                            queste siano state lette.\\
+    \const{MADV\_WILLNEED}& ci si aspetta un accesso nell'immediato futuro,
+                            pertanto l'applicazione del \textit{read-ahead}
+                            deve essere incentivata.\\
+    \const{MADV\_DONTNEED}& non ci si aspetta nessun accesso nell'immediato
+                            futuro, pertanto le pagine possono essere
+                            liberate dal kernel non appena necessario; l'area
+                            di memoria resterà accessibile, ma un accesso
+                            richiederà che i dati vengano ricaricati dal file
+                            a cui la mappatura fa riferimento.\\
+    \hline
+    \const{MADV\_REMOVE}  & libera un intervallo di pagine di memoria ed il
+                            relativo supporto sottostante; è supportato
+                            soltanto sui filesystem in RAM \textit{tmpfs} e
+                            \textit{shmfs}.\footnotemark\\ 
+    \const{MADV\_DONTFORK}& impedisce che l'intervallo specificato venga
+                            ereditato dal processo figlio dopo una
+                            \func{fork}; questo consente di evitare che il
+                            meccanismo del \itindex{copy~on~write}
+                            \textit{copy on write} effettui la rilocazione
+                            delle pagine quando il padre scrive sull'area
+                            di memoria dopo la \func{fork}, cosa che può
+                            causare problemi per l'hardware che esegue
+                            operazioni in DMA su quelle pagine.\\
+    \const{MADV\_DOFORK}  & rimuove l'effetto della precedente
+                            \const{MADV\_DONTFORK}.\\ 
+    \const{MADV\_MERGEABLE}& marca la pagina come accorpabile (indicazione
+                            principalmente ad uso dei sistemi di
+                            virtualizzazione).\footnotemark\\
+    \hline
+  \end{tabular}
+  \caption{Valori dell'argomento \param{advice} di \func{madvise}.}
+  \label{tab:madvise_advice_values}
+\end{table}
+
+\footnotetext{se usato su altri tipi di filesystem causa un errore di
+  \errcode{ENOSYS}.}
+
+\footnotetext{a partire dal kernel 2.6.32 è stato introdotto un meccanismo che
+  identifica pagine di memoria identiche e le accorpa in una unica pagina
+  (soggetta al \textit{copy-on-write} per successive modifiche); per evitare
+  di controllare tutte le pagine solo quelle marcate con questo flag vengono
+  prese in considerazione per l'accorpamento; in questo modo si possono
+  migliorare le prestazioni nella gestione delle macchine virtuali diminuendo
+  la loro occupazione di memoria, ma il meccanismo può essere usato anche in
+  altre applicazioni in cui sian presenti numerosi processi che usano gli
+  stessi dati; per maggiori dettagli si veda
+  \href{http://kernelnewbies.org/Linux_2_6_32\#head-d3f32e41df508090810388a57efce73f52660ccb}{\texttt{http://kernelnewbies.org/Linux\_2\_6\_32}}.}
+
+La funzione non ha, tranne il caso di \const{MADV\_DONTFORK}, nessun effetto
+sul comportamento di un programma, ma può influenzarne le prestazioni fornendo
+al kernel indicazioni sulle esigenze dello stesso, così che sia possibile
+scegliere le opportune strategie per la gestione del \itindex{read-ahead}
+\textit{read-ahead} e del caching dei dati. A differenza da quanto specificato
+nello standard POSIX.1b, per il quale l'uso di \func{madvise} è a scopo
+puramente indicativo, Linux considera queste richieste come imperative, per
+cui ritorna un errore qualora non possa soddisfarle.\footnote{questo
+  comportamento differisce da quanto specificato nello standard.}
 
-% TODO documentare \func{madvise}
 \itindend{memory~mapping}
 
 
@@ -3697,15 +3796,16 @@ serie multipla di operazioni di I/O, come una serie di letture o scritture di
 vari buffer. Un esempio tipico è quando i dati sono strutturati nei campi di
 una struttura ed essi devono essere caricati o salvati su un file.  Benché
 l'operazione sia facilmente eseguibile attraverso una serie multipla di
-chiamate, ci sono casi in cui si vuole poter contare sulla atomicità delle
-operazioni.
-
-Per questo motivo su BSD 4.2 sono state introdotte due nuove system call,
-\funcd{readv} e \funcd{writev},\footnote{in Linux le due funzioni sono riprese
-  da BSD4.4, esse sono previste anche dallo standard POSIX.1-2001.}  che
-permettono di effettuare con una sola chiamata una lettura o una scrittura su
-una serie di buffer (quello che viene chiamato \textsl{I/O vettorizzato}. I
-relativi prototipi sono:
+chiamate a \func{read} e \func{write}, ci sono casi in cui si vuole poter
+contare sulla atomicità delle operazioni.
+
+Per questo motivo fino da BSD 4.2 vennero introdotte delle nuove system call
+che permettessero di effettuare con una sola chiamata una serie di letture o
+scritture su una serie di buffer, con quello che viene normalmente chiamato
+\textsl{I/O vettorizzato}. Queste funzioni sono \funcd{readv} e
+\funcd{writev},\footnote{in Linux le due funzioni sono riprese da BSD4.4, esse
+  sono previste anche dallo standard POSIX.1-2001.} ed i relativi prototipi
+sono:
 \begin{functions}
   \headdecl{sys/uio.h}
   
@@ -3776,9 +3876,63 @@ buffer di dimensioni sufficienti appositamente allocato e sufficiente a
 contenere tutti i dati indicati da \param{vector}. L'operazione avrà successo
 ma si perderà l'atomicità del trasferimento da e verso la destinazione finale.
 
-% TODO verificare cosa succederà a preadv e pwritev o alla nuova niovec
-% vedi http://lwn.net/Articles/164887/
-% inserite nel kernel 2.6.30, vedi http://lwn.net/Articles/326818/
+Si tenga presente infine che queste funzioni operano sui file con
+l'interfaccia dei file descriptor, e non è consigliabile mescolarle con
+l'interfaccia classica dei \textit{file stream} di
+cap.~\ref{cha:files_std_interface}; a causa delle bufferizzazioni interne di
+quest'ultima infatti si potrebbero avere risultati indefiniti e non
+corrispondenti a quanto aspettato.
+
+Come per le normali operazioni di lettura e scrittura, anche per l'\textsl{I/O
+  vettorizzato} si pone il problema di poter effettuare le operazioni in
+maniera atomica a partire da un certa posizione sul file. Per questo motivo a
+partire dal kernel 2.6.30 sono state introdotte anche per l'\textsl{I/O
+  vettorizzato} le analoghe delle funzioni \func{pread} e \func{pwrite} (vedi
+sez.~\ref{sec:file_read} e \ref{sec:file_write}); le due funzioni sono
+\funcd{preadv} e \func{pwritev} ed i rispettivi prototipi sono:\footnote{le
+  due funzioni sono analoghe alle omonime presenti in BSD; le \textit{system
+    call} usate da Linux (introdotte a partire dalla versione 2.6.30)
+  utilizzano degli argomenti diversi per problemi collegati al formato a 64
+  bit dell'argomento \param{offset}, che varia a seconda delle architetture,
+  ma queste differenze vengono gestite dalle funzioni di librerie di libreria
+  che mantengono l'interfaccia delle analoghe tratte da BSD.}
+\begin{functions}
+  \headdecl{sys/uio.h}
+  
+  \funcdecl{int preadv(int fd, const struct iovec *vector, int count, off\_t
+    offset)}
+  \funcdecl{int pwritev(int fd, const struct iovec *vector, int count, off\_t
+    offset)}
+
+  Eseguono una lettura o una scrittura vettorizzata a partire da una data
+  posizione sul file.
+  
+  \bodydesc{Le funzioni hanno gli stessi valori di ritorno delle
+    corrispondenti \func{readv} e \func{writev}; anche gli eventuali errori
+    sono gli stessi già visti in precedenza, ma ad essi si possono aggiungere
+    per \var{errno} anche i valori:
+  \begin{errlist}
+  \item[\errcode{EOVERFLOW}] \param{offset} ha un valore che non può essere
+    usato come \ctyp{off\_t}.
+  \item[\errcode{ESPIPE}] \param{fd} è associato ad un socket o una pipe.
+  \end{errlist}
+}
+\end{functions}
+
+Le due funzioni eseguono rispettivamente una lettura o una scrittura
+vettorizzata a partire dalla posizione \param{offset} sul file indicato
+da \param{fd}, la posizione corrente sul file, come vista da eventuali altri
+processi che vi facciano riferimento, non viene alterata. A parte la presenza
+dell'ulteriore argomento il comportamento delle funzioni è identico alle
+precedenti \func{readv} e \func{writev}. 
+
+Con l'uso di queste funzioni si possono evitare eventuali
+\itindex{race~condition} \textit{race conditions} quando si deve eseguire la
+una operazione di lettura e scrittura vettorizzata a partire da una certa
+posizione su un file, mentre al contempo si possono avere in concorrenza
+processi che utilizzano lo stesso file descriptor (si ricordi quanto visto in
+sez.~\ref{sec:file_adv_func}) con delle chiamate a \func{lseek}.
+
 
 
 \subsection{L'I/O diretto fra file descriptor: \func{sendfile} e
@@ -3798,15 +3952,15 @@ efficiente mantenere tutto in kernel space. Tratteremo in questa sezione
 alcune funzioni specialistiche che permettono di ottimizzare le prestazioni in
 questo tipo di situazioni.
 
-La prima funzione che si pone l'obiettivo di ottimizzare il trasferimento dei
-dati fra due file descriptor è \funcd{sendfile};\footnote{la funzione è stata
+La prima funzione che è stata ideata per ottimizzare il trasferimento dei dati
+fra due file descriptor è \func{sendfile};\footnote{la funzione è stata
   introdotta con i kernel della serie 2.2, e disponibile dalle \acr{glibc}
   2.1.} la funzione è presente in diverse versioni di Unix,\footnote{la si
   ritrova ad esempio in FreeBSD, HPUX ed altri Unix.} ma non è presente né in
 POSIX.1-2001 né in altri standard,\footnote{pertanto si eviti di utilizzarla
   se si devono scrivere programmi portabili.} per cui per essa vengono
-utilizzati prototipi e semantiche differenti; nel caso di Linux il suo
-prototipo è:
+utilizzati prototipi e semantiche differenti; nel caso di Linux il prototipo
+di \funcd{sendfile} è:
 \begin{functions}  
   \headdecl{sys/sendfile.h} 
 
@@ -3835,7 +3989,7 @@ prototipo 
 La funzione copia direttamente \param{count} byte dal file descriptor
 \param{in\_fd} al file descriptor \param{out\_fd}; in caso di successo
 funzione ritorna il numero di byte effettivamente copiati da \param{in\_fd} a
-\param{out\_fd} o $-1$ in caso di errore, come le ordinarie \func{read} e
+\param{out\_fd} o $-1$ in caso di errore; come le ordinarie \func{read} e
 \func{write} questo valore può essere inferiore a quanto richiesto con
 \param{count}.
 
@@ -3883,19 +4037,16 @@ non 
 casi l'uso di \func{sendfile} darà luogo ad un errore di \errcode{EINVAL}.
 
 Nonostante ci possano essere casi in cui \func{sendfile} non migliora le
-prestazioni, le motivazioni addotte non convincono del tutto e resta il dubbio
-se la scelta di disabilitarla sempre per il trasferimento di dati fra file di
-dati sia davvero corretta. Se ci sono peggioramenti di prestazioni infatti si
-può sempre fare ricorso all'uso successivo di, ma lasciare a disposizione la
-funzione consentirebbe se non altro, anche in assenza di guadagni di
-prestazioni, di semplificare la gestione della copia dei dati fra file,
-evitando di dover gestire l'allocazione di un buffer temporaneo per il loro
-trasferimento; inoltre si avrebbe comunque il vantaggio di evitare inutili
-trasferimenti di dati da kernel space a user space e viceversa.
-
-Questo dubbio si può comunque ritenere superato con l'introduzione, avvenuto a
-partire dal kernel 2.6.17, della nuova system call \func{splice}. Lo scopo di
-questa funzione è quello di fornire un meccanismo generico per il
+prestazioni, resta il dubbio se la scelta di disabilitarla sempre per il
+trasferimento fra file di dati sia davvero corretta. Se ci sono peggioramenti
+di prestazioni infatti si può sempre fare ricorso al metodo ordinario, ma
+lasciare a disposizione la funzione consentirebbe se non altro di semplificare
+la gestione della copia dei dati fra file, evitando di dover gestire
+l'allocazione di un buffer temporaneo per il loro trasferimento.
+
+Questo dubbio si può comunque ritenere superato con l'introduzione, avvenuta a
+partire dal kernel 2.6.17, della nuova \textit{system call} \func{splice}. Lo
+scopo di questa funzione è quello di fornire un meccanismo generico per il
 trasferimento di dati da o verso un file utilizzando un buffer gestito
 internamente dal kernel. Descritta in questi termini \func{splice} sembra
 semplicemente un ``\textsl{dimezzamento}'' di \func{sendfile}.\footnote{nel
@@ -4057,16 +4208,17 @@ descrizioni complete di tutti i valori possibili anche quando, come per
   \label{tab:splice_flag}
 \end{table}
 
-\footnotetext{per una maggiore efficienza \func{splice} usa quando possibile i
-  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 copiate.}
+\footnotetext[120]{per una maggiore efficienza \func{splice} usa quando
+  possibile i 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 copiate.}
 
-\footnotetext{questa opzione consente di utilizzare delle opzioni di gestione
-  dei socket che permettono di ottimizzare le trasmissioni via rete, si veda
-  la descrizione di \const{TCP\_CORK} in sez.~\ref{sec:sock_tcp_udp_options} e
-  quella di \const{MSG\_MORE} in sez.~\ref{sec:net_sendmsg}.}
+\footnotetext[121]{questa opzione consente di utilizzare delle opzioni di
+  gestione dei socket che permettono di ottimizzare le trasmissioni via rete,
+  si veda la descrizione di \const{TCP\_CORK} in
+  sez.~\ref{sec:sock_tcp_udp_options} e quella di \const{MSG\_MORE} in
+  sez.~\ref{sec:net_sendmsg}.}
 
 \footnotetext{questo significa che la cache delle pagine e i dati su disco
   potranno differire, e che l'applicazione non potrà modificare quest'area di
@@ -4172,7 +4324,8 @@ descriptor, le tratteremo qui.
 
 La prima funzione, \funcd{vmsplice}, è la più simile a \func{splice} e come
 indica il suo nome consente di trasferire i dati dalla memoria di un processo
-verso una \textit{pipe}, il suo prototipo è:
+(ad esempio per un file mappato in memoria) verso una \textit{pipe}, il suo
+prototipo è:
 \begin{functions}  
   \headdecl{fcntl.h} 
   \headdecl{sys/uio.h}
@@ -4196,21 +4349,25 @@ verso una \textit{pipe}, il suo prototipo 
   }
 \end{functions}
 
-La \textit{pipe} dovrà essere specificata tramite il file descriptor
-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 suddetto vettore devono essere passate
+La \textit{pipe} indicata da \param{fd} dovrà essere specificata tramite il
+file descriptor 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 dovrà utilizzare un vettore di
+strutture \struct{iovec} (vedi fig.~\ref{fig:file_iovec}), esattamente con gli
+stessi criteri con cui le si usano per l'I/O vettorizzato, indicando gli
+indirizzi e le dimensioni di ciascun segmento di memoria su cui si vuole
+operare; 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}.
 
 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 indirizzi del
-processo, e scaricarle nella cache, così che queste possono essere utilizzate
+\textit{pipe}. In generale, se i dati una volta creati non devono essere
+riutilizzati (se cioè l'applicazione che chiama \func{vmsplice} non
+modificherà più la memoria trasferita), è opportuno utilizzare
+per \param{flag} il valore \const{SPLICE\_F\_GIFT}; questo fa sì che il 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.
 
 La seconda funzione aggiunta insieme a \func{splice} è \func{tee}, che deve il
@@ -4331,6 +4488,8 @@ questa sezione una serie funzioni che consentono ai programmi di ottimizzare
 il loro accesso ai dati dei file e controllare la gestione del relativo
 \textit{caching}.
 
+\itindbeg{read-ahead}
+
 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
@@ -4364,12 +4523,12 @@ La funzione richiede che venga letto in anticipo il contenuto del file
 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
+La funzione estende quello che è un comportamento normale del kernel che
+quando si legge un file, aspettandosi che l'accesso prosegua, esegue sempre
+una lettura preventiva di una certa quantità di dati; questo meccanismo di
+lettura anticipata viene chiamato \textit{read-ahead}, da cui deriva il nome
+della funzione. La funzione, per ottimizzare gli accessi a disco, effettua la
+lettura in cache della sezione richiesta e si blocca 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.
@@ -4380,6 +4539,8 @@ dati saranno necessari in seguito. Si potr
 momento (ad esempio in fase di inizializzazione) la lettura, così da ottenere
 una migliore risposta nelle operazioni successive.
 
+\itindend{read-ahead}
+
 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}
@@ -4417,9 +4578,13 @@ valore nullo la regione coperta sar
 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.
+illustrati in tab.~\ref{tab:posix_fadvise_flag}, che riprendono il significato
+degli analoghi già visti in sez.~\ref{sec:file_memory_map} per
+\func{madvise}.\footnote{dato che si tratta dello stesso tipo di funzionalità,
+  in questo caso applicata direttamente al sistema ai contenuti di un file
+  invece che alla sua mappatura in memoria.} 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
@@ -4444,17 +4609,17 @@ kernel, che utilizza semplicemente l'informazione.
     \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
+  \caption{Valori delle costanti usabili per l'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
+Come \func{madvise} anche \func{posix\_fadvise} si appoggia al sistema della
+memoria virtuale ed al meccanismo standard del \textit{read-ahead} 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
@@ -4462,13 +4627,14 @@ immediatamente successivi gli attuali; infine l'uso 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}.
+fino al kernel 2.6.18 erano equivalenti, a partire da questo kernel la prima
+viene non ha più alcune effetto, mentre la seconda dà 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.
@@ -4531,6 +4697,41 @@ mancanza di spazio disco.
 % http://kernelnewbies.org/Linux_2_6_23
 % \func{fallocate} con il 2.6.25 supporta pure XFS
 
+Infine a partire dal kernel 2.6.23 è stata introdotta la nuova system call
+\funcd{fallocate}, che consente di realizzare direttamente all'interno del
+kernel le funzionalità di \func{posix\_fallocate}. Trattandosi di una funzione
+di servizio questa non è stata definita come funzione di libreria e pertanto
+può essere invocata indirettamente con l'ausilio di \func{syscall} (vedi
+sez.~\ref{sec:intro_syscall}; il suo prototipo è:
+
+\begin{functions}
+  \headdecl{linux/falloc.h}
+  \funcdecl{long fallocate(int fd, int mode, loff\_t offset, loff\_t len)}
+
+  Prealloca dello spazio disco per un file.
+  
+  \bodydesc{La funzione ritorna 0 in caso di successo e $-1$ in caso di errore,
+    nel qual caso \var{errno} può assumere i valori:
+    \begin{errlist}
+    \item[\errcode{EBADF}] \param{fd} non fa riferimento ad un file descriptor
+      valido aperto in scrittura.
+    \item[\errcode{EFBIG}] la somma di \param{offset} e \param{len} eccede le
+      dimensioni massime di un file. 
+    \item[\errcode{EINVAL}] \param{offset} è minore di zero o \param{len} è
+      minore o uguale a zero. 
+    \item[\errcode{ENODEV}] \param{fd} non fa riferimento ad un file ordinario
+      o a una directory. 
+    \item[\errcode{ENOSPC}] non c'è spazio disco sufficiente per l'operazione. 
+    \item[\errcode{ENOSYS}] il filesystem contenente il file associato
+      a \param{fd} non supporta \func{fallocate}.
+    \item[\errcode{EOPNOTSUPP}] il filesystem contenente il file associato
+      a \param{fd} non supporta l'operazione \param{mode}.
+  \end{errlist} 
+  ed inoltre \errval{EINTR}, \errval{EIO}.
+}
+\end{functions}
+
+
 
 %\subsection{L'utilizzo delle porte di I/O}
 %\label{sec:file_io_port}
@@ -4590,6 +4791,8 @@ mancanza di spazio disco.
 % LocalWords:  Jens Anxboe vmsplice seek ESPIPE GIFT TCP CORK MSG splicecp nr
 % LocalWords:  nwrite segs patch readahead posix fadvise TC advice FADV NORMAL
 % LocalWords:  SEQUENTIAL NOREUSE WILLNEED DONTNEED streaming fallocate EFBIG
+% LocalWords:  POLLRDHUP half close pwait Gb madvise MADV ahead REMOVE tmpfs
+% LocalWords:  DONTFORK DOFORK shmfs preadv pwritev syscall linux loff
 
 
 %%% Local Variables: