Materiale su {{{posix_fallocate}}} e correzioni a {{{posix_fadvise}}}
authorSimone Piccardi <piccardi@gnulinux.it>
Tue, 28 Aug 2007 13:18:03 +0000 (13:18 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Tue, 28 Aug 2007 13:18:03 +0000 (13:18 +0000)
fileadv.tex
fileunix.tex

index d10d6f29bdef34fc36101e4a9ca42d5435a5270f..346fc454499a592999383f1c03ef8be8f7ab8f60 100644 (file)
@@ -3363,18 +3363,18 @@ 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 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 modo da riempire la memoria
-di cache, così che le seguenti operazioni di lettura non debbano bloccarsi
-nell'I/O su disco, il suo prototipo è:
-\begin{functions}  
-  \headdecl{fcntl.h} 
+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)}
   
-  Legge il contenuto di un file nella cache di memoria.
+  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:
@@ -3387,18 +3387,23 @@ nell'I/O su disco, il suo prototipo 
   }
 \end{functions}
 
-La funzione richiede che sul file \param{fd}, a partire dalla posizione
-\param{offset}, venga letto in anticipo il contenuto, portandolo nella cache
-della memoria virtuale, per un ammontare di \param{count} bytes. La funzione
-usa la memoria virtuale ed il meccanismo della paginazione per cui la lettura
-verrà eseguita in blocchi corrispondenti alle dimensioni delle pagine di
-memoria, ed i valori di \param{offset} e \param{count} arrotondati di
-conseguenza. 
-
-La funzione esegue la lettura bloccandosi fintanto che questa non viene
-completata. La posizione corrente sul file non viene modificata ed
+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} bytes, 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.
+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
@@ -3412,7 +3417,7 @@ POSIX.1-2001 dalla funzione \funcd{posix\_fadvise},\footnote{anche se
   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
+  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}  
@@ -3430,9 +3435,9 @@ definisce la macro \macro{\_XOPEN\_SOURCE} ad almeno 600, 
     \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).
-    \end{errlist}
     \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}
 
@@ -3455,27 +3460,101 @@ kernel, che utilzza semplicemente l'informazione.
     \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} & .\\ 
-    \const{POSIX\_FADV\_RANDOM} & .\\ 
-    \const{POSIX\_FADV\_NOREUSE} & .\\ 
-    \const{POSIX\_FADV\_WILLNEED} & .\\ 
-    \const{POSIX\_FADV\_DONTNEED} & .\\ 
+    \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 spercificati in maniera
+                                   sequenziale, a partire dalle posizioni più
+                                   basse.\\ 
+    \const{POSIX\_FADV\_RANDOM}  & I dati saranno letti in maniera
+                                   completamete 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.} 
+    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, apettandosi
+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 di 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}
+
+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 inidicata non fallirà per
+mancanza di spazio disco.
+
+
 % TODO documentare \func{posix\_fadvise}
-% TODO documentare \func{readahead}
 % vedi http://insights.oetiker.ch/linux/fadvise.html
 % questo tread? http://www.ussg.iu.edu/hypermail/linux/kernel/0703.1/0032.html
 
index bf476ee45b6be8d6a0dfbf8813e967caf2eb70f0..1901208d33ba745733757f0f77204e9788240565 100644 (file)
@@ -561,9 +561,9 @@ essersi spostata, ma noi scriveremo alla posizione impostata in precedenza
   condition}, vedi sez.~\ref{sec:file_atomic}).
 
 Non tutti i file supportano la capacità di eseguire una \func{lseek}, in
-questo caso la funzione ritorna l'errore \errcode{EPIPE}. Questo, oltre che per
-i tre casi citati nel prototipo, vale anche per tutti quei dispositivi che non
-supportano questa funzione, come ad esempio per i file di
+questo caso la funzione ritorna l'errore \errcode{ESPIPE}. Questo, oltre che
+per i tre casi citati nel prototipo, vale anche per tutti quei dispositivi che
+non supportano questa funzione, come ad esempio per i file di
 terminale.\footnote{altri sistemi, usando \const{SEEK\_SET}, in questo caso
   ritornano il numero di caratteri che vi sono stati scritti.} Lo standard
 POSIX però non specifica niente in proposito. Infine alcuni file speciali, ad