Passa al contenuto principale

1. Introduzione (Introduction)

Il protocollo NFS (NFS Protocol) di Sun fornisce accesso remoto trasparente ai file system condivisi attraverso le reti. Il protocollo NFS è progettato per essere indipendente dalla macchina, dal sistema operativo, dall'architettura di rete e dal protocollo di trasporto. Questa indipendenza è ottenuta attraverso l'uso di primitive Remote Procedure Call (RPC) costruite sopra una rappresentazione esterna dei dati (eXternal Data Representation, XDR). Esistono implementazioni del protocollo NFS versione 2 per una varietà di macchine, dai personal computer ai supercomputer. La versione iniziale del protocollo NFS è specificata nella Network File System Protocol Specification [RFC1094]. Una descrizione dell'implementazione iniziale può essere trovata in [Sandberg].

Il protocollo MOUNT di supporto esegue le funzioni specifiche del sistema operativo che consentono ai client di collegare alberi di directory remoti a un punto all'interno del file system locale. Il processo di mount consente inoltre al server di concedere privilegi di accesso remoto a un insieme limitato di client tramite il controllo delle esportazioni.

Il Lock Manager fornisce supporto per il blocco dei file quando utilizzato nell'ambiente NFS. Il protocollo Network Lock Manager (NLM) isola gli aspetti intrinsecamente stateful del blocco dei file in un protocollo separato.

Una descrizione completa dei protocolli sopra menzionati e della loro implementazione si trova in [X/OpenNFS].

Lo scopo di questo documento è:

  • Specificare il protocollo NFS versione 3.

  • Descrivere la semantica del protocollo attraverso annotazioni e descrizione dell'implementazione prevista.

  • Specificare il protocollo MOUNT versione 3.

  • Descrivere brevemente le modifiche tra il protocollo NLM versione 3 e il protocollo NLM versione 4.

Il testo normativo è la descrizione delle procedure RPC e degli argomenti e risultati, che definisce il protocollo over-the-wire e la semantica di tali procedure. Il materiale che descrive la pratica di implementazione aiuta a comprendere la specifica del protocollo e descrive alcuni possibili problemi di implementazione e soluzioni. Non è possibile descrivere tutte le implementazioni e l'implementazione del sistema operativo UNIX del protocollo NFS versione 3 è più spesso utilizzata per fornire esempi. Dato ciò, la discussione sull'implementazione non ha l'autorità della descrizione del protocollo over-the-wire stesso.

1.1 Ambito del protocollo NFS versione 3 (Scope of the NFS version 3 protocol)

Questa revisione del protocollo NFS affronta nuovi requisiti. La necessità di supportare file e file system più grandi ha portato a estensioni per consentire dimensioni e offset di file a 64 bit. La revisione migliora la sicurezza aggiungendo supporto per un controllo di accesso da eseguire sul server. Le modifiche alle prestazioni sono di tre tipi:

  1. Il numero di pacchetti over-the-wire per un dato insieme di operazioni su file è ridotto restituendo gli attributi del file ad ogni operazione, diminuendo così il numero di chiamate per ottenere gli attributi modificati.

  2. Il collo di bottiglia del throughput di scrittura causato dalla definizione sincrona di scrittura nel protocollo NFS versione 2 è stato affrontato aggiungendo supporto affinché il server NFS possa eseguire scritture non sicure (unsafe writes). Le scritture non sicure sono scritture che non sono state confermate su storage stabile prima che l'operazione ritorni. Questa specifica definisce un metodo per confermare queste scritture non sicure su storage stabile in modo affidabile.

  3. Le limitazioni sulle dimensioni di trasferimento sono state allentate.

La capacità di supportare più versioni di un protocollo in RPC consentirà agli implementatori del protocollo NFS versione 3 di definire client e server che forniscono retrocompatibilità con la base installata esistente di implementazioni del protocollo NFS versione 2.

Le estensioni qui descritte rappresentano un'evoluzione del protocollo NFS esistente e la maggior parte delle caratteristiche di progettazione del protocollo NFS descritte in [Sandberg] persistono. Vedere Modifiche rispetto al protocollo NFS versione 2 a pagina 11 per un riepilogo più dettagliato delle modifiche introdotte da questa revisione.

1.2 Termini utili (Useful terms)

