In che modo i flag O_SYNC e O_DIRECT sono aperti (2) diversi / uguali?

L’uso e gli effetti dei flag O_SYNC e O_DIRECT sono molto confusi e sembrano variare in qualche modo tra le piattaforms. Dalla pagina di manuale di Linux (vedere un esempio qui ), O_DIRECT fornisce I / O sincrono, riduce al minimo gli effetti della cache e richiede all’utente di gestire autonomamente l’allineamento della dimensione del blocco. O_SYNC garantisce solo I / O sincrono. Sebbene entrambi garantiscano che i dati siano scritti nella cache del disco rigido, credo che le operazioni di I / O diretto siano più veloci del semplice I / O sincrono poiché ignorano la cache della pagina (anche se la pagina man di FreeBSD per open (2) afferma che la cache viene bypassata quando viene utilizzato O_SYNC. Vedi qui ).

Quali sono esattamente le differenze tra i flag O_DIRECT e O_SYNC? Alcune implementazioni suggeriscono di usare O_SYNC | O_DIRECT. Perché?

Solo O_DIRECT promette che il kernel eviterà di copiare i dati dallo spazio utente allo spazio del kernel e invece lo scriverà direttamente tramite DMA (accesso diretto alla memoria, se ansible). I dati non entrano nella cache. Non vi è alcuna garanzia che la funzione verrà restituita solo dopo che tutti i dati sono stati trasferiti.

O_SYNC garantisce che la chiamata non ritorni prima che tutti i dati siano stati trasferiti sul disco (a seconda del sistema operativo). Ciò non garantisce ancora che i dati non si trovino da qualche parte nella cache di scrittura del disco rigido, ma è tanto quanto il sistema operativo può garantire.

O_DIRECT | O_SYNC è la combinazione di questi, vale a dire “garanzia DMA +”.

Si prega di consultare questo articolo di lwn per una descrizione chiara dei ruoli di O_DIRECT e O_SYNC e il loro impatto sull’integrità dei dati:

https://lwn.net/Articles/457667/

Actuall sotto linux 2.6, o_direct è syncronus, vedi la pagina man:

manpage di open, ci sono 2 sezioni su di esso ..

Sotto 2.4 non è garantito

O_DIRECT (A partire da Linux 2.4.10) Prova a minimizzare gli effetti di cache dell’I / O verso e da questo file. In questo modo si ridurranno le prestazioni, ma è utile in situazioni speciali, ad esempio quando le applicazioni eseguono il proprio caching. L’I / O di file viene eseguito direttamente da / per i buffer dello spazio utente. Il flag O_DIRECT da solo fa uno sforzo per trasferire i dati in modo sincrono, ma non fornisce le garanzie del flag O_SYNC che i dati e i metadati necessari vengono trasferiti. Per garantire l’I / O sincrono, O_SYNC deve essere utilizzato in aggiunta a O_DIRECT. Vedere le NOTE qui sotto per ulteriori discussioni.

Un’interfaccia semanticamente simile (ma deprecata) per i dispositivi a blocchi è descritta in raw (8).

ma sotto 2.6 è garantito, vedi

O_DIRECT

Il flag O_DIRECT può imporre restrizioni di allineamento sulla lunghezza e sull’indirizzo dei buffer userspace e l’offset del file degli I / O. In Linux le restrizioni di allineamento variano a seconda del file system e della versione del kernel e potrebbero essere completamente assenti. Tuttavia non esiste attualmente un’interfaccia indipendente dal file system per un’applicazione per scoprire queste restrizioni per un determinato file o file system. Alcuni file system forniscono le proprie interfacce per farlo, ad esempio l’operazione XFS_IOC_DIOINFO in xfsctl (3).

Sotto Linux 2.4, le dimensioni di trasferimento e l’allineamento del buffer utente e l’offset del file devono essere tutti multipli della dimensione del blocco logico del file system. Sotto Linux 2.6, l’allineamento ai limiti di 512 byte è sufficiente.

