Molte correzioni ed risistemazioni indici. Inizio trattazione dei
[gapil.git] / fileadv.tex
index 97249198be36d745d604947117032ff1c642b114..38bd320f168b551fed88b316b62baf50e2f81272 100644 (file)
@@ -1,6 +1,6 @@
 %% fileadv.tex
 %%
-%% Copyright (C) 2000-2009 Simone Piccardi.  Permission is granted to
+%% Copyright (C) 2000-2010 Simone Piccardi.  Permission is granted to
 %% copy, distribute and/or modify this document under the terms of the GNU Free
 %% Documentation License, Version 1.1 or any later version published by the
 %% Free Software Foundation; with the Invariant Sections being "Un preambolo",
@@ -2076,7 +2076,7 @@ kernel 
 \textit{lease breaker} rimaste bloccate proseguono automaticamente.
 
 
-\index{file!dnotify|(}
+\itindbeg{dnotify}
 
 Benché possa risultare utile per sincronizzare l'accesso ad uno stesso file da
 parte di più processi, l'uso dei \textit{file lease} non consente comunque di
@@ -2154,7 +2154,7 @@ specificate in chiamate successive vengono aggiunte a quelle gi
 nelle precedenti.  Se si vuole rimuovere la notifica si deve invece
 specificare un valore nullo.
 
-\index{file!inotify|(}
+\itindbeg{inotify}
 
 Il maggiore problema di \textit{dnotify} è quello della scalabilità: si deve
 usare un file descriptor per ciascuna directory che si vuole tenere sotto
@@ -2174,7 +2174,7 @@ 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.
 
-\index{file!dnotify|)}
+\itindend{dnotify}
 
 Per risolvere i problemi appena illustrati è stata introdotta una nuova
 interfaccia per l'osservazione delle modifiche a file o directory, chiamata
@@ -2656,7 +2656,7 @@ verificano pi
 dei campi \var{wd}, \var{mask}, \var{cookie}, e \var{name}) questi vengono
 raggruppati in un solo evento.
 
-\index{file!inotify|)}
+\itindend{inotify}
 
 % TODO trattare fanotify, vedi http://lwn.net/Articles/339399/ e 
 % http://lwn.net/Articles/343346/ 
@@ -2736,17 +2736,6 @@ come vedremo, permette di eseguire con una sola chiamata una serie di
 operazioni, usando un vettore di \textit{control block}. Tramite questo campo
 si specifica quale è la natura di ciascuna di esse.
 
-\begin{figure}[!htb]
-  \footnotesize \centering
-  \begin{minipage}[c]{15cm}
-    \includestruct{listati/sigevent.h}
-  \end{minipage} 
-  \normalsize 
-  \caption{La struttura \structd{sigevent}, usata per specificare le modalità
-    di notifica degli eventi relativi alle operazioni di I/O asincrono.}
-  \label{fig:file_sigevent}
-\end{figure}
-
 Infine il campo \var{aio\_sigevent} è una struttura di tipo \struct{sigevent}
 che serve a specificare il modo in cui si vuole che venga effettuata la
 notifica del completamento delle operazioni richieste. La struttura è
@@ -3927,7 +3916,7 @@ dell'ulteriore argomento il comportamento delle funzioni 
 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
+\itindex{race~condition} \textit{race condition} 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
@@ -4315,17 +4304,17 @@ anche se un valore nullo avrebbe dato gli stessi risultati, l'uso di questi
 flag, che si ricordi servono solo a dare suggerimenti al kernel, permette in
 genere di migliorare le prestazioni.
 
-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
+Come accennato con l'introduzione di \func{splice} sono state realizzate anche
+altre due \textit{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 trasferimento dati fra file
-descriptor, le tratteremo qui.
+descriptor, le tratteremo qui, essendo strettamente correlate fra loro.
 
 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
-(ad esempio per un file mappato in memoria) verso una \textit{pipe}, il suo
-prototipo è:
+indica il suo nome consente di trasferire i dati dalla memoria virtuale di un
+processo (ad esempio per un file mappato in memoria) verso una \textit{pipe};
+il suo prototipo è:
 \begin{functions}  
   \headdecl{fcntl.h} 
   \headdecl{sys/uio.h}
@@ -4351,24 +4340,25 @@ prototipo 
 
 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}.
+faccia riferimento a sez.~\ref{sec:ipc_unix}), mentre per indicare quali
+segmenti della memoria del processo devono essere trasferiti verso di essa 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
 \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.
