From: Simone Piccardi Date: Fri, 18 Jan 2019 09:55:07 +0000 (+0100) Subject: Note varie e revisione X-Git-Url: https://gapil.gnulinux.it/gitweb/?p=gapil.git;a=commitdiff_plain;h=5cb7d403c1ad342d363c958310a119001218c9d5 Note varie e revisione --- diff --git a/fileio.tex b/fileio.tex index 419877a..024cc34 100644 --- a/fileio.tex +++ b/fileio.tex @@ -771,7 +771,7 @@ operano effettivamente sul file (come ad esempio \func{read}, \func{write}, \func{fchown}, \func{fchmod}, \func{ioctl}, ecc.) fallirà con un errore di \errval{EBADF}, come se questo non fosse un file descriptor valido. Per questo motivo usando questo flag non è necessario avere nessun permesso per aprire un -file, neanche quello di lettura (occorre ovviamente avere il permesso di +file, neanche quello di lettura (ma occorre ovviamente avere il permesso di esecuzione per le directory sovrastanti). Questo consente di usare il file descriptor con funzioni che non richiedono @@ -791,7 +791,6 @@ così da poter usare il file descriptor ottenuto per le funzioni supportano l'uso come come primo argomento (torneremo su questo in sez.~\ref{sec:file_openat}). - Nelle prime versioni di Unix i valori di \param{flag} specificabili per \func{open} erano solo quelli relativi alle modalità di accesso del file. Per questo motivo per creare un nuovo file c'era una \textit{system call} @@ -985,23 +984,23 @@ indefinito. Infine si tenga presente che, come accennato in sez.~\ref{sec:file_file_size}, con \func{lseek} è possibile impostare una posizione anche oltre la corrente fine del file. In tal caso alla successiva scrittura il file sarà esteso a -partire da detta posizione, con la creazione di quello che viene chiamato +partire da detta posizione, con la creazione di quello che viene chiamato un ``\textsl{buco}'' (in gergo \textit{hole}) nel file. Il nome deriva dal fatto che nonostante la dimensione del file sia cresciuta in seguito alla scrittura -effettuata, lo spazio vuoto fra la precedente fine del file ed la nuova parte -scritta dopo lo spostamento non corrisponde ad una allocazione effettiva di +effettuata, lo spazio vuoto fra la precedente fine del file e la nuova parte, +scritta dopo lo spostamento, non corrisponde ad una allocazione effettiva di spazio su disco, che sarebbe inutile dato che quella zona è effettivamente vuota. Questa è una delle caratteristiche specifiche della gestione dei file di un -sistema unix-like e si dice che il file in questione è uno \textit{sparse - file}. In sostanza, se si ricorda la struttura di un filesystem illustrata -in fig.~\ref{fig:file_filesys_detail}, quello che accade è che -nell'\textit{inode} del file viene segnata l'allocazione di un blocco di dati -a partire dalla nuova posizione, ma non viene allocato nulla per le posizioni -intermedie; in caso di lettura sequenziale del contenuto del file il kernel si -accorgerà della presenza del buco, e restituirà degli zeri come contenuto di -quella parte del file. +sistema unix-like e quando si ha questa situazione si dice che il file in +questione è uno \textit{sparse file}. In sostanza, se si ricorda la struttura +di un filesystem illustrata in fig.~\ref{fig:file_filesys_detail}, quello che +accade è che nell'\textit{inode} del file viene segnata l'allocazione di un +blocco di dati a partire dalla nuova posizione, ma non viene allocato nulla +per le posizioni intermedie. In caso di lettura sequenziale del contenuto del +file il kernel si accorgerà della presenza del buco, e restituirà degli zeri +come contenuto di quella parte del file. Questa funzionalità comporta una delle caratteristiche della gestione dei file su Unix che spesso genera più confusione in chi non la conosce, per cui @@ -1011,24 +1010,23 @@ disco e comunque maggiore della dimensione che riporta un comando come \cmd{du}, che calcola lo spazio disco occupato in base al numero dei blocchi effettivamente allocati per il file. -Questo avviene proprio perché in un sistema unix-like la dimensione di un file -è una caratteristica del tutto indipendente dalla quantità di spazio disco -effettivamente allocato, e viene registrata sull'\textit{inode} come le altre -proprietà del file. La dimensione viene aggiornata automaticamente quando si -estende un file scrivendoci, e viene riportata dal campo \var{st\_size} di una -struttura \struct{stat} quando si effettua la chiamata ad una delle funzioni -\texttt{*stat} viste in sez.~\ref{sec:file_stat}. - -Questo comporta che in generale, fintanto che lo si è scritto sequenzialmente, -la dimensione di un file sarà più o meno corrispondente alla quantità di -spazio disco da esso occupato, ma esistono dei casi, come questo in cui ci si -sposta in una posizione oltre la fine corrente del file, o come quello -accennato in sez.~\ref{sec:file_file_size} in cui si estende la dimensione di -un file con una \func{truncate}, in cui in sostanza si modifica il valore -della dimensione di \var{st\_size} senza allocare spazio su disco. Questo -consente di creare inizialmente file di dimensioni anche molto grandi, senza -dover occupare da subito dello spazio disco che in realtà sarebbe -inutilizzato. +Tutto ciò avviene proprio perché in un sistema unix-like la dimensione di un +file è una caratteristica del tutto indipendente dalla quantità di spazio +disco effettivamente allocato, e viene registrata sull'\textit{inode} come le +altre proprietà del file. La dimensione viene aggiornata automaticamente +quando si estende un file scrivendoci, e viene riportata dal campo +\var{st\_size} di una struttura \struct{stat} quando si effettua la chiamata +ad una delle funzioni \texttt{*stat} viste in sez.~\ref{sec:file_stat}. + +Questo comporta che la dimensione di un file, fintanto che lo si è scritto +sequenzialmente, sarà corrispondente alla quantità di spazio disco da esso +occupato, ma possono esistere dei casi, come questo in cui ci si sposta in una +posizione oltre la fine corrente del file, o come quello accennato in +sez.~\ref{sec:file_file_size} in cui si estende la dimensione di un file con +una \func{truncate}, in cui si modifica soltanto il valore della dimensione di +\var{st\_size} senza allocare spazio su disco. Così è possibile creare +inizialmente file di dimensioni anche molto grandi, senza dover occupare da +subito dello spazio disco che in realtà sarebbe inutilizzato. \itindend{sparse~file} @@ -1168,7 +1166,7 @@ funzione di sistema, \funcd{pread}, il cui prototipo è: La funzione prende esattamente gli stessi argomenti di \func{read} con lo stesso significato, a cui si aggiunge l'argomento \param{offset} che indica -una posizione sul file a partire dalla quale verranno i \param{count} +una posizione sul file a partire dalla quale verranno letti i \param{count} byte. Identico è il comportamento ed il valore di ritorno, ma la posizione corrente sul file resterà invariata. Il valore di \param{offset} fa sempre riferimento all'inizio del file. @@ -1222,7 +1220,8 @@ prototipo è: potuto scrivere qualsiasi dato. \item[\errcode{EINVAL}] \param{fd} è connesso ad un oggetto che non consente la scrittura o si è usato \const{O\_DIRECT} ed il buffer non è allineato. -% \item[\errcode{EPERM}] la scrittura è proibita da un \textit{file seal}. + \item[\errcode{EPERM}] la scrittura è proibita da un \textit{file seal} + (vedi sez.~\ref{sec:file_fcntl_ioctl}). \item[\errcode{EPIPE}] \param{fd} è connesso ad una \textit{pipe} il cui altro capo è chiuso in lettura; in questo caso viene anche generato il segnale \signal{SIGPIPE}, se questo viene gestito (o bloccato o ignorato) @@ -1281,7 +1280,7 @@ In questa sezione approfondiremo alcune delle caratteristiche più sottili della gestione file in un sistema unix-like, esaminando in dettaglio il comportamento delle funzioni base, inoltre tratteremo le funzioni che permettono di eseguire alcune operazioni avanzate con i file (il grosso -dell'argomento sarà comunque affrontato in cap.~\ref{cha:file_advanced}). +dell'argomento sarà comunque affrontato nel cap.~\ref{cha:file_advanced}). \subsection{La gestione dell'accesso concorrente ai files} @@ -1589,16 +1588,16 @@ fra \param{newfd} e \param{oldfd}, fallendo con un errore di \errval{EINVAL}. Come accennato in sez.~\ref{sec:file_open_close} tutte le operazioni di scrittura sono in genere bufferizzate dal kernel, che provvede ad effettuarle -in maniera asincrona, ad esempio accorpando gli accessi alla stessa zona del -disco in un secondo tempo rispetto al momento della esecuzione della -\func{write}. +in maniera asincrona per ottimizzarle, ad esempio accorpando gli accessi alla +stessa zona del disco in un secondo tempo rispetto al momento della esecuzione +della \func{write}. -Per questo motivo quando è necessaria una sincronizzazione dei dati il sistema -mette a disposizione delle funzioni che provvedono a forzare lo scarico dei -dati dai buffer del kernel. La prima di queste funzioni di sistema è -\funcd{sync}, il cui prototipo è:\footnote{questo è il prototipo usato a - partire dalla \acr{glibc} 2.2.2 seguendo gli standard, in precedenza la - funzione era definita come \code{int sync(void)} e ritornava sempre $0$.} +Per questo motivo quando è necessaria una sincronizzazione immediata dei dati +il sistema mette a disposizione delle funzioni che provvedono a forzare lo +scarico dei dati dai buffer del kernel. La prima di queste funzioni di +sistema è \funcd{sync}, il cui prototipo è:\footnote{questo è il prototipo + usato a partire dalla \acr{glibc} 2.2.2 seguendo gli standard, in precedenza + la funzione era definita come \code{int sync(void)} e ritornava sempre $0$.} \begin{funcproto}{ \fhead{unistd.h} @@ -1693,7 +1692,7 @@ L'uso di \func{sync} presenta in certi casi, quando ci sono più filesystem montati, problemi di prestazioni dovute al fatto che la funzione provoca la sincronizzazione dei dati su tutti quanti i filesystem, anche quando interesserebbe che questo avvenga soltanto su quello dei file su cui si sta -lavorando, se i dati in attesa sono molti questo può causare seri problemi di +lavorando. se i dati in attesa sono molti questo può causare seri problemi di prestazioni. Per questo motivo è stata introdotta una nuova funzione di sistema, @@ -1805,7 +1804,7 @@ esame la nuova funzione di sistema \funcd{openat}, il cui prototipo è: \end{funcproto} Il comportamento di \func{openat} è del tutto analogo a quello di \func{open}, -con la sola eccezione del fatto che se per l'argomento \pathname{pathname} si +con la sola eccezione del fatto che se per l'argomento \param{pathname} si utilizza un \textit{pathname} relativo questo, sarà risolto rispetto alla directory indicata da \param{dirfd}. Qualora invece si usi un \textit{pathname} assoluto \param{dirfd} verrà semplicemente ignorato. Infine @@ -2149,6 +2148,8 @@ un file descriptor, che non riguardano la normale lettura e scrittura di dati, ma la gestione sia delle loro proprietà, che di tutta una serie di ulteriori funzionalità che il kernel può mettere a disposizione. +% TODO: trattare qui i file seal + Per le operazioni di manipolazione e di controllo delle varie proprietà e caratteristiche di un file descriptor, viene usata la funzione di sistema \funcd{fcntl},\footnote{ad esempio si gestiscono con questa funzione varie