Facoltà di Ingegneria Corso di Studi in Ingegneria Informatica Elaborato finale in Sistemi Operativi Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) Anno Accademico 2012/2013 Candidato: Jacopo Russo matr. N46000142 Ai miei amici, senza di loro non ce l’avrei fatta Indice Introduzione 5 Capitolo 1. Journaling File System classici 7 1.1 1.1.1 1.1.2 1.1.3 1.1.4 1.2 1.2.1 1.2.2 1.2.3 NTFS Struttura ed utilizzo del log Checkpointing Ripristino Riempimento del log Ext4 Struttura ed utilizzo del journal Checksumming Critiche 9 9 10 11 11 12 12 13 14 Capitolo 2. Journaling File System alternativi: COW based 16 2.1 2.2 2.2.1 2.2.2 2.2.2 2.2.3 2.2.4 2.2.5 2.2.6 2.3 2.3.1 2.2.2 2.2.2 2.2.3 Copy-on-write ZFS Struttura Checksum end-to-end Ripristino Silent data corruption RAID-Z Resilvering Riepilogo Btrfs Struttura Checksum Aggiornamento dei dati e ripristino Fsync 16 17 18 19 20 20 21 21 22 23 23 25 25 26 Capitolo 3. Journaling File System alternativi: flash oriented 27 3.1 3.2 3.3 28 30 31 NILFS UBIFS YAFFS III Capitolo 4. Confronto fra le soluzioni proposte 33 Conclusioni Bibliografia 35 36 IV Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) Introduzione Quando viene a mancare l’alimentazione in un sistema informatico tutte le operazioni che hanno luogo al suo interno vengono bruscamente interrotte, senza che vi sia un esplicito comando di terminazione. In tali circostanze alcune componenti possono continuare a lavorare più a lungo rispetto ad altre, come ad esempio accade per i dispositivi di memorizzazione. Le memorie volatili, non aggiornate propriamente, vedranno un rapido degrado dei dati contenuti in esse. Allo stesso tempo i dispositivi di memorizzazione fissa ed i moduli DMA manifesteranno una durata residua leggermente superiore. Se si dovesse manifestare un calo di tensione contestualmente alla scrittura sul disco, si avrebbe la memorizzazione di una certa quantità di dati corrotti, nonché la perdita di tutte le informazioni parzialmente sovrascritte. La suscettibilità agli arresti improvvisi rappresenta un problema ancora più critico per file system che fanno ricorso a tecniche di codifica. In questo caso, infatti, la variazione indesiderata di un singolo bit implica la perdita dell’intera informazione memorizzata. Un primo approccio al problema fu rappresentato negli anni ’80 dall’implementazione di tool dedicati al recupero della consistenza dei dati, come fsck (File System Check) per i sistemi Unix e dal suo equivalente per i sistemi Windows, chkdsk (CHecK DiSK). Tali tool prevedono la scansione dell’intero volume di memorizzazione alla ricerca di file o directory che non possono essere ricollocati automaticamente nella gerarchia di 5 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) indicizzazione del sistema. In una seconda fase, se non avesse successo una riparazione automatica basata sui dati contenuti nel file system, sarebbe demandato all’amministratore del sistema il ripristino di tali collegamenti. Un approccio di questo tipo ha tuttavia manifestato nel tempo pesanti limitazioni: La durata della fase di scansione dipende fortemente dalla dimensione del disco (condizione resa insostenibile dalle crescenti dimensioni dei dispositivi di memorizzazione). Scansione e riparazione dei file danneggiati sono eseguibili solo su file system offline, o comunque impostati in sola lettura. Tali restrizioni hanno portato allo sviluppo di nuove politiche di gestione dei dati, capaci di assicurare un certo livello di affidabilità. Saranno in seguito trattati diversi file system relativi a variegati ambienti ed esigenze, ma legati da un filo comune: tutti pongono le basi sul meccanismo del transaction processing. Un sistema transazionale mira a conservare l’integrità di un insieme di dati assicurando che l’esecuzione di operazioni interdipendenti sia completata integralmente oppure totalmente abortita. Un file system transazionale ha a disposizione gli strumenti adatti per far fronte a guasti improvvisi: l’invalidamento di tutte le transazioni completate in modo parziale ha l’effetto di riportare il sistema ad uno stato consistente precedente al sopraggiungimento del guasto, come se quest’ultimo non si fosse mai verificato. 6 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) Capitolo 1 Journaling File System Classici Un journaling file system presenta fra le sue principali caratteristiche la capacità di tenere traccia dell’evoluzione dello stato del sistema, in modo da garantire in ogni momento la consistenza delle informazioni in esso contenute. Ciascuna operazione dedicata alla modifica dei dati contenuti sul disco è accompagnata dalla sua annotazione su un diario (detto journal), costituito da un registro circolare allocato in una particolare area di memorizzazione. Periodicamente le modifiche annotate sul diario vengono riversate sul disco, in modo tale da costituire un punto di ripristino consultabile dal sistema in seguito ad eventi di arresto inaspettato, per riportare lo stesso ad uno stato consistente. Ad una prima analisi sembrerebbe lecito sollevare una maliziosa osservazione: ciò non equivale forse a spostare il problema dell’inconsistenza dal file system al journal stesso? Ciò tuttavia non trova riscontro nella realtà, poichè se si verificasse un guasto proprio durante la scrittura del journal verrebbero semplicemente ignorate tutte le transazioni ad esso inerenti, lasciando il sistema in uno stato non aggiornato, ma pur sempre integro. È possibile distinguere diverse categorie di journaling in base alla valutazione di due parametri : come si tiene traccia delle transazioni, e cosa viene annotato nel diario. In base al primo parametro si differenziano : Journaling fisico : il sistema tiene traccia del contenuto dei blocchi fisici coinvolti nell’operazione (la descrizione si attesta a livello di memorizzazione). 7 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) Journaling logico : il sistema registra quali modifiche verranno apportate in termini di operazioni logiche. (vengono annotati cambiamenti al livello del file system). Relativamente al secondo parametro sono classificate, in ordine di affidabilità : Modalità writeback : si tiene nota dei soli metadati del file system, ed i blocchi dati vengono scritti nelle loro locazioni, senza che vi sia ordine tra le due operazioni. Coi comporta discreti vantaggi prestazionali, al costo di una garanzia di integrità molto debole (se venissero registrati in memoria prima i metadati e poi i dati, un guasto fra le due operazioni renderebbe questi ultimi irrecuperabili). Modalità ordinata : simile alla precedente, essa impone la scrittura ordinata dei dati, seguita dall’aggiornamento del journal. Anche in questo caso l’annotazione riguarda solo le modifiche apportate ai metadati. Modalità dati : il journal contiene informazioni sulle modifiche dei metadati e dei dati. Si garantisce la massima protezione contro la corruzione dei dati, al costo di un ingente degrado delle prestazioni (il numero delle operazioni di scrittura viene di fatto raddoppiato). Figura 1: Modalità di journaling. 8 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) L’operazione che conferma l’avvenuto completamento di una transazione è detta commit, Il commit del journal stesso, ovvero l’operazione di trascrizione di quest ultimo sul disco, può essere innescato da diversi fattori come lo scadere di un timeout oppure l’esaurimento dello spazio in memoria dedicato al journal. È possibile che, per ragioni di throughput, il sistema operativo attui delle politiche di riordino delle operazioni di scrittura (e.g. algoritmo dell’ascensore), a prescindere dalla modalità di journaling adottata. Per di più molti dispositivi di archiviazione sono dotati di cache di scrittura dedicate, gestite attraverso ulteriori politiche di riordinamento. Per ovviare a tale inconveniente alcuni file system sacrificano le proprie performance per assicurare un corretto ordine delle operazioni attraverso l’imposizione al dispositivo di memorizzazione di barriere di sincronizzazione. 1.1 NTFS NTFS (New Technology File System) è stato presentato da Microsoft nel 1993 per il sistema operative windows NT 3.1. Nonostante non siano pubblicamente reperibili codice sorgente o documentazione di NTFS, studi di ingegneria inversa hanno delineato la struttura adottata per l’implementazione del journaling. Tale file system considera ogni oggetto come file, perfino i metadati. Lo stesso journal è un file (Log file), collocato al centro del file system. L’implementazione adottata si basa sul meccanismo del journaling logico, dedicato ai metadati in modalità ordinata, ottenuta mediante l’applicazione di un ritardo forzato sulle operazioni di scrittura. La gestione del journal è affidata al Log File Service (LFS), che implementa le routine del kernel necessarie all’aggiornamento del journal ed al servizio di ripristino del sistema. 1.1.1 Struttura ed utilizzo del log Il file di log è suddiviso in due regioni: l’area di riavvio (restart area) e l’area di annotazione (logging area). LFS viene richiamato dal file system per leggere o scrivere la restart area, nella quale sono contenute le informazioni utili ad un’eventuale operazione di ripristino, come ad esempio la locazione della logging area dalla quale cominciare a 9 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) leggere. LFS memorizza anche una seconda copia della restart area, in modo da poter far fronte all’ipotizzabile corruzione della prima copia. La logging area è strutturata come una coda circolare (per tale motivo è detta anche “infinite” logging area), nella quale ogni elemento è contrassegnato da un Log Sequence Number (LSN), e possiede due update record (redo information, undo information). Figura 2:Struttura del log NTFS LFS memorizza nella logging area un record per ciascuna sub-operazione che che compone una transazione. Tale record contiene le informazioni utili a riapplicare tutte le transazioni correttamente concluse (redo information) e riavvolgere quelle parzialmente completate (undo information). Nuovi update record vengono aggiunti all’atto di creazione, cancellazione, troncamento, rinominazione o cambiamento degli attributi di un file. Figura 3:Struttura della logging area 1.1.2 Checkpointing Per facilitare l’operazione di ripristino, evitando di scorrere l’intera logging area, NTFS implementa un meccanismo di checkpoint. Ogni otto secondi1 viene salvato un particolare record di checkpoint nella logging area, ed il suo LSN viene salvato nella restart area. In 1 Charles M. Kozierok, “The PC Guide”, 2001 10 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) questo modo LFS, una volta richiamato, potrà usare tale LSN per trasferire dalla memoria centrale al disco un certo numero di record, per poi effettuare un operazione di commit sul journal. Figura 4:Checkpointing NTFS 1.1.3 Ripristino In caso di arresto inaspettato del sistema, NTFS provvederà all’avvio della procedura di ripristino, scandita dai seguenti passi: NTFS legge la Master File Table (MFT) ed avvia il LFS LFS accede al log e legge dalla restart area l’LSN relativo all’ultimo checkpoint Viene effettuata una fase di redo. Alla fine di essa, la cache riflette lo stato del dispositivo quando è avvenuto il crash. Viene effettuata una fase di undo. Alla fine di essa il dispositivo è ripristinato ad uno stato consistente. 1.1.4 Riempimento del log L’implementazione della logging area mediante l’uso di un buffer circolare può portare ad una situazione di saturazione dello stesso. Questo fenomeno è gestito da NTFS attraverso il lancio di un’eccezione volta a bloccare tutte le transazioni in atto, che saranno riprese successivamente, e riavvolgere quelle parzialmente completate. In questo modo il sistema avrà modo di svuotare le proprie cache (journal compreso) sul disco e riprendere le transazioni poste in attesa, sfruttando un log stavolta vuoto. 11 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) 1.2 ext4 Ext4, o fourth extended file system, è stato presentato nel 2008 per il sistema operativo Linux. Esso riprende la struttura base del suo predecessore ext3 (già dotato di journaling), introducendo diverse caratteristiche aggiuntive, tra le quali il meccanismo del checksumming, volto a rafforzare l’integrità dei dati. Così come ext3, ext4 supporta tutte le modalità di journaling (data, writeback, ordered), applicata ai blocchi (journaling fisico). Come già accennato, ciò comporta un maggiore grado di affidabilità, al prezzo di un maggior overhead – poichè la struttura di ext4 è basata su inode, la cui dimensione è inferiore al blocco, la variazione di un singolo bit in un singolo inode si traduce nella copia sul journal dell’intero blocco, contenente anche gli inode vicini, non implicati nell’operazione. 1.2.1 Struttura ed utilizzo del journal Identicamente ad NTFS, il journal ext4 è un file, residente all’interno del file system (comunemente) – è prevista la possibilità di memorizzare il journal anche su un diverso supporto. Il journal è strutturato in blocchi di diversa tipologia: Superblock, che mantiene informazioni sul journal stesso, come la dimensione dei blocchi di cui è composto; il numero totale di blocchi a disposizione; la locazione dove effettivamente inizia il journal; il numero di sequenza della prima transazione e la sua locazione in memoria. Descriptor block, ogni transazione contiene una descrizione delle locazioni finali dei blocchi dati che seguono nel journal. Metadata block, uno o più per ogni transazione. È qui che vengono registrate le modifiche apportate al sistema. Nel caso in cui si adotti il data journaling, tali blocchi rispecchiano anche i dati coinvolti nella scrittura. Commit block, indica la terminazione di una transazione effettuata con successo. 12 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) Revoke block, contenente la lista dei blocchi che non dovrebbero essere riscritti nel file system, per esempio nel caso in cui vi sia una dipendenza ciclica tra due transazioni,ed una di esse non sia stata ancora confermata nel journal. In ogni caso tali blocchi possono essere scritti sul disco nel caso in cui il sequence number sia più alto rispetto a quello del revoke block. Figura 5: struttura del journal ext4 Tutti i blocchi descritti, fatta eccezione per i metadata, sono detti blocchi amministrativi e condividono nei primi 12 byte un header di identica struttura. Il sistema tratta tutte le operazioni in esecuzione come un’unica transazione globale. Nonostante ciò si rifletta in un miglioramento delle prestazioni, è possibile che dia luogo a raggruppamenti di operazioni incorrelate, che possono portare ad un intreccio tra traffico sincrono ed asincrono nel file system. Le politiche di commit e di checkpiont delle transazioni variano in base a tre fattori: richiesta di sincronizzazione da parte di un’applicazione; dimensione del diario; impostazione del timer di commit. 1.2.2 Checksumming Il meccanismo di checksum aggiunto in ext4 permette di rilevare più facilmente fenomeni di corruzione dei dati riguardanti il journal stesso, reso vulnerabile dalle continue operazioni di scrittura ad esso applicate. Inoltre rende più efficienti le meccaniche di annotazione del sistema, introducendo sostanziali miglioramenti delle performance. Durante le normali operazioni di journal, il blocco di commit viene scritto solo quando tutte le informazioni su header e metadati sono state registrate (commit a due fasi); e la transazione successiva dovrà attendere tale commit per poter procedere. Una transazione è giudicata ripetibile solo se header e commit block hanno lo stesso transaction number. 13 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) La situazione cambia con l’adozione del checksumming: viene generato un CRC32 sul gruppo di blocchi che compone la transazione, che sarà registrato all’interno del blocco di commit. Se in fase di ripristino dovesse fallire il controllo su tale checksum, l’intera transazione verrebbe scartata. In questo modo viene meno l’esigenza di un commit a due fasi per ogni transazione: il blocco di commit può essere scritto contemporaneamente agli altri, comportando un sensibile miglioramento delle prestazioni del file system (intorno al 20%2), contrariamente a quanto potrebbe far intuire l’introduzione di un campo aggiuntivo. 1.2.3 Critiche Per migliorare le prestazioni in fase di scrittura ext4 utilizza la tecnica dell’allocazione ritardata (allocate-on-flush): l’allocazione dei blocchi avviene in due fasi (prenotazione ed allocazione), in modo tale da mantenere i dati quanto più possibile nella cache. Molti file infatti hanno vita breve, ed in questo modo è possibile farne uso senza doverli allocare sul disco. Anche i file più “longevi” traggono vantaggio da questa tecnica poiché il kernel ha a disposizione più dati da poter allocare in maniera contigua, riducendo sensibilmente la frammentazione e velocizzando di conseguenza le operazioni di lettura e scrittura. L’allocazione ritardata presenta tuttavia dei forti effetti collaterali: il mantenimento prolungato dei dati all’interno della cache non fa altro che vanificare gli sforzi compiuti dal meccanismo di journaling per preservarne la consistenza: a favore delle performance si va a contrastare il processo di allocazione ordinata, permettendo che la scrittura dei metadati anticipi quella dei dati ad essi afferenti. Linus Torvalds, coordinatore del progetto di sviluppo Linux, ha espresso tutto il suo turbamento riguardo l’introduzione dell’allocazione ritardata nella mailing list degli sviluppatori Linux: 2 Vijayan Prabhakaran, Lakshmi N. Bairavasundaram, Nitin Agrawal, Haryadi S. Gunawi, Andrea C. Arpaci-Dusseau, and Remzi H. Arpaci Dusseau. Iron file systems, 2005. 14 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) "Doesn't at least ext4 default to the insane model of 'data is less important than metadata, and it doesn't get journalled'? And ext3 with 'data=writeback' does the same, no? Both of which are -- as far as I can tell -- total brain damage. At least with ext3 it's not the default mode.[…] if you write your metadata earlier (say, every 5 sec) and the real data later (say, every 30 sec), you're actually more likely to see corrupt files than if you try to write them together... This is why I absolutely detest the idiotic ext3 writeback behavior. It literally does everything the wrong way around -- writing data later than the metadata that points to it. Whoever came up with that solution was a moron. No ifs, buts, or maybes about it."3 “ext4 non aderisce come minimo al folle modello de ‘i dati sono meno importanti dei metadati, e non c’è bisogno di annotarli’? Ed ext3 con ‘data=writeback’ non fa lo stesso? Entrambi sono -- per quanto ne sappia – una totale offesa all’intelligenza. Almeno in ext3 non è la modalità predefinita.[…] scrivendo i metadati prima (ad esempio, ogni 5 sec) e i veri dati dopo (ad esempio, ogni 30 sec), sarai più propenso a vedere dati corrotti piuttosto che se provi a scriverli insieme… È per questo che io detesto assolutamente il comportamento idiota del writeback di ext3. Fa letteralmente le cose al contrario – scrivendo i dati dopo dei metadati che puntano ad essi. Chiunque sia giunto a questa conclusione era un imbecille. Senza se, ma, o forse al riguardo.” 3 Britta Wuelfing. Linus Torvalds Upset over Ext3 and Ext4, 2009. 15 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) Capitolo 2 Journaling File System Alternativi: COW based Oltre ai classici meccanismi di journaling, è possibile identificare diverse soluzioni volte a garantire l’integrità dei dati costituenti un file system. A differenza di quanto visto finora riguardo tecniche esplicite per il trattamento delle informazioni di gestione, alcuni file system di recente implementazione realizzano un approccio basato sui meccanismi fondamentali di memorizzazione. Tratteremo in questo capitolo due dei maggiori esponenti della filosofia copy-on-write attualmente sul mercato: ZFS e btrfs. 2.1 Copy-on-write Il principio del copy-on-write (spesso abbreviato COW) pone le sue basi nell’ambito della programmazione concorrente: consentire a diversi processi l’accesso alla medesima risorsa, fornendo a ciascuno un riferimento ad essa. Una eventuale modifica della risorsa condivisa non sarà tradotta nella sovrascrittura del dato originale, bensì darà luogo ad una nuova versione di esso, memorizzata in una locazione diversa dalla precedente. Figura 6: modifica copy-on-write di un nodo in una struttura ad albero (es. nodo 34) 16 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) Una implementazione possibile del copy-on-write si può ottenere comunicando alla MMU che determinate pagine nello spazio di indirizzamento sono a sola lettura. Un’operazione di scrittura su di esse solleverà un’eccezione gestita dal kernel, che allocherà nuovo spazio in memoria dove saranno depositate le nuove copie. Applicato al contesto d’analisi, tale meccanismo consente al file system di tenere traccia delle modifiche apportate ad esso (mediante snapshots, ovvero “istantanee” dello stato del sistema precedenti a determinate operazioni). È possibile riportare il sistema ad uno stato consistente a fronte di un guasto improvviso semplicemente spostando i riferimenti di un file danneggiato all’ultima versione “sana” contenuta in memoria. Sotto queste ipotesi viene meno la necessità di annotare esplicitamente le modifiche apportate al sistema: il file system implementa la strategia di ripristino nella struttura stessa che lo compone. 2.2 ZFS ZFS (Zettabyte File System) è un file system open source sviluppato dalla Sun Microsystems per il suo sistema operativo Solaris, rilasciato nel novembre 2005. I princìpi alla base di tale file system traggono la loro ispirazione da diversi prodotti già sul mercato, come l’uso di snapshots di Network Appliance, la gestione object-oriented della memoria e l’utilizzo di transazioni e checksum di Veritas. La struttura di ZFS è data dalla combinazione di un file system ed un volume manager. Le istruzioni del file system non necessitano della conoscenza dei dettagli dell’effettivo livello fisico sottostante, poichè quest’ultimo viene virtualizzato. Le interazioni di alto livello sono gestite da una Data Management Unit (DMU) - un concetto molto simile all’MMU, applicato ai dischi. Tutte le transazioni effettuate attraverso la DMU sono considerate atomiche, a garanzia della consistenza dei dati. 17 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) Figura 7: Virtualizzazione della memoria in ZFS 2.2.1 Struttura La struttura adottata da ZFS per la memorizzazione delle informazioni è costituita da un albero di blocchi, ed il meccanismo delle transazioni è associato a quello del copy on write, per cui nuove informazioni sono scritte su blocchi diversi, ed il puntatore al dato in uso è aggiornato solo all’atto di conferma della transazione. Tale evento si ripete sull’intera gerarchia del file system, fino al nodo principale, detto uberblock. Figura 8: Aggiornamento di un blocco in ZFS 18 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) 2.2.2 Checksum end-to-end Molti file system che implementano il meccanismo di checksum garantiscono un’integrità dei dati solo parziale, poichè memorizzano tale valore all’interno del blocco che contiene l’informazione stessa da proteggere. Ciò non permette di far fronte a problemi come: Operazioni di scrittura fantasma, nelle quali i dati (e quindi le checksum) non vengono effettivamente scritti. Operazioni di lettura/scrittura indirizzate in maniera errata. Errori di parità generati durante un trasferimento dati da/verso il DMA. Errori dei driver, per i quali i dati vengono depositati in buffer errati. In ZFS tutti i puntatori ai blocchi contengono un campo checksum di 256 bit, relativo al blocco puntato. La gerarchia di checksum forma un albero di Merkle auto-validante; solamente l’uberblock contiene una checksum relativa a se stesso. In un implementazione che sfrutta RAID-Z, di cui discuteremo in seguito, tale meccanismo permette la rigenerazione automatica dei dati. I puntatori ai blocchi utilizzati contengono fino a tre indirizzi, detti DVA (Data Virtual Addresses), riferiti a blocchi differenti che contengono gli stessi dati, detti ditto blocks. La politica standard di ZFS prevede l’uso di un DVA per i dati, due per i metadati del file system, e tre per i metadati globali, comuni a tutte le istanze del file system. Indipendentemente dal numero di DVA, ogni puntatore ad un blocco contiene una singola copia della checksum. Figura 9: Struttura di un puntatore a blocco 19 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) 2.2.3 Ripristino Il meccanismo di aggiornamento dal basso verso l’alto della struttura ad albero, associata all’implementazione di una politica di checksum separate dai dati stessi rende il meccanismo di ripristino semplice ed al cotempo efficace: in fase di montaggio del file system viene ripercorso l’intero albero a partire dall’uberblock. Il controllo della checksum precede ogni passaggio ad un blocco successivo. Nel caso in cui tale controllo dovesse fallire, l’albero verrebbe “potato” del ramo non valido, sostituito da un ditto block, oppure da una versione “più vecchia” del blocco stesso. Tutti i blocchi in ZFS sono infatti marcati con un parametro temporale, detto “birth time”, che identifica il gruppo di transazione al quale appartiene il blocco. Figura 10: blocchi ZFS identificati attraverso il birth time 2.2.3 Silent data corruption Oltre a garantire l’integrità dei dati in caso di guasto, ZFS propone soluzioni per la gestione della corruzione “silente” dei dati. Studi statistici condotti da alcune case produttrici di sistemi di memorizzazione e dal CERN hanno infatti dimostrato che si verifica un errore non rilevabile dai dispositivi ogni 1016 bit4 a causa di difetti associati a dischi, controllori, cavi, driver o firmware. Ciò rappresenta un problema rilevante per sistemi come i database server che gestiscono 4 Bernd Panzer-Steindel. "Draft 1.3". Data integrity. CERN. 20 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) ingenti moli di dati: il creatore di ZFS, Jeff Bonwick ha affermato che il database della Greenplum – importante database software company americana – affronta la corruzione silente ogni 15 minuti5. 2.2.4 RAID-Z Per assicurare l’integrità dei dati soggetti a corruzione silente, ZFS implementa una funzionalità nota come RAID-Z. Tale soluzione è simile a quella offerta da RAID-5, ma a differenza di esso fa uso di strisce a dimensione variabile, in modo tale da risolvere il problema del “write hole”: in RAID-5 le operazioni di scrittura sono indipendenti, effettuate in su maniera più non dischi atomica. Un’interruzione di servizio tra la scrittura dei dati e del blocco di parità ha come risultato la memorizzazione di dati corrotti. Figura 11: strisce RAID-Z a dimensione variabile Al contrario, la scrittura di una striscia RAID-Z è atomica, ed essendo basata sul copy-onwrite, non necessita di un ciclo read-modify-write. La complessità di RAID-Z si riflette tuttavia nel processo di ricostruzione dei dati: poiché le strisce non sono di dimensione fissa, non è possibile determinarne immediatamente la geometria, bensì è necessario ripercorrere tutti i metadati del file system (ciò può risultare oneroso rispetto al RAID classico). 2.2.5 Resilvering In uno scenario RAID tradizionale, la ricostruzione di un dispositivo danneggiato si effettua mediante una elaborazione integrale del disco (mediante un’operazione di XOR), 5 "A Conversation with Jeff Bonwick and Bill Moore". Association for Computing Machinery. November 15, 2007. 21 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) anche se quest’ultimo è quasi vuoto, e senza che vi sia cognizione di cosa si stia riparando. Il resilvering RAID-Z, al contrario, prevede che sia percorso l’albero di sistema a partire dall’uberblock, in modo da dare priorità ai blocchi più importanti, ed evitare di lavorare su quelli non in uso, ottenendo un notevole risparmio di tempo. Per il recupero di una transazione può essere utilizzato il dirt time logging (DTL): il sistema tiene traccia del tempo di inattività del disco danneggiato, e nella fase di ripristino provvede alla riapplicazione delle transazioni avvenute in questa finestra temporale, se registrate sugli altri dischi del pool RAID. 2.2.6 Riepilogo Per ragioni di chiarezza, procediamo ad un riepilogo delle potenzialità di protezione offerte da ZFS: Qualunque sia la configurazione dei dischi, gli errori che si presentano sia sui blocchi dati che sui blocchi metadati sono sempre rilevati, grazie alle checksum. Una configurazione basata su un singolo disco o su più dischi che adottano tecniche di memorizzazione “a strisce” permette il ripristino dei blocchi metadati, mentre per i dati è necessario l’utilizzo dei ditto blocks. Una configurazione basata su più dischi ridondanti (RAID-Z) permette il ripristino del contenuto di qualunque tipo di blocco. 22 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) 2.3 btrfs Btrfs (B-tree file system, o “Butter FS”) è un file system annunciato da Oracle Corporation nel 2007 (non ancora rilasciato in versione stabile) per il sistema operativo Linux. Esso si distingue dai suoi omologhi (soprattutto ZFS) per il pregio di conciliare la struttura B-tree (Particolarmente performante, in termini di tempi di ricerca, scrittura e cancellazione) con il meccanismo del copy-on-write. Ogni informazione, che si tratti di inode, file dati, cartelle, bitmap è generalizzata come “oggetto”. In questo modo tutte le operazioni di lettura/scrittura all’interno della struttura ad albero sulla quale si regge btrfs condividono lo stesso codice, indipendentemente dalla tipologia di file coinvolta. 2.3.1 Struttura Tale file system è strutturato come una “foresta” di composizioni ad albero. Il blocco principale, detto superblock, posizionato in una locazione di memoria fissa, funge da punto d’innesto. Esso punta ad un albero delle radici, che indicizza gli alberi che costituiscono il file system vero e proprio. Figura 12: struttura “a foresta” di btrfs 23 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) All’interno di ogni albero è possibile distinguere due “sottostrutture”: una superiore, costituita dai nodi ramo, ed una inferiore, data dai nodi foglia. Tutti i nodi appartenenti alla sezione superiore sono costituiti esclusivamente da una coppia (chiave, puntatore), dove il primo elemento è utilizzato per indicare la direzione da intraprendere per continuare a percorrere l’albero, ed il secondo rappresenta l’effettivo indirizzo in memoria del blocco successivo. I nodi della struttura inferiore contengono gli oggetti (citati precedentemente), dati dalla combinazione di header, usati per specificare il tipo di oggetto memorizzato, e dei dati associati ad ogni oggetto. Header e dati sono depositati rispettivamente all’inizio ed alla fine del blocco, in modo tale che crescano l’uno verso l’altro. Figura 13: blocco dati btrfs Un’architettura di questo tipo porta con se, rispetto alle strutture tradizionali, un risparmio di spazio (in un unico blocco è possibile memorizzare diversi tipi di informazioni) e di tempo (l’accesso ad una particolare sezione di un file non richiede l’accesso a diversi tipi di metadati, posizionati in diverse locazioni del file system). 24 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) Figura 13-15: confronto fra allocazione tradizionale e btrfs 2.3.2 Checksum Nella struttura principale di btrfs è contemplata la presenza di un albero dedicato esclusivamente alle checksum. Ogni oggetto di questo tipo è riferito ad un particolare extent (che in btrfs equivale a 4kb) e contiene una lista di checksum associate ai vari blocchi.In questo modo viene implementata, al pari di ZFS la separazione fra i dati e le checksum relative ad essi. 2.3.3 Aggiornamento dei dati e ripristino La modifica di file o directory da luogo una scrittura copy-on-write di nodi foglia, che innesca un aggiornamento a catena di tutti i rami sovrastanti fino al nodo radice. Ogni albero contenente informazioni sul file modificato sarà coinvolto in questo processo. Tali modifiche vengono accumulate in memoria ed in seguito ad un timeout (di default 30 sec), o al raggiungimento di una certa soglia quantitativa sono scritte in batch nelle nuove locazioni del disco, creando un checkpoint. A questo punto viene modificato il superblock in modo tale che faccia riferimento al nuovo checkpoint. Questa è l’unica situazione in cui un blocco del disco viene sovrascritto. Per questo motivo l’integrità dell’intero sistema è garantita dalla presenza di più copie del superblock, posizionate in varie regioni del disco (64KiB, 64MiB, 256GiB, 25 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) 1PiB). In fase di aggiornamento, viene incrementato un campo generation number, in modo tale che in fase di montaggio venga scelto il blocco che possiede il valore più alto. Figura 16: aggiornamento di un file in btrfs Tutte le copie del superblock vengono aggiornate in tandem. Se dovesse verificarsi un arresto improvviso del sistema, il file system ripristinerebbe lo stato leggendo il superblock più recente, e seguirebbe i riferimenti fino all’ultimo checkpoint valido sul disco. Ciascun nodo registra infatti il generation number in uso al momento della propria creazione, in modo da poter essere associato ad un dato checkpoint. Inoltre ad ogni puntatore al successivo nodo è affiancato il valore del generation number atteso, in modo da rilevare scritture fantasma o maldirette sul disco. In sintesi, la verifica del contenuto di un blocco è possibile grazie all’utilizzo congiunto di generation number e checksum. 2.3.4 Fsync Per sopperire all’elevata latenza caratteristica del checkpointing, btrfs offre una funzionalità aggiuntiva volta a garantire una sincronizzazione orientata ad un singolo file, detta fsync. Le modifiche al file system comportate dalla modifica del file sono annotate in uno speciale albero di log. Al verificarsi di un’anomalia, l’albero di log viene letto come parte della sequenza di ripristino. 26 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) Capitolo 3 Journaling File System Alternativi: Flash oriented Lo sviluppo di nuove tecnologie nel campo dei supporti di memorizzazione sta compiendo grandi passi avanti. L’idea comune è che l’utilizzo dei classici dischi rigidi rappresenti uno stop-gap in termini di tempi di elaborazione, a causa delle latenze determinate dai processi di seek associati alla natura meccanica del supporto. Un’alternativa concreta è rappresentata dalle memorie flash, basate su MOSFET e largamente utilizzate nel settore dei dispositivi portatili, come palmari, lettori MP3, smartphone, fotocamere digitali. Esistono principalmente due tipologie di memorie flash, dette NOR e NAND, che differiscono per l’architettura ed il procedimento di programmazione. A dispetto di alte velocità in lettura e scrittura, tuttavia tali supporti presentano dei limiti comuni (che necessitano di particolari strategie di gestione): la scrittura di un blocco richiede necessariamente la previa cancellazione dello stesso. Per di più tale operazione richiede un tempo superiore a quello di una semplice scrittura di almeno un ordine di grandezza, e può essere eseguita un numero limitato di volte (tipicamente 10 3 - 106 ) prima che la cella diventi inutilizzabile. In un simile scenario molte delle politiche adottate dai tradizionali file system divengono inadatte, se non addirittura dannose. Allo stesso tempo nasce la necessità di implementarne di nuove, delle quali due sono fondamentali: 27 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) Garbage collection: dati obsoleti necessitano di essere cancellati per rendere disponibile nuovo spazio in memoria (essenziale per tecniche di memorizzazione “out of place”). Contemporaneamente i blocchi soggetti a frequenti operazioni di lettura tendono a dissipare i dati contenuti. L’algoritmo di garbage collection mira a spostare il contenuto valido dei blocchi in nuove locazioni, eliminando i dati non più necessari. Wear Leveling: per contrastare lo sviluppo del deterioramento delle celle sottoposte a cicli di lettura-cancellazione-scrittura si punta ad un utilizzo equamente distribuito della memoria, in modo da rallentare il processo di “invecchiamento” del supporto Tratteremo brevemente tre file system di ultima generazione, progettati per essere tolleranti alle interruzioni improvvise dell’alimentazione, in un ambiente basato su memorie flash: NILFS, UBIFS, YAFFS. 3.1 NILFS NILFS (New Implementation of a Log-structured File System) è un file system sviluppato dalla Nippon Telegraph and Telephone Corporation (NTT) per il sistema operativo Linux, rilasciato nel 2005. L’architettura di NILFS è realizzata dalla sovrapposizione di più strutture: l’archivio fisico vero e proprio, un b-tree dedicato all’allocazione dei dati, un altro b-tree per gli inode. Per ragioni di compattezza e di attinenza al soggetto di studio non saranno esposte tali strutture nel dettaglio, per maggiori approfondimenti è consigliata la lettura di “The NILFS version 1: overview” a cura del team di sviluppo NILFS. Per garantire un elevato livello di affidabilità viene adottata al livello fisico una struttura “a log” (tipica di flash file systems “storici”, come JFFS): la memorizzazione dei blocchi, indipendentemente dal contenuto, avviene in maniera contigua, ed il dispositivo flash è visto come un log circolare. In tal modo i file non sono aggiornati per sovrascrittura, permettendone la co-esistenza di diverse versioni. 28 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) Figura 17: Log-structured file system Il layout del disco comprende: Superblock: contiene i parametri del file system, l’indirizzo sul disco dell’ultimo blocco scritto, la radice del b-tree adottato logicamente dal sistema. Data la sua importanza, il superblock è replicato su un altro blocco del disco. Full segment: gruppo di blocchi del disco, di lunghezza fissata. Costituisce l’unità base del garbage collector. Partial segment: unità di scrittura del sistema. Logical segment: sequenza inseparabile di partial segments, rappresenta una transazione Figura 1148: Layout NILFS 29 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) Ogni partial segment consiste di tre sezioni: Segment summary: contiene informazioni utili sull’utilizzo del blocco, tra le quali una checksum dell’area dati. Area dati. Checkpoint: posto in coda al segmento, contiene una checksum del checkpoint stesso, ed un block number relativo alla radice dell’inode b-tree. Tale informazione viene scritta per ultima, ed aggiorna lo stato dell’intero file system. Riassumendo, le seguenti funzioni garantiscono l’affidabilità del file system: Checksum: non esistono checksum per i blocchi individuali, bensì il tool newfs genera casualmente ad ogni transazione un numero a 32 bit e lo deposita nel superblock. Tale numero è utilizzato come valore iniziale dall’algoritmo CRC32 per generare le checksum. Il processo di ripristino controllerà la validità delle checksum confrontandole al valore contenuto nel superblock Scrittura ordinata: Tutti i blocchi vengono scritti secondo il seguente ordine: I blocchi dati sono memorizzati sul disco, seguiti dai nodi del b-tree dei dati, dai blocchi inode, ed infine i nodi del btree relativo agli inode. Sovrascrittura minimizzata: Gli unici blocchi ad essere sovrascritti sono il superblock, le sezioni di uso dei segmenti (non trattate in questo discorso), e le loro repliche. 3.2 UBIFS UBIFS (Unsorted Block Image File System) è un file system sviluppato da NOKIA, in collaborazione con l’università di Szeged (Ungheria) e rilasciato nel 2008 per il sistema operativo Linux. Tale file system lavora al di sopra di uno strato detto UBI (Unsorted Block Image), che si occupa di gestire il wear leveling attraverso propri meccanismi di amministrazione della memoria fisica, e offre al livello superiore dei blocchi di memorizzazione logica, detti 30 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) LEB (Logical EraseBlocks), propriamente mappati su quelli fisici. UBIFS adotta una struttura B+tree (al pari di btrfs), e memorizza la posizione del nodo radice in un master node, che tiene traccia di tutte le strutture che non sono allocate in posizioni logiche fisse. Per facilitare le strategie di recupero dai guasti, vengono memorizzate due copie del master node. All’atto di creazione del file system vengono distinte sei partizioni fisse. Una di queste è detta area di log (o più semplicemente log). Esso è una parte del journal di UBIFS, usato per ridurre la frequenza di aggiornamento dei rami del b-tree. I nuovi nodi foglia sono memorizzati nel journal e, periodicamente, quando quast’ultimo è considerato ragionevolmente pieno, è attuata un’operazione di commit, che consiste nello scrivere le effettive nuove versioni degli indici e del corrispondente master node. Diversamente da quanto visto in precedenza, l’operazione di commit non sposta i nodi foglia dal journal, ma sposta il journal stesso: le informazioni contenute in esso in seguito al commit entrano a far parte del b-tree principale, mentre il journal verrà scritto in una nuova area di memoria libera. Ogni volta che UBIFS viene montato, gli indici del b-tree vengono considerati “da aggiornare”, in modo da rinnovare le informazioni memorizzate con quelle contenute nel journal. Tale processo è detto replay. L’area di log è utilizzata per tenere traccia, in un buffer circolare, della posizione del journal in memoria attraverso un commit start node, che registra l’inizio di un commit, e reference nodes, che registrano il numero di LEB che fanno parte del journal, detti Buds. Un commit viene considerato concluso nel momento in cui viene aggiornato il master node, che punterà alla nuova coda dell’area di log. Nel caso in cui il commit non dovesse giungere a compimento a causa di guasti improvvisi, il processo di replay ri-applicherebbe sia la sezione di journal già elaborata, sia quella non ancora raggiunta. 3.3 YAFFS YAFFS (Yet Another Flash File System) è un file system sviluppato nel 2002 dalla Aleph One e concepito per diversi sistemi operativi, tra i quali Linux e Android. 31 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) Esso si fonda su una architettura a log, che viene, ad ogni boot, riassemblata in memoria centrale in una struttura ad albero. L’unità di memorizzazione adottata è il chunk, che consiste di un header e dei dati, più una spare area che contiene, oltre a vari parametri, un sequence number. Figura 159: montaggio YAFFS Quando si apporta una modifica alla sezione dati viene allocato un nuovo chunk, che conterrà un sequence number incrementato, per intendere che si tratta di una versione successiva del dato. Solo a questo punto il sistema potrà, se necessario, deallocare la vecchia copia. I chunk obsoleti vengono distinti attraverso un valore “dirty” settato alto all’interno della spare area. Quando tutti i chunk in un eraseblock sono marcati come tali, il blocco può essere cancellato e riutilizzato. Il processo di ripristino del sistema è ottenuto ripercorrendo a ritroso il log (quindi in ordine cronologico inverso), in modo tale che tutte le ulteriori coppie (objectid, sequence number) rilevate saranno scartate immediatamente come obsolete. Per velocizzare le operazioni di montaggio del file system è possibile sfruttare un meccanismo di checkpoint: un flusso dati viene scritto in un set di blocchi, marcati come detentori di checkpoint data. Tale flusso conterrà lo stato a runtime del sistema, costituito dalle sole informazioni utili ad avviare il processo di recupero dei metadati, tra le quali un indice di versione, usato per distinguere l’ultimo checkpoint da quelli obsoleti; ed un checksum per verificarne l’integrità. 32 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) 33 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) Capitolo 4 Confronto fra le soluzioni proposte Giunti a questo punto sorge spontaneo chiedersi quale delle soluzioni analizzate sia la migliore. È immediato comprendere tuttavia che è difficile, se non impossibile, poter sostenere un confronto “assoluto” a causa della mole di parametri in gioco. Le meccaniche di journaling classico potrebbero dimostrarsi poco adatte a soddisfare le attuali richieste in materia di affidabilità, considerando un ambiente che contempla il trattamento di ingenti quantità di dati e che vede affacciarsi all’orizzonte problematiche che in un passato non lontano erano considerabili di poco conto. D’altro canto l’esperienza accumulata da tali file system li rende dei “veterani” nel settore, ai quali è possibile attribuire un certo grado di stabilità. I file system COW based hanno dalla loro la forza di un meccanismo dedicato a preservare le “vecchie” informazioni nonostante l’evolversi dello stato del sistema, che, se ben sviluppato, può risultare praticamente infallibile. L’altra faccia della medaglia si manifesta di conseguenza: la qualità ha un costo, che in termini di risorse si rivela abbastanza alto, a causa della richiesta da soddisfare per poter gestire le meccaniche di conservazione e ridondanza dei dati. Non bisogna inoltre ignorare la relativa immaturità dei file system COW based: al giorno d’oggi sono ancora in atto studi volti a risolverne bug ed inesattezze (basti pensare che per btrfs non è ancora stata rilasciata una versione stabile). 34 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) L’assenza dei file system dedicati alle memorie flash da questo confronto non è casuale. La relatività alla quale si faceva riferimento ad inizio discorso viene in questo caso amplificata di ordini di grandezza. Le memorie flash hanno già conosciuto una notevole fama nel mondo dei sistemi embedded, ma non sono ancora considerabili definitivamente mature da poter costituire una valida alternativa ai supporti di memorizzazione classici. La ricerca in questa direzione sta incontrando purtroppo non pochi ostacoli, a causa della reticenza mostrata dalle case produttrici di memorie flash, disposte per il momento alla sola offerta di soluzioni proprietarie per la gestione della memoria al livello fisico (Le memorie SSD, attualmente in commercio, dispongono di un controllore autonomo, unico beneficiario dell’accesso al livello fisico, ed intermediario fra esso ed il file system). Nel campo dei dispositivi mobili le memorie flash rappresentano uno standard de facto, ed è proprio grazie all’applicazione in questo campo - che di recente sta avendo molto successo grazie all’ampia diffusione degli smartphone - che i file system dedicati a tale supporto conosceranno presto un notevole sviluppo. 35 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) Conclusioni L’analisi condotta conduce alla seguente conclusione: esiste una variegata gamma di possibilità quando si parla di file system failure-aware. Allo stesso tempo, tuttavia, la risposta ad un possibile confronto si traduce in un “ingegneristico” dipende. È possibile classificare tali file system in termini di affidabilità, prestazioni, requisiti senza ottenere due volte la stessa scala di importanza. La soluzione che si potrebbe prospettare al momento più saggia consisterebbe nell’affidare il mercato general purpose, meno delicato in termini di valore dei dati e meno esigente in termini di prestazioni, ai meccanismi di journaling classico, per ora più stabili. Il mondo delle grandi aziende e dei data server si prospetta invece come un ottimo banco di sperimentazione, in vista di uno sviluppo definitivo delle più moderne tecniche di gestione di grandi quantità di dati. 36 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) Bibliografia [1] Valerie Aurora. 2009, “A short history of btrfs” [2] Jeff Bonwick, Bill Moore. “ZFS The Last Word In File Systems” [3] Wiebe Cazemier. “Why power outages are bad for your data” [4] Dominique Heger. “An Introduction to ZFS – The Next Generation in File System Technology” [5] Adrian Hunter. 2008, “A Brief Introduction to the Design of UBIFS” [6] M. Tim Jones. 2008, “Anatomy of Linux flash file systems” [7] M. Tim Jones. 2008, “Anatomy of Linux journaling file systems” [8] Jeffrey B. Layton. 2009, “NILFS: A File System to Make SSDs Scream” [9] Charles Manning. 2010, “How YAFFS Works” [10] Joe Peterson. 2008, “More on data integrity: Enter Btrfs!” [11] Vijayan Prabhakaran. 2006, “IRON FILE SYSTEMS” [12] Ohad Rodeh. 2012, “BTRFS: The Linux B-tree Filesystem” [13] Britta Wuelfing. 2009, “Linus Torvalds Upset over Ext3 and Ext4” [14] Avantika Mathur, Mingming Cao, Suparna Bhattacharya, Andreas Dilger, Alex Tomas, Laurent Vivier. 2007, “The new ext4 filesystem: current status and future plans” [15] Vijayan Prabhakaran, Lakshmi N. Bairavasundaram, Nitin Agrawal, Haryadi S. Gunawi, Andrea C. ArpaciDusseau, and Remzi H. ArpaciDusseau. 2005, “Linus Torvalds Upset over Ext3 and Ext4IRON File Systems, pagg 206-220” [16] Yupu Zhang, Abhishek Rajimwale, Andrea C. Arpaci-Dusseau, Remzi H. ArpaciDusseau. “End-to-end Data Integrity for File Systems: A ZFS Case Study” [17] Yuanting Wei, Dongkun Shin. “NAND Flash Storage Device Performance in Linux 37 Analisi e confronto dei meccanismi di journaling adottati nei file system di ultima generazione (ZFS, brtfs, ext4, NTFS) File System” [18] NTFS Developers. “NTFS.COM/Transaction Journal” [19] Btrfs wiki moderators “wiki.kernel.org/Btrfs” 38