Correzioni varie ed aggiuno O_DIRECT
authorSimone Piccardi <piccardi@gnulinux.it>
Wed, 9 Mar 2005 11:44:39 +0000 (11:44 +0000)
committerSimone Piccardi <piccardi@gnulinux.it>
Wed, 9 Mar 2005 11:44:39 +0000 (11:44 +0000)
fileunix.tex

index 3e9560c152a08eaa7b54840f956f688bacae58f5..c0305b73ac7290d250e2a3e9f35d0be8c5749b46 100644 (file)
@@ -91,6 +91,11 @@ file, fra cui:
 In fig.~\ref{fig:file_proc_file} si è riportato uno schema in cui è illustrata
 questa architettura, ed in cui si sono evidenziate le interrelazioni fra le
 varie strutture di dati sulla quale essa è basata.
+Ritorneremo su questo schema più volte, dato che esso è fondamentale per
+capire i dettagli del funzionamento dell'interfaccia dei \textit{file
+  descriptor}.  
+\index{file!descriptor|)}
+
 \begin{figure}[htb]
   \centering
   \includegraphics[width=13cm]{img/procfile}
@@ -98,11 +103,6 @@ varie strutture di dati sulla quale essa 
   l'interfaccia dei \textit{file descriptor}.}
   \label{fig:file_proc_file}
 \end{figure}
-Ritorneremo su questo schema più volte, dato che esso è fondamentale per
-capire i dettagli del funzionamento dell'interfaccia dei \textit{file
-  descriptor}.  
-\index{file!descriptor|)}
-
 
 
 
@@ -115,22 +115,22 @@ assegnati in successione tutte le volte che si apre un nuovo file (se non ne 
 stato chiuso nessuno in precedenza).
 
 In tutti i sistemi unix-like esiste una convenzione generale per cui ogni
-processo viene lanciato con almeno tre file aperti. Questi, per quanto appena
-detto, avranno come \textit{file descriptor}\index{file!descriptor} i valori
-0, 1 e 2.  Benché questa sia soltanto una convenzione, essa è seguita dalla
-gran parte delle applicazioni, e non aderirvi potrebbe portare a gravi
-problemi di interoperabilità.
+processo viene lanciato dalla shell con almeno tre file aperti. Questi, per
+quanto appena detto, avranno come \textit{file
+  descriptor}\index{file!descriptor} i valori 0, 1 e 2.  Benché questa sia
+soltanto una convenzione, essa è seguita dalla gran parte delle applicazioni,
+e non aderirvi potrebbe portare a gravi problemi di interoperabilità.
 
 Il primo file è sempre associato al cosiddetto \textit{standard input}; è cioè
-il file da cui il processo si aspetta di ricevere i dati in ingresso (nel caso
-della shell, è associato all'input del terminale, cioè alla lettura della
-tastiera). Il secondo file è il cosiddetto \textit{standard output}, cioè
-quello su cui ci si aspetta debbano essere inviati i dati in uscita (sempre
-nel caso della shell, è associato all'output del terminale, cioè alla
-scrittura sullo schermo). Il terzo è lo \textit{standard error}, su cui viene
-inviata l'uscita relativa agli errori, ed è anch'esso associato al terminale.
-Lo standard POSIX.1 provvede, al posto di questi valori numerici, tre costanti
-simboliche, definite in tab.~\ref{tab:file_std_files}.
+il file da cui il processo si aspetta di ricevere i dati in ingresso. Il
+secondo file è il cosiddetto \textit{standard output}, cioè quello su cui ci
+si aspetta debbano essere inviati i dati in uscita. Il terzo è lo
+\textit{standard error}, su cui viene inviata l'uscita relativa agli errori.
+Nel caso della shell tutti questi file sono associati al terminale di
+controllo, e corrispondono quindi alla lettura della tastiera per l'ingresso e
+alla scrittura sul terminale per l'uscita.  Lo standard POSIX.1 provvede, al
+posto dei valori numerici, tre costanti simboliche, definite in
+tab.~\ref{tab:file_std_files}.
 
 \begin{table}[htb]
   \centering
@@ -175,12 +175,10 @@ sez.~\ref{sec:sys_limits}).
 L'interfaccia standard Unix per l'input/output sui file è basata su cinque
 funzioni fondamentali: \func{open}, \func{read}, \func{write}, \func{lseek} e
 \func{close}, usate rispettivamente per aprire, leggere, scrivere, spostarsi e