+possa rimuovere le relative pagine dalla cache della memoria virtuale, 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
 suo nome all'omonimo comando in user space, perché in analogia con questo
@@ -4403,7 +4393,12 @@ sorgente e \param{fd\_out} il capo in scrittura della \textit{pipe}
 destinazione; a differenza di quanto avviene con \func{read} i dati letti con
 \func{tee} da \func{fd\_in} non vengono \textsl{consumati} e restano
 disponibili sulla \textit{pipe} per una successiva lettura (di nuovo per il
-comportamento delle \textit{pipe} si veda sez.~\ref{sec:ipc_unix}).
+comportamento delle \textit{pipe} si veda sez.~\ref{sec:ipc_unix}). Al
+momento\footnote{quello della stesura di questo paragrafo, avvenuta il Gennaio
+  2010, in futuro potrebbe essere implementato anche \const{SPLICE\_F\_MORE}.}
+il solo valore utilizzabile per \param{flag}, fra quelli elencati in
+tab.~\ref{tab:splice_flag}, è \const{SPLICE\_F\_NONBLOCK} che rende la
+funzione non bloccante.
 
 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
@@ -4521,35 +4516,37 @@ La funzione richiede che venga letto in anticipo il contenuto del file
 \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.
+\param{offset} e \param{count} vengono arrotondati di conseguenza.
 
 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.
+della funzione. La funzione \func{readahead}, 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.
 
 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.
+all'interno di un programma tutte le volte che si conosce in anticipo quanti
+dati saranno necessari nelle elaborazioni successive. Si potrà così
+concentrare in un unico momento (ad esempio in fase di inizializzazione) la
+lettura dei dati da disco, così da ottenere una migliore velocità di 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
+POSIX.1-2001 dalla funzione \func{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, è:
+opportune ottimizzazioni; il prototipo di \funcd{posix\_fadvise}, che è
+disponibile soltanto se è stata definita la macro \macro{\_XOPEN\_SOURCE} ad
+valore di almeno 600, è:
 \begin{functions}  
   \headdecl{fcntl.h} 
 
@@ -4617,18 +4614,18 @@ che utilizza semplicemente l'informazione.
 
 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
-\const{POSIX\_FADV\_NORMAL} consente di riportarsi al comportamento di
-default.
+dal kernel; in particolare utilizzando il valore
+\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}
 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
+viene non ha più alcun 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
@@ -4647,11 +4644,12 @@ nuovi dati utili.\footnote{la pagina di manuale riporta l'esempio dello
 
 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, è:
+specifica per le operazioni di scrittura,
+\funcd{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} 
 
@@ -4678,35 +4676,58 @@ macro \macro{\_XOPEN\_SOURCE} ad almeno 600, 
   }
 \end{functions}
 
-La funzione si assicura che venga allocato sufficiente spazio disco perché sia
+La funzione 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 controllare la trattazione della nuova funzionalità di preallocazione 
-
-% 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
-% \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 è:
-
+se questa regione 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 successiva scrittura nella regione
+indicata non fallirà per mancanza di spazio disco. La funzione non ha nessun
+effetto né sul contenuto, né sulla posizione corrente del file.
+
+Ci si può chiedere a cosa possa servire una funzione come
+\func{posix\_fallocate} dato che è sempre possibile ottenere l'effetto voluto
+eseguendo esplicitamente sul file la scrittura\footnote{usando \funcd{pwrite}
+  per evitare spostamenti della posizione corrente sul file.} di una serie di
+zeri per l'estensione di spazio necessaria qualora il \itindex{sparse~file}
+file debba essere esteso o abbia dei \index{file!\textit{hole}}
+buchi.\footnote{si ricordi che occorre scrivere per avere l'allocazione e che
+  l'uso di \func{truncate} per estendere un file creerebbe soltanto uno
+  \itindex{sparse~file} \textit{sparse file} (vedi sez.~\ref{sec:file_lseek})
+  senza una effettiva allocazione dello spazio disco.}  In realtà questa è la
+modalità con cui la funzione veniva realizzata nella prima versione fornita
+dalle \acr{glibc}, per cui la funzione costituiva in sostanza soltanto una
+standardizzazione delle modalità di esecuzione di questo tipo di allocazioni.
+
+Questo metodo, anche se funzionante, comporta però l'effettiva esecuzione una
+scrittura su tutto lo spazio disco necessario, da fare al momento della
+richiesta di allocazione, pagandone il conseguente prezzo in termini di
+prestazioni; il tutto quando in realtà servirebbe solo poter riservare lo
+spazio per poi andarci a scrivere, una sola volta, quando il contenuto finale
+diventa effettivamente disponibile.
+
+Per poter fare tutto questo è però necessario il supporto da parte del kernel,
+e questo è divenuto disponibile solo a partire dal kernel 2.6.23 in cui è
+stata introdotta la nuova \textit{system call} \func{fallocate},\footnote{non
+  è detto che la funzione sia disponibile per tutti i filesystem, ad esempio
+  per XFS il supporto è stato introdotto solo a partire dal kernel 2.6.25.}
+che consente di realizzare direttamente all'interno del kernel l'allocazione
+dello spazio disco così da poter realizzare una versione di
+\func{posix\_fallocate} con prestazioni molto più elevate.\footnote{nelle
+  \acr{glibc} la nuova \textit{system call} viene sfruttata per la
+  realizzazione di \func{posix\_fallocate} a partire dalla versione 2.10.}
+
+Trattandosi di una funzione di servizio, ed ovviamente disponibile
+esclusivamente su Linux, inizialmente \funcd{fallocate} non era stata definita
+come funzione di libreria,\footnote{pertanto poteva essere invocata soltanto
+  in maniera indiretta con l'ausilio di \func{syscall}, vedi
+  sez.~\ref{sec:intro_syscall}, come \code{long fallocate(int fd, int mode,
+      loff\_t offset, loff\_t len)}.} ma a partire dalle \acr{glibc} 2.10 è
+  stato fornito un supporto esplicito; il suo prototipo è:
 \begin{functions}