In questa specifica, un "server" è una macchina che fornisce risorse alla rete; un "client" è una macchina che accede alle risorse tramite la rete; un "utente (user)" è una persona connessa a un client; un'"applicazione (application)" è un programma che viene eseguito su un client.

1.3 Remote Procedure Call

La specifica Sun Remote Procedure Call fornisce un'interfaccia orientata alle procedure ai servizi remoti. Ogni server fornisce un programma, che è un insieme di procedure. Il servizio NFS è uno di questi programmi. La combinazione di indirizzo host, numero di programma, numero di versione e numero di procedura specifica una procedura di servizio remoto. I server possono supportare più versioni di un programma utilizzando numeri di versione del protocollo diversi.

Il protocollo NFS è stato progettato per non richiedere alcun livello specifico di affidabilità dai suoi livelli inferiori, in modo che possa essere potenzialmente utilizzato su molti protocolli di trasporto sottostanti. Il servizio NFS è basato su RPC che fornisce l'astrazione sopra i protocolli di rete e trasporto di livello inferiore.

Il resto di questo documento presume che l'ambiente NFS sia implementato sopra Sun RPC, che è specificato in [RFC1057]. Una discussione completa si trova in [Corbin].

1.4 Rappresentazione esterna dei dati (External Data Representation)

La specifica eXternal Data Representation (XDR) fornisce un modo standard di rappresentare un insieme di tipi di dati su una rete. Questo risolve il problema di diversi ordini di byte, allineamento delle strutture e rappresentazione dei tipi di dati su diverse macchine comunicanti.

In questo documento, il linguaggio RPC Data Description Language viene utilizzato per specificare i parametri e i risultati in formato XDR per ciascuna delle procedure di servizio RPC che un server NFS fornisce. Il linguaggio RPC Data Description Language è simile alle dichiarazioni nel linguaggio di programmazione C. Sono stati aggiunti alcuni nuovi costrutti. La notazione:

string  name[SIZE];
string data<DSIZE>;

definisce name, che è un blocco di dimensione fissa di SIZE byte, e data, che è un blocco di dimensione variabile fino a DSIZE byte. Questa notazione indica array di lunghezza fissa e array con un numero variabile di elementi fino a un massimo fisso. Una definizione di lunghezza variabile senza dimensione specificata significa che non c'è una dimensione massima per il campo.

La definizione di union discriminata:

union example switch (enum status) {
case OK:
struct {
filename file1;
filename file2;
integer count;
}
case ERROR:
struct {
errstat error;
integer errno;
}
default:
void;
}

definisce una struttura in cui la prima cosa sulla rete è un tipo di enumerazione chiamato status. Se il valore di status è OK, la cosa successiva sulla rete sarà la struttura contenente file1, file2 e count. Altrimenti, se il valore di status è ERROR, la cosa successiva sulla rete sarà una struttura contenente error e errno. Se il valore di status non è né OK né ERROR, non ci sono altri dati nella struttura.

Il tipo XDR hyper è una quantità di 8 byte (64 bit). Viene utilizzato nello stesso modo del tipo integer. Per esempio:

hyper          foo;
unsigned hyper bar;

foo è un valore con segno di 8 byte, mentre bar è un valore senza segno di 8 byte.

Sebbene esistano compilatori RPC/XDR per generare stub client e server dall'input del linguaggio RPC Data Description Language, le implementazioni NFS non richiedono il loro utilizzo. Qualsiasi software che fornisca codifica e decodifica equivalenti all'ordine di rete canonico dei dati definiti da XDR può essere utilizzato per interoperare con altre implementazioni NFS.

XDR è descritto in [RFC1014].

1.5 Autenticazione e controllo dei permessi (Authentication and Permission Checking)

Il protocollo RPC include uno slot per i parametri di autenticazione ad ogni chiamata. Il contenuto dei parametri di autenticazione è determinato dal tipo di autenticazione utilizzato dal server e dal client. Un server può supportare diversi tipi di autenticazione contemporaneamente. Il tipo AUTH_NONE fornisce autenticazione nulla, cioè non vengono passate informazioni di autenticazione. Il tipo AUTH_UNIX fornisce ID utente, ID gruppo e gruppi in stile UNIX ad ogni chiamata. Il tipo AUTH_DES fornisce parametri di autenticazione crittografati DES basati su un nome a livello di rete, con chiavi di sessione scambiate tramite uno schema a chiave pubblica. Il tipo AUTH_KERB fornisce parametri di autenticazione crittografati DES basati su un nome a livello di rete con chiavi di sessione scambiate tramite chiavi segrete Kerberos.

Il server NFS controlla i permessi prendendo le credenziali dalle informazioni di autenticazione RPC in ogni richiesta remota. Per esempio, utilizzando il tipo di autenticazione AUTH_UNIX, il server ottiene l'ID utente effettivo, l'ID gruppo effettivo e i gruppi dell'utente ad ogni chiamata e li utilizza per controllare l'accesso. L'uso di ID utente e ID gruppo implica che il client e il server condividano lo stesso elenco di ID o eseguano il mapping locale degli ID utente e gruppo. I server e i client devono concordare sul mapping da utente a uid e da gruppo a gid, per quei siti che non implementano uno spazio di ID utente e ID gruppo coerente. In pratica, tale mapping viene tipicamente eseguito sul server, seguendo uno schema di mapping statico o un mapping stabilito dall'utente da un client al momento del mount.

Lo stile di autenticazione AUTH_DES e AUTH_KERB si basa su un nome a livello di rete. Fornisce maggiore sicurezza attraverso l'uso della crittografia DES e delle chiavi pubbliche nel caso di AUTH_DES, e della crittografia DES e delle chiavi segrete Kerberos (e ticket) nel caso di AUTH_KERB. Ancora una volta, il server e il client devono concordare sull'identità di un particolare nome sulla rete, ma il mapping da nome a identità è più indipendente dal sistema operativo rispetto al mapping uid e gid in AUTH_UNIX. Inoltre, poiché i parametri di autenticazione sono crittografati, un utente malintenzionato deve conoscere la password di rete o la chiave privata di un altro utente per impersonare quell'utente. Allo stesso modo, il verificatore restituito dal server è anch'esso crittografato, quindi impersonare un server richiede la conoscenza di una password di rete.

La procedura NULL tipicamente non richiede autenticazione.

1.6 Filosofia (Philosophy)

Questa specifica definisce il protocollo NFS versione 3, cioè il protocollo over-the-wire attraverso il quale un client accede a un server. Il protocollo fornisce un'interfaccia ben definita alle risorse di file di un server. Un client o un server implementa il protocollo e fornisce un mapping della semantica e delle azioni del file system locale a quelle definite nel protocollo NFS versione 3. Le implementazioni possono differire in varia misura, a seconda del grado in cui un dato ambiente può supportare tutte le operazioni e la semantica definite nel protocollo NFS versione 3. Sebbene esistano implementazioni e vengano utilizzate per illustrare vari aspetti del protocollo NFS versione 3, la specifica del protocollo stessa è la descrizione finale di come i client accedono alle risorse del server.

Poiché il protocollo NFS versione 3 è progettato per essere indipendente dal sistema operativo, non corrisponde necessariamente alla semantica di alcun sistema esistente. Ci si aspetta che le implementazioni server facciano del loro meglio per supportare il protocollo. Se un server non può supportare una particolare procedura del protocollo, può restituire l'errore NFS3ERR_NOTSUP, che indica che l'operazione non è supportata. Per esempio, molti sistemi operativi non supportano il concetto di hard link. Un server che non può supportare gli hard link dovrebbe restituire NFS3ERR_NOTSUP in risposta a una richiesta LINK. FSINFO descrive le procedure più comunemente non supportate nella bitmap delle proprietà. In alternativa, un server potrebbe non supportare nativamente una data operazione, ma può emularla nell'implementazione del protocollo NFS versione 3 per fornire maggiore funzionalità.

In alcuni casi, un server può supportare la maggior parte della semantica descritta dal protocollo ma non tutta. Per esempio, il campo ctime nella struttura fattr fornisce il tempo in cui gli attributi di un file sono stati modificati l'ultima volta. Molti sistemi non mantengono queste informazioni. In questo caso, piuttosto che non supportare l'operazione GETATTR, un server potrebbe simularla restituendo il tempo dell'ultima modifica al posto di ctime. I server devono essere cauti quando simulano informazioni sugli attributi a causa di possibili effetti collaterali sui client. Per esempio, molti client utilizzano i tempi di modifica dei file come base per il loro schema di coerenza della cache.

I server NFS sono stupidi e i client NFS sono intelligenti. Sono i client che svolgono il lavoro necessario per convertire l'accesso ai file generalizzato che i server forniscono in un metodo di accesso ai file utile per le applicazioni e gli utenti. Nell'esempio LINK dato sopra, un client UNIX che ha ricevuto un errore NFS3ERR_NOTSUP da un server eseguirebbe il recupero necessario per far apparire all'applicazione che la richiesta di link è riuscita o restituire un errore ragionevole. In generale, è l'onere del client recuperare.

Il protocollo NFS versione 3 assume un'implementazione server stateless. Stateless significa che il server non ha bisogno di mantenere lo stato su nessuno dei suoi client per funzionare correttamente. I server stateless hanno un vantaggio distinto rispetto ai server stateful in caso di crash. Con i server stateless, un client deve solo riprovare una richiesta fino a quando il server risponde; il client non ha nemmeno bisogno di sapere che il server si è arrestato. Vedere commenti aggiuntivi in Duplicate request cache a pagina 99.

Per essere utile, un server mantiene stato non volatile: dati memorizzati nel file system. Le assunzioni di progettazione nel protocollo NFS versione 3 riguardanti lo svuotamento dei dati modificati su storage stabile riducono il numero di modalità di guasto in cui può verificarsi la perdita di dati. In questo modo, le implementazioni del protocollo NFS versione 3 possono tollerare guasti transitori, inclusi guasti transitori della rete. In generale, le implementazioni server del protocollo NFS versione 3 non possono tollerare un guasto non transitorio dello storage stabile stesso. Tuttavia, esistono implementazioni fault-tolerant che tentano di affrontare tali problemi.

Ciò non significa che un server del protocollo NFS versione 3 non possa mantenere stato non critico. In molti casi, i server manterranno stato (cache) sulle operazioni precedenti per aumentare le prestazioni. Per esempio, una richiesta READ del client potrebbe attivare una lettura anticipata del blocco successivo del file nella cache dati del server in previsione che il client stia eseguendo una lettura sequenziale e che la successiva richiesta READ del client sarà soddisfatta dalla cache dati del server invece che dal disco. La lettura anticipata sul server aumenta le prestazioni sovrapponendo l'I/O del disco del server con le richieste del client. Il punto importante qui è che il blocco di lettura anticipata non è necessario per un comportamento corretto del server. Se il server si arresta e perde la sua cache in memoria dei buffer di lettura, il recupero al riavvio è semplice - i client continueranno le operazioni di lettura recuperando i dati dal disco del server.

La maggior parte delle operazioni di modifica dei dati nel protocollo NFS sono sincrone. Cioè, quando una procedura di modifica dei dati ritorna al client, il client può assumere che l'operazione sia stata completata e che tutti i dati modificati associati alla richiesta siano ora su storage stabile. Per esempio, una richiesta WRITE sincrona del client può causare l'aggiornamento da parte del server di blocchi di dati, blocchi di informazioni sul file system e informazioni sugli attributi del file - queste ultime informazioni sono solitamente chiamate metadati (metadata). Quando l'operazione WRITE è completata, il client può assumere che i dati di scrittura siano al sicuro e scartarli. Questa è una parte molto importante della natura stateless del server. Se il server non svuotasse i dati sporchi su storage stabile prima di ritornare al client, il client non avrebbe modo di sapere quando è sicuro scartare i dati modificati. Le seguenti procedure di modifica dei dati sono sincrone: WRITE (con flag stabile impostato su FILE_SYNC), CREATE, MKDIR, SYMLINK, MKNOD, REMOVE, RMDIR, RENAME, LINK e COMMIT.

Il protocollo NFS versione 3 introduce scritture asincrone sicure sul server, quando la procedura WRITE viene utilizzata in combinazione con la procedura COMMIT. La procedura COMMIT fornisce un modo per il client di svuotare i dati dalle precedenti richieste WRITE asincrone sul server su storage stabile e di rilevare se è necessario ritrasmettere i dati. Vedere le descrizioni delle procedure di WRITE a pagina 49 e COMMIT a pagina 92.

La procedura LOOKUP viene utilizzata dal client per attraversare nomi di file multi-componente (pathname). Ogni chiamata a LOOKUP viene utilizzata per risolvere un segmento di un pathname. Ci sono due ragioni per limitare LOOKUP a un singolo segmento: è difficile standardizzare un formato comune per i nomi di file gerarchici e il client e il server possono avere mapping diversi di pathname a file system. Ciò implicherebbe che o il client deve spezzare il pathname ai punti di attacco del file system, o il server deve conoscere i punti di attacco del file system del client. Nelle implementazioni del protocollo NFS versione 3, è il client che costruisce lo spazio dei nomi di file gerarchico utilizzando i mount per costruire una gerarchia. Le utility di supporto, come l'Automounter, forniscono un modo per gestire un'immagine condivisa e coerente dello spazio dei nomi di file pur essendo guidate dal processo di mount del client.

I client possono eseguire il caching in modo vario. La pratica generale con il protocollo NFS versione 2 era di implementare un meccanismo di coerenza della cache client-server basato sul tempo. Si prevede che le implementazioni del protocollo NFS versione 3 utilizzeranno un meccanismo simile. Il protocollo NFS versione 3 ha un supporto esplicito, sotto forma di informazioni sugli attributi aggiuntive per eliminare i controlli espliciti degli attributi. Tuttavia, il caching non è richiesto, né è definita alcuna politica di caching dal protocollo. Né il protocollo NFS versione 2 né il protocollo NFS versione 3 forniscono un mezzo per mantenere una coerenza stretta client-server (e, per implicazione, coerenza tra le cache dei client).

1.7 Modifiche rispetto al protocollo NFS versione 2 (Changes from the NFS Version 2 Protocol)

Le procedure ROOT e WRITECACHE sono state rimosse. È stata definita una procedura MKNOD per consentire la creazione di file speciali, eliminando il sovraccarico di CREATE. Il caching sul client non è definito né dettato dal protocollo NFS versione 3, ma sono state aggiunte informazioni e suggerimenti aggiuntivi al protocollo per consentire ai client che implementano il caching di gestire le loro cache in modo più efficace. Le procedure che influenzano gli attributi di un file o directory possono ora restituire i nuovi attributi dopo il completamento dell'operazione per ottimizzare un successivo GETATTR utilizzato nella validazione delle cache degli attributi. Inoltre, le operazioni che modificano la directory in cui risiede l'oggetto target restituiscono i vecchi e nuovi attributi della directory per consentire ai client di implementare procedure di invalidazione della cache più intelligenti. La procedura ACCESS fornisce il controllo dei permessi di accesso sul server, la procedura FSSTAT restituisce informazioni dinamiche su un file system, la procedura FSINFO restituisce informazioni statiche su un file system e un server, la procedura READDIRPLUS restituisce handle di file e attributi oltre alle voci di directory, e la procedura PATHCONF restituisce informazioni POSIX pathconf su un file.

Di seguito è riportato un elenco delle modifiche importanti tra il protocollo NFS versione 2 e il protocollo NFS versione 3.

Dimensione dell'handle del file (File handle size)

L'handle del file è stato aumentato da un array fisso di 32 byte a un array di lunghezza variabile di massimo 64 byte. Questo affronta alcuni requisiti noti per una dimensione dell'handle del file leggermente più grande. L'handle del file è stato convertito da lunghezza fissa a lunghezza variabile per ridurre i requisiti di storage locale e larghezza di banda di rete per i sistemi che non utilizzano i 64 byte completi di lunghezza.

Dimensioni massime dei dati (Maximum data sizes)

La dimensione massima di un trasferimento di dati utilizzato nelle procedure READ e WRITE è ora impostata dai valori nella struttura di ritorno FSINFO. Inoltre, le dimensioni di trasferimento preferite vengono restituite da FSINFO. Il protocollo non impone alcun limite artificiale sulle dimensioni massime di trasferimento.

I nomi di file e i pathname sono ora specificati come stringhe di lunghezza variabile. Le restrizioni di lunghezza effettive sono determinate dalle implementazioni client e server in modo appropriato. Il protocollo non impone alcun limite artificiale sulla lunghezza. L'errore NFS3ERR_NAMETOOLONG è fornito per consentire al server di restituire un'indicazione al client che ha ricevuto un pathname troppo lungo per essere gestito.

Restituzione degli errori (Error return)

Le restituzioni degli errori in alcuni casi ora restituiscono dati (per esempio, attributi). nfsstat3 ora definisce l'insieme completo di errori che possono essere restituiti da un server. Non sono consentiti altri valori.

Tipo di file (File type)

Il tipo di file ora include NF3CHR e NF3BLK per i file speciali. Gli attributi per questi tipi includono sottocampi per i numeri di device maggiori e minori UNIX. NF3SOCK e NF3FIFO sono ora definiti per i socket e i fifo nel file system.

Attributi del file (File attributes)

Il campo blocksize (la dimensione in byte di un blocco nel file) è stato rimosso. Il campo mode non contiene più informazioni sul tipo di file. I campi size e fileid sono stati ampliati a interi senza segno a otto byte da interi a quattro byte. Le informazioni sui numeri di device maggiori e minori sono ora presentate in una struttura distinta. Il nome del campo blocks è stato cambiato in used e ora contiene il numero totale di byte utilizzati dal file. È anche un intero senza segno a otto byte.

Impostazione degli attributi del file (Set file attributes)

Nel protocollo NFS versione 2, gli attributi impostabili erano rappresentati da un sottoinsieme della struttura degli attributi del file; il client indicava quali attributi non dovevano essere modificati impostando il campo corrispondente a -1, sovraccaricando alcuni campi senza segno. La struttura di impostazione degli attributi del file ora utilizza un'union discriminata per ogni campo per indicare se o come impostare quel campo. I campi atime e mtime possono essere impostati sul tempo corrente del server o su un tempo fornito dal client.

LOOKUP

La struttura di ritorno LOOKUP ora include gli attributi per la directory cercata.

ACCESS

È stata aggiunta una procedura ACCESS per consentire un controllo esplicito dei permessi over-the-wire. Questo affronta problemi noti con la funzionalità di mapping dell'ID del superutente in molte implementazioni server (dove, a causa del mapping dell'utente root, potevano verificarsi errori imprevisti di permesso negato durante la lettura o la scrittura in un file). Questo rimuove anche l'assunzione che è stata fatta nel protocollo NFS versione 2 che l'accesso ai file fosse basato esclusivamente sui bit di modalità in stile UNIX.

READ

La struttura di risposta include un booleano che è TRUE se è stata incontrata la fine del file durante la READ. Questo consente al client di rilevare correttamente la fine del file.

WRITE

I campi beginoffset e totalcount sono stati rimossi dagli argomenti WRITE. La risposta ora include un conteggio in modo che il server possa scrivere meno della quantità di dati richiesta, se necessario. È stato aggiunto un indicatore agli argomenti per istruire il server sul livello di sincronizzazione della cache richiesto dal client.

CREATE

Un flag esclusivo e un verificatore di creazione sono stati aggiunti per la creazione esclusiva di file regolari.

MKNOD

Questa procedura è stata aggiunta per supportare la creazione di file speciali. Questo evita il sovraccarico di CREATE come è stato fatto in alcune implementazioni del protocollo NFS versione 2.

READDIR

Gli argomenti READDIR ora includono un verificatore per consentire al server di validare il cookie. Il cookie è ora un intero senza segno a 64 bit invece dell'array di 4 byte utilizzato nel protocollo NFS versione 2. Questo aiuterà a ridurre i problemi di interoperabilità.

READDIRPLUS

Questa procedura è stata aggiunta per restituire handle di file e attributi in un elenco di directory esteso.

FSINFO

FSINFO è stato aggiunto per fornire informazioni non volatili su un file system. La risposta include la dimensione di trasferimento di lettura preferita e massima, la dimensione di trasferimento di scrittura preferita e massima, e flag che indicano se sono supportati i link o i link simbolici. Vengono anche restituite la dimensione di trasferimento preferita per le risposte della procedura READDIR, la granularità temporale del server e se i tempi possono essere impostati in una richiesta SETATTR.

FSSTAT

FSSTAT è stato aggiunto per fornire informazioni volatili su un file system, per l'uso da parte di utility come il comando df del sistema Unix. La risposta include la dimensione totale e lo spazio libero nel file system specificato in byte, il numero totale di file e il numero di slot di file liberi nel file system, e una stima del tempo tra le modifiche del file system (per l'uso negli algoritmi di controllo della coerenza della cache).

COMMIT

La procedura COMMIT fornisce il meccanismo di sincronizzazione da utilizzare con le operazioni WRITE asincrone.