-chiudere un file. 
-
-La gran parte delle operazioni sui file si effettua attraverso queste cinque
-funzioni, esse vengono chiamate anche funzioni di I/O non bufferizzato dato
-che effettuano le operazioni di lettura e scrittura usando direttamente le
-system call del kernel.
+chiudere un file.  La gran parte delle operazioni sui file si effettua
+attraverso queste cinque funzioni, esse vengono chiamate anche funzioni di I/O
+non bufferizzato dato che effettuano le operazioni di lettura e scrittura
+usando direttamente le system call del kernel.
 
 
 \subsection{La funzione \func{open}}
@@ -229,7 +227,8 @@ prototipo 
 
 La funzione apre il file, usando il primo file descriptor libero, e crea
 l'opportuna voce (cioè la struttura \struct{file}) nella \textit{file table}.
-Viene usato sempre il file descriptor con il valore più basso.
+Viene sempre restituito come valore di ritorno il file descriptor con il
+valore più basso disponibile.
 
 \begin{table}[!htb]
   \centering
@@ -239,17 +238,19 @@ Viene usato sempre il file descriptor con il valore pi
     \textbf{Flag} & \textbf{Descrizione} \\
     \hline
     \hline % modalità di accesso al file
-    \const{O\_RDONLY} & apre il file in sola lettura. \\
-    \const{O\_WRONLY} & apre il file in sola scrittura. \\
-    \const{O\_RDWR} & apre il file in lettura/scrittura. \\
+    \const{O\_RDONLY} & apre il file in sola lettura, le \acr{glibc}
+                        definiscono anche \const{O\_READ} come sinonimo. \\
+    \const{O\_WRONLY} & apre il file in sola scrittura, le \acr{glibc}
+                        definiscono anche \const{O\_WRITE} come sinonimo. \\
+    \const{O\_RDWR} & apre il file sia in lettura che in scrittura. \\
     \hline % modalità di apertura del file
     \hline
     \const{O\_CREAT} & se il file non esiste verrà creato, con le regole di
                        titolarità del file viste in
-                       sez.~\ref{sec:file_ownership}. L'argomento 
-                       \param{mode} deve essere specificato. \\
+                       sez.~\ref{sec:file_ownership}. Con questa opzione
+                       l'argomento \param{mode} deve essere specificato. \\
     \const{O\_EXCL}  & usato in congiunzione con \const{O\_CREAT} fa sì che
-                       l'esistenza del file diventi un
+                       la precedente esistenza del file diventi un
                        errore\protect\footnotemark\ che fa fallire
                        \func{open} con \errcode{EEXIST}. \\ 
     \const{O\_NONBLOCK}& apre il file in modalità non bloccante. Questo
@@ -292,9 +293,9 @@ Viene usato sempre il file descriptor con il valore pi
     \hline  % modalità di operazione col file
     \const{O\_APPEND} & il file viene aperto in append mode. Prima di ciascuna
                         scrittura la posizione corrente viene sempre impostata
-                        alla fine del file. Può causare corruzione del file
-                        con NFS se più di un processo scrive allo stesso
-                        tempo.\footnotemark\\ 
+                        alla fine del file. Con NFS si può avere una
+                        corruzione del file se più di un processo scrive allo
+                        stesso tempo.\footnotemark\\ 
     \const{O\_NONBLOCK}&il file viene aperto in modalità non bloccante per
                         le operazioni di I/O (che tratteremo in
                         sez.~\ref{sec:file_noblocking}): questo significa il
@@ -313,11 +314,28 @@ Viene usato sempre il file descriptor con il valore pi
     \const{O\_SYNC} &   apre il file per l'input/output sincrono: ogni
                         \func{write} bloccherà fino al completamento della
                         scrittura di tutti i dati sull'hardware sottostante.\\ 
-    \const{O\_FSYNC} &  sinonimo di \const{O\_SYNC}. \\
+    \const{O\_FSYNC} &  sinonimo di \const{O\_SYNC}, usato da BSD. \\
+    \const{O\_DSYNC} &  richiede una variante di I/O sincorno definita nello
+                        standard POSIX; definita a partire dal kernel 2.1.130
+                        come sinonimo di \const{O\_SYNC}. \\ 
+    \const{O\_RSYNC} &  richiede una variante di I/O sincorno definita nello
+                        standard POSIX; definita a partire dal kernel 2.1.130
+                        come sinonimo di \const{O\_SYNC}. \\
     \const{O\_NOATIME}& blocca l'aggiornamento dei tempi di accesso dei
                         file (vedi sez.~\ref{sec:file_file_times}). Per molti
                         filesystem questa funzionalità non è disponibile per