O_DIRECT I / O non dovrebbe mai essere eseguito contemporaneamente alla chiamata di sistema fork (2), se il buffer di memoria è un mapping privato (cioè qualsiasi mapping creata con il flag MAP_PRIVATE mmap (2), che include la memoria allocata nell’heap e staticamente buffer assegnati). Qualsiasi tale I / O, sia inviato tramite un’interfaccia I / O asincrona o da un altro thread nel processo, deve essere completato prima di chiamare il fork (2). In caso contrario, si può verificare un danneggiamento dei dati e un comportamento non definito nei processi padre e figlio. Questa restrizione non si applica quando il buffer di memoria per gli I / O O_DIRECT è stato creato utilizzando shmat (2) o mmap (2) con il flag MAP_SHARED. Né si applica questa restrizione quando il buffer di memoria è stato consigliato come MADV_DONTFORK con madvise (2), assicurandosi che non sarà disponibile per il bambino dopo la fork (2).

Il flag O_DIRECT è stato introdotto in SGI IRIX, dove ha restrizioni di allineamento simili a quelle di Linux 2.4. IRIX ha anche una chiamata a fcntl (2) per richiedere gli allineamenti e le dimensioni appropriati. FreeBSD 4.x ha introdotto un flag con lo stesso nome, ma senza restrizioni di allineamento.

Il supporto O_DIRECT è stato aggiunto sotto Linux nella versione del kernel 2.4.10. I vecchi kernel di Linux ignorano semplicemente questa bandiera. Alcuni file system potrebbero non implementare il flag e open () non riuscirà con EINVAL se viene utilizzato.

Le applicazioni dovrebbero evitare di mixare O_DIRECT e I / O normale allo stesso file, e in particolare a sovrapporre le regioni di byte nello stesso file. Anche quando il file system gestisce correttamente i problemi di coerenza in questa situazione, il throughput complessivo di I / O sarà probabilmente più lento rispetto all’utilizzo di entrambe le modalità. Allo stesso modo, le applicazioni dovrebbero evitare di mescolare mmap (2) di file con I / O diretto con gli stessi file.

Il comportamento di O_DIRECT con NFS sarà diverso dai file system locali. I kernel più vecchi, o kernel configurati in determinati modi, potrebbero non supportare questa combinazione. Il protocollo NFS non supporta il passaggio del flag al server, quindi O_DIRECT I / O ignorerà solo la cache della pagina sul client; il server può ancora memorizzare nella cache l’I / O. Il client chiede al server di rendere l’I / O sincrono per preservare la semantica sincrona di O_DIRECT. Alcuni server funzioneranno male in queste circostanze, specialmente se la dimensione I / O è piccola. Alcuni server possono anche essere configurati per mentire ai client in merito all’I / O che ha raggiunto una memoria stabile; ciò eviterà la penalizzazione delle prestazioni a rischio di integrità dei dati in caso di interruzione dell’alimentazione del server. Il client NFS Linux non pone restrizioni di allineamento su O_DIRECT I / O.

In breve, O_DIRECT è uno strumento potenzialmente potente che dovrebbe essere usato con caucanvas. Si raccomanda che le applicazioni trattino l’uso di O_DIRECT come opzione di prestazioni che è disabilitata per impostazione predefinita.

“La cosa che mi ha sempre turbato su O_DIRECT è che l’intera interfaccia è semplicemente stupida, ed è stata probabilmente progettata da una scimmia squilibrata su alcune sostanze che controllano la mente”. — Linus

AFAIK, O_DIRECT ignora la cache della pagina. O_SYNC utilizza la cache della pagina ma la sincronizza immediatamente. La cache della pagina è condivisa tra i processi, quindi se c’è un altro processo che sta lavorando sullo stesso file senza il flag O_DIRECT può leggere i dati corretti.