-  \headdecl{linux/falloc.h}
-  \funcdecl{long fallocate(int fd, int mode, loff\_t offset, loff\_t len)}
+  \headdecl{linux/fcntl.h} 
+
+  \funcdecl{int fallocate(int fd, int mode, off\_t offset, off\_t len)}
 
   Prealloca dello spazio disco per un file.
   
@@ -4731,6 +4752,25 @@ sez.~\ref{sec:intro_syscall}; il suo prototipo 
 }
 \end{functions}
 
+La funzione prende gli stessi argomenti di \func{posix\_fallocate} con lo
+stesso significato, a cui si aggiunge l'argomento \param{mode} che indica le
+modalità di allocazione; al momento quest'ultimo può soltanto essere nullo o
+assumere il valore \const{FALLOC\_FL\_KEEP\_SIZE} che richiede che la
+dimensione del file\footnote{quella ottenuta nel campo \var{st\_size} di una
+  struttura \struct{stat} dopo una chiamata a \texttt{fstat}.} non venga
+modificata anche quando la somma di \param{offset} e \param{len} eccede la
+dimensione corrente. 
+
+Se \param{mode} è nullo invece la dimensione totale del file in caso di
+estensione dello stesso viene aggiornata, come richiesto per
+\func{posix\_fallocate}, ed invocata in questo modo si può considerare
+\func{fallocate} come l'implementazione ottimale di \func{posix\_fallocate} a
+livello di kernel.
+
+% 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}
@@ -4770,7 +4810,7 @@ sez.~\ref{sec:intro_syscall}; il suo prototipo 
 % LocalWords:  only ETXTBSY DENYWRITE ENODEV filesystem EPERM EXEC noexec table
 % LocalWords:  ENFILE lenght segment violation SIGSEGV FIXED msync munmap copy
 % LocalWords:  DoS Denial Service EXECUTABLE NORESERVE LOCKED swapping stack fs
-% LocalWords:  GROWSDOWN ANON GiB POPULATE prefaulting SIGBUS fifo VME fork old
+% LocalWords:  GROWSDOWN ANON POPULATE prefaulting SIGBUS fifo VME fork old
 % LocalWords:  exec atime ctime mtime mprotect addr EACCESS mremap address new
 % LocalWords:  long MAYMOVE realloc VMA virtual Ingo Molnar remap pages pgoff
 % LocalWords:  dall' fault cache linker prelink advisory discrectionary lock fl
@@ -4792,7 +4832,8 @@ sez.~\ref{sec:intro_syscall}; il suo prototipo 
 % 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
+% LocalWords:  DONTFORK DOFORK shmfs preadv pwritev syscall linux loff head XFS
+% LocalWords:  MERGEABLE EOVERFLOW prealloca hole FALLOC KEEP stat fstat
 
 
 %%% Local Variables: