\label{sec:file_record_locking}
La prima modalità di file locking che è stata implementata nei sistemi
-unix-like è quella che viene usualmente chiamata \textit{advisory locking}, in
-quanto sono i singoli processi, e non il sistema, che si incaricano di
-asserire e verificare se esistono delle condizioni di blocco per l'accesso ai
-file. Questo significa che le funzioni \func{read} o \func{write} non
-risentono affatto della presenza di un eventuale blocco, e che sta ai vari
-processi controllare esplicitamente lo stato dei file condivisi prima di
-accedervi ed implementare opportunamente un protocollo di accesso.
+unix-like è quella che viene usualmente chiamata \textit{advisory
+ locking},\footnote{Stevens in APUE fa riferimento a questo argomento come al
+ \textit{record locking}, dizione utilizzata anche dal manuale delle
+ \acr{glibc}; nelle pagine di manuale si parla di \textit{discretionary file
+ lock} per \func{fcntl} e di \textit{advisory locking} per \func{flock},
+ mentre questo nome viene usato anche da Stevens per riferirsi al
+ \textit{file locking} di POSIX. Dato che la dizione \textit{record locking}
+ è quantomeno ambigua in quanto non esiste niente che possa fare riferimento
+ al concetto di \textit{record}, alla fine si è scelto di mantenere il nome
+ \textit{advisory locking}.} in quanto sono i singoli processi, e non il
+sistema, che si incaricano di asserire e verificare se esistono delle
+condizioni di blocco per l'accesso ai file. Questo significa che le funzioni
+\func{read} o \func{write} non risentono affatto della presenza di un
+eventuale blocco, e che sta ai vari processi controllare esplicitamente lo
+stato dei file condivisi prima di accedervi ed implementare opportunamente un
+protocollo di accesso.
In Linux sono disponibili due interfacce per utilizzare l'\textit{advisory
locking}, la prima è quella derivata da BSD, che è basata sulla funzione
sono implementati in maniera completamente indipendente nelle due interfacce,
che pertanto possono coesistere senza interferenze.
+In generale si distinguono due tipologie di blocco per un file: la prima è il
+cosiddetto \textit{shared lock}, detto anche \textit{read lock} in quanto
+serve a bloccare l'accesso in scrittura su un file affinché non venga
+modificato mentre lo si legge. Si parla di \textsl{blocco condiviso} in quanto
+più processi possono richiedere contemporaneamente uno \textit{shared lock}
+per proteggere un accesso in lettura.
+
+La seconda è il cosiddetto \textit{exclusive lock}, detto anche \textit{write
+ lock} in quanto serve a bloccare l'accesso su un file da parte di altri (sia
+in lettura che in scrittura) mentre lo si sta scrivendo. Si parla di
+\textsl{blocco esclusivo} appunto perché un solo processo alla volta può
+richiedere un \textit{exclusive lock} per proteggere un accesso in scrittura.
+
+Entrambe le interfacce garantiscono che quando si richiede un \textit{file
+ lock} su un file su cui ne sia già presente un altro che non ne consente
+l'acquisizione (uno \textit{shared lock} su un file con un \textit{exclusive
+ lock}, o un \textit{exclusive lock} su un file con altro \textit{file lock})
+la funzione blocca il processo fintanto che \textit{file lock} preesistente
+non viene rimosso.
+
L'interfaccia classica usata da BSD permette di eseguire il blocco solo su un
-intero file, come accennato essa è basata sulla funzione \func{flock}, il cui
-prototipo è:
+intero file, funzione usata per richiedere e rimuovere un \textit{file lock} è
+\func{flock}, il cui prototipo è:
\begin{prototype}{sys/file.h}{int flock(int fd, int operation)}
Applica o rimuove un \textit{file lock} sul file \param{fd}.
\textbf{Valore} & \textbf{Significato} \\
\hline
\hline
- \macro{LOCK\_SH} & Asserisce uno \textit{shared lock} (blocco
- condiviso) sul file. Un blocco condiviso può essere
- mantenuto da più processi contemporaneamente.\\
- \macro{LOCK\_EX} & Asserisce un \textit{esclusive lock} (blocco
- esclusivo) sul file. Un blocco esclusivo può essere
- mantenuto da un solo processo alla volta.\\
+ \macro{LOCK\_SH} & Asserisce uno \textit{shared lock} sul file.\\
+ \macro{LOCK\_EX} & Asserisce un \textit{esclusive lock} sul file.\\
\macro{LOCK\_UN} & Sblocca il file.\\
\macro{LOCK\_NB} & Impedisce che la funzione si blocchi nella
richiesta di un \textit{file lock}.\\
\label{tab:file_flock_operation}
\end{table}
+La funzione blocca direttamente il file (cioè rispetto allo schema di
+\secref{fig:file_stat_struct} fa riferimento all'inode, non al file
+descriptor). Pertanto sia \func{dup} che \func{fork} non creano altre istanze
+di un \textit{file lock}.
+
+La seconda interfaccia per l'\textit{advisory locking} disponibile in Linux è
+quella standardizzata da POSIX, basata sulla funzione \func{fcntl}. Abbiamo
+già trattato questa funzione nelle sue molteplici funzionalità in
+\secref{sec:file_fcntl}, quando la si impiega per il \textit{file locking}
+però essa viene usata secondo il prototipo:
+\begin{prototype}{fcntl.h}{int fcntl(int fd, int cmd, struct flock *lock)}
+
+ Applica o rimuove un \textit{file lock} sul file \param{fd}.
+
+ \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[\macro{EACCES}] L'operazione è proibita per la presenza di
+ \textit{file lock} da parte di altri processi.
+ \item[\macro{ENOLCK}] Il sistema non ha le risorse per il locking: ci sono
+ troppi segmenti di lock aperti, si è esaurita la tabella dei lock, o il
+ protocollo per il locking remoto è fallito.
+ \item[\macro{EDEADLK}] Si è richiesto un lock su una regione bloccata da
+ un altro processo che è a sua volta in attesa dello sblocco di un lock
+ mantenuto dal processo corrente; si avrebbe pertanto un
+ \textit{deadlock}. Non è garantito che il sistema riconosca sempre
+ questa situazione.
+ \item[\macro{EINTR}] La funzione è stata interrotta da un segnale prima di
+ poter acquisire un lock.
+ \end{errlist}
+ ed inoltre \macro{EBADF}, \macro{EFAULT}.
+ }
+\end{prototype}
-Si tenga conto che la funzione non è in grado di eseguire un blocco su NFS, in
-tal caso occorre usare \func{fcntl} che funziona anche attraverso NFS, posto
-che il server supporti il \textit{file locking}.
+Al contrario di \func{flock} con \func{fcntl} è possibile bloccare anche solo
+delle sezioni di un file. La funzione prende come argomento
+\begin{figure}[!htb]
+ \footnotesize \centering
+ \begin{minipage}[c]{15cm}
+ \begin{lstlisting}[labelstep=0]{}%,frame=,indent=1cm]{}
+struct struct {
+ short int l_type; /* Type of lock: F_RDLCK, F_WRLCK, or F_UNLCK. */
+ short int l_whence; /* Where `l_start' is relative to (like `lseek'). */
+ off_t l_start; /* Offset where the lock begins. */
+ off_t l_len; /* Size of the locked area; zero means until EOF. */
+ pid_t l_pid; /* Process holding the lock. */
+};
+ \end{lstlisting}
+ \end{minipage}
+ \normalsize
+ \caption{La struttura \type{flock}, usata da \func{fcntl} per il file
+ locking.}
+ \label{fig:struct_flock}
+\end{figure}
+
+
+
+
+Si tenga conto che \func{flock} non è in grado di eseguire il \textit{file
+ locking} su NFS, se si ha questa necessità occorre usare \func{fcntl} che
+funziona anche attraverso NFS, posto che il server supporti il \textit{file
+ locking}.
\subsection{Il \textit{mandatory locking}}
\label{sec:file_mand_locking}