-                        il singolo file ma come opzione in fase di montaggio.\\
+                        il singolo file ma come opzione generale da
+                        specificare in fase di montaggio.\\
+    \const{O\_DIRECT} & esegue l'I/O direttamente dai buffer in user space, ed
+                        in maniera sincrona, in modo da scavalcare i
+                        meccanismi di caching del kernel. In gebere questo
+                        peggiora le prestazioni tranne per casi speciali in
+                        cui sono le applicazioni\footnotemark a gestire il
+                        caching. Per i kernel della serie 2.4 si deve
+                        garantire che i buffer in user space siano allineati
+                        alle dimensioni dei blocchi del filesystem; per il
+                        kernel 2.6 basta che siano allineati a multipli di 512
+                        byte.\\
     \hline
   \end{tabular}
   \caption{Valori e significato dei vari bit del \textit{file status flag}.}
@@ -345,16 +363,26 @@ Viene usato sempre il file descriptor con il valore pi
   un'ambiguità, dato che come vedremo in sez.~\ref{sec:file_read} il ritorno di
   zero da parte di \func{read} ha il significato di una end-of-file.}
 
+\footnotetext[6]{l'opzione è stata introdotta dalla SGI in IRIX, e serve
+  sostanzialmente a permettere ad alcuni programmi (in genere database) la
+  gestione diretta della bufferizzazione dell'I/O in quanto essi sono in grado
+  di ottimizzarla al meglio per le loro prestazioni; l'opzione è presente
+  anche in FreeBSD, senza limiti di allineamento dei buffer. In Linux è stata
+  introdotta con il kernel 2.4.10, le versioni precedenti la ignorano.}
+
+
 Questa caratteristica permette di prevedere qual'è il valore del file
 descriptor che si otterrà al ritorno di \func{open}, e viene talvolta usata da
 alcune applicazioni per sostituire i file corrispondenti ai file standard
 visti in sez.~\ref{sec:file_std_descr}: se ad esempio si chiude lo standard
 input e si apre subito dopo un nuovo file questo diventerà il nuovo standard
-input (avrà cioè il file descriptor 0).  Il nuovo file descriptor non è
-condiviso con nessun altro processo (torneremo sulla condivisione dei file, in
-genere accessibile dopo una \func{fork}, in sez.~\ref{sec:file_sharing}) ed è
-impostato per restare aperto attraverso una \func{exec} (come accennato in
-sez.~\ref{sec:proc_exec}); l'offset è impostato all'inizio del file.
+input (avrà cioè il file descriptor 0).  
+
+Il nuovo file descriptor non è condiviso con nessun altro processo (torneremo
+sulla condivisione dei file, in genere accessibile dopo una \func{fork}, in
+sez.~\ref{sec:file_sharing}) ed è impostato per restare aperto attraverso una
+\func{exec} (come accennato in sez.~\ref{sec:proc_exec}); l'offset è impostato
+all'inizio del file.
 
 L'argomento \param{mode} indica i permessi con cui il file viene creato; i
 valori possibili sono gli stessi già visti in sez.~\ref{sec:file_perm_overview}
@@ -584,19 +612,21 @@ con un numero di byte inferiore a quelli richiesti.
 Lo stesso comportamento avviene caso di lettura dalla rete (cioè su un
 socket\index{socket}, come vedremo in sez.~\ref{sec:sock_io_behav}), o per la
 lettura da certi file di dispositivo, come le unità a nastro, che
-restituiscono sempre i dati ad un singolo blocco alla volta.  
-
-In realtà anche le due condizioni segnalate dagli errori \errcode{EINTR} e
-\errcode{EAGAIN} non sono errori. La prima si verifica quando la \func{read} è
-bloccata in attesa di dati in ingresso e viene interrotta da un segnale; in
-tal caso l'azione da intraprendere è quella di rieseguire la funzione.
-Torneremo in dettaglio sull'argomento in sez.~\ref{sec:sig_gen_beha}.  La
-seconda si verifica quando il file è in modalità non bloccante (vedi
-sez.~\ref{sec:file_noblocking}) e non ci sono dati in ingresso: la funzione
-allora ritorna immediatamente con un errore \errcode{EAGAIN}\footnote{BSD usa
-  per questo errore la costante \errcode{EWOULDBLOCK}, in Linux, con le
-  \acr{glibc}, questa è sinonima di \errcode{EAGAIN}.} che indica soltanto che
-occorrerà provare a ripetere la lettura.
+restituiscono sempre i dati ad un singolo blocco alla volta, o come le linee
+seriali, che restituiscono solo i dati ricevuti fino al momento della lettura.
+
+Infine anche le due condizioni segnalate dagli errori \errcode{EINTR} ed
+\errcode{EAGAIN} non sono propriamente degli errori. La prima si verifica
+quando la \func{read} è bloccata in attesa di dati in ingresso e viene
+interrotta da un segnale; in tal caso l'azione da intraprendere è quella di
+rieseguire la funzione.  Torneremo in dettaglio sull'argomento in
+sez.~\ref{sec:sig_gen_beha}.  La seconda si verifica quando il file è aperto
+in modalità non bloccante (vedi sez.~\ref{sec:file_noblocking}) e non ci sono
+dati in ingresso: la funzione allora ritorna immediatamente con un errore
+\errcode{EAGAIN}\footnote{BSD usa per questo errore la costante
+  \errcode{EWOULDBLOCK}, in Linux, con le \acr{glibc}, questa è sinonima di
+  \errcode{EAGAIN}.} che indica soltanto che non essendoci al momento dati
+disponibili occorre provare a ripetere la lettura in un secondo tempo.
 
 La funzione \func{read} è una delle system call fondamentali, esistenti fin
 dagli albori di Unix, ma nella seconda versione delle \textit{Single Unix
@@ -617,24 +647,35 @@ posizione \param{offset}, nel buffer \param{buf}.
   in caso di errore, nel qual caso \var{errno} assumerà i valori già visti per
   \func{read} e \func{lseek}.}
 \end{prototype}
-\noindent che però diventa accessibile solo con la definizione della macro:
+
+La funzione prende esattamente gli stessi argomenti di \func{read} con lo
+stesso significato, a cui si aggiunge l'argomento \func{offset} che indica una
+posizione sul file. Indetico è il comportamento ed il valore di ritorno. La
+funzione serve quando si vogliono leggere dati dal file senza modificare la
+posizione corrente.
+
+L'uso di \func{pread} è equivalente all'esecuzione di una \func{read} seguita
+da una \func{lseek} che riporti al valore precedente la posizione corrente sul
+file, ma permette di eseguire l'operazione atomicamente. Questo può essere
+importante quando la posizione sul file viene condivisa da processi diversi
+(vedi sez.~\ref{sec:file_sharing}).  Il valore di
+\param{offset} fa sempre riferimento all'inizio del file.
+
+La funzione \func{pread} è disponibile anche in Linux, però diventa
+accessibile solo attivando il supporto delle estensioni previste dalle
+\textit{Single Unix Specification} con la definizione della macro:
 \begin{verbatim}
 #define _XOPEN_SOURCE 500
 \end{verbatim}
+e si ricordi di definire questa macro prima dell'inclusione del file di
+dichiarazioni \file{unistd.h}.
 
-Questa funzione serve quando si vogliono leggere dati dal file senza
-modificare la posizione corrente. È equivalente all'esecuzione di una
-\func{read} seguita da una \func{lseek} che riporti al valore precedente la
-posizione corrente sul file, ma permette di eseguire l'operazione
-atomicamente. Questo può essere importante quando la posizione sul file viene
-condivisa da processi diversi (vedi sez.~\ref{sec:file_sharing}).  Il valore di
-\param{offset} fa sempre riferimento all'inizio del file.
 
 
 \subsection{La funzione \func{write}}
 \label{sec:file_write}
 
-Una volta che un file è stato aperto (con il permesso in scrittura) su può
+Una volta che un file è stato aperto (con il permesso in scrittura) si può
 scrivere su di esso utilizzando la funzione \funcd{write}, il cui prototipo è:
 \begin{prototype}{unistd.h}{ssize\_t write(int fd, void * buf, size\_t count)}