






Studia grazie alle numerose risorse presenti su Docsity
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Prepara i tuoi esami
Studia grazie alle numerose risorse presenti su Docsity
Prepara i tuoi esami con i documenti condivisi da studenti come te su Docsity
Trova i documenti specifici per gli esami della tua università
Preparati con lezioni e prove svolte basate sui programmi universitari!
Rispondi a reali domande d’esame e scopri la tua preparazione
Riassumi i tuoi documenti, fagli domande, convertili in quiz e mappe concettuali
Studia con prove svolte, tesine e consigli utili
Togliti ogni dubbio leggendo le risposte alle domande fatte da altri studenti come te
Esplora i documenti più scaricati per gli argomenti di studio più popolari
Ottieni i punti per scaricare
Guadagna punti aiutando altri studenti oppure acquistali con un piano Premium
Libro di Michael Dahlin, Thomas Anderson tradotto in italiano (13 capitoli).
Tipologia: Appunti
1 / 12
Questa pagina non è visibile nell’anteprima
Non perderti parti importanti!







Capitolo 13 (Professore – 22/05/18)
Discuteremo principalmente della gestione dei file su disco. I file sono organizzati in gruppi -> super gruppi -> etc.. (directory).
I file possono essere piccoli, medi o grandi.
Per l’allocazione dei file piccoli/medi/grandi dobbiamo stare attenti poiché rischio di aumentare il tempo di seek e di rotazione.
I file vengono riconosciuti con un nome simbolico (file named) e fungono da interfaccia tra l’utente e macchina. Ogni file quindi è identificato da un numero file e i suoi metadati all’interno delle macchina; quest’ultimi possono essere acceduti tramite le directory ( rappresentate sempre come file).
Metadati: Dove troviamo i blocchi di un file che contengono i dati (equivalente page table).
Mappa spazio libero (Free map): Lista dei blocchi liberi.
Problemi: Come stabiliamo quali blocchi vengono assegnati ad un file? Quanto devono essere grandi i blocchi? Come troviamo i blocchi liberi su disco? Come preserviamo la località spaziale? Cosa succede se vi sono guasti durante qualche trasferimento?
Ci preoccuperemo di come organizzare la struttura d’indicizzazione:
Come accediamo al file?
Dal nome del file + offset (attraverso la directory) si ha il numero del file + offset. Attraverso la struttura d’indicizzazione riesco a risalire ai blocchi di dati cercati.
FAT
Si una linked list. È molto facile da implementare, ed è molto utilizzata nelle flash storage.
Il nome dei file viene fatto coincidere “per comodità” con l’indice del blocco fisico in cui risiede il primo blocco logico di quel file.
Se io volessi caricare/leggere dei dati per/da un file, e volessi avere delle informazioni relative a quel file, dovrei avere salvata la FAT in memoria. Quanta memoria occupa in memoria? E se volessi percorrere metà cammino di un file, quanto ci metterei?
Supponiamo di avere una FAT di L bit (base FAT), avrà quindi 2^L blocchi!
Se B è la lunghezza di ogni blocco. La massima estensione del file system è: 2^L * B.
FFS (FAST FILE SYSTEM)
Si usa un albero. Ciascun elemento dell’albero vengono chiamato inode , i quali sono tutti contenuti in un array inode.
Un problema che affrontiamo è la località. Usiamo i cilindri.
Che algoritmo uso per allocare i blocchi liberi?
NTFS
La differenza con FFS, è che vi è un vettore MASTER FILE TABLE (MFT) utilizzato in modo molto intelligente. Ogni elemento è di 1KB, contenente metadati e dati (dati sse il file è piccolo).
Se i file sono grandi, non metto i puntatori a tutti i blocchi, ma riferisco un gruppo di blocchi fisici contigui che sono riferito da un gruppo di blocchi logici ( extent).
In questo capitolo discuteremo come i file system sono organizzati per incontrare le prime 3 sfide. Il capitolo 14 realizzerà l’affidabilità.
13.1 Overview d’implementazione
I file system devono mappare i nomi dei file e gli offset per i blocchi dei dispositivi fisici in modo tale da accedere in modo efficiente. Sebbene ci sono molti file system, molte di queste implementazioni sono basate su quattro idee: cartelle, indici di strutture, mappe degli spazi liberi, e località euristiche.
Directory e indici di strutture. Come illustrato nella figura 13.1, il file system mappa il nome del file e gli offset di quest’ultimo per dei specifici blocchi nei dispositivi fisici in due step.
Figura 13.
Per prima, cosa usa le directory per mappare il nome (“umano” per così dire) al numero del file.
Le directory sono spesso file speciali che contengono liste di mappe “file name” -> “file number”.
In secondo, una volta che il file name è stato tradotto in file number, il file system usa una struttura di indici persistenti per localizzare i blocchi dei file. L’indice di struttura può essere una qualsiasi struttura dati persistente che mappa un numero del file ad un blocco del dispositivo di memorizzazione. Spesso, per supportare efficientemente una grande range di “file sizes” e “ pattern di accesso”, le strutture di indicizzazione sono spesso alberi.
Mappe degli spazi liberi. Il file system implementa mappe degli spazi liberi per tracciare quali blocchi sono liberi e quali in uso mentre il file cresce o si restringe. Come minimo, la mappa di spazio libero del file system deve permettere al file system di trovare un blocco libero quando un file ha bisogno di crescere, ma poiché la località spaziale è importante, i più moderni file system implementano mappe di spazio libero che permettono di trovare blocchi liberi vicini alla locazione desiderata. Per esempio, in molte implementazioni del file system le mappe di spazio libero vengono rappresentante come bitmap sul dispositivo persistente.
Località euristica. Le directory e le strutture di indicizzazione permettono al file system di localizzare i dati e metadati del file senza preoccuparsi di dove questi siano memorizzati, invece le mappe di spazio libero permettono di localizzare spazio libero vicino ad ogni locazione sul dispositivo persistente. Questi meccanismi permettono al file system di sviluppare varie politiche ( policies ) per decidere dove un blocco o un file dato dovrebbe essere memorizzato.
Queste politiche si incarnano sulle località euristiche per gruppi di dati per ottimizzare le performance. Per esempio, alcuni file system raggruppano insieme i file di ogni directory ma diffondono directory diverse in parti diverse del dispositivo di archiviazione. Altre periodicamente deframmentano i loro storage, riscrivendo file esistenti così che ogni file è memorizzano in blocchi di storage sequenziali così il device ha lunghe sequenze di spazio sequenziale libere, quindi i nuovi file possono essere scritti in sequenza. Altre ancora ottimizzano le scritture rispetto alle letture e scrivono tutti i dati in sequenza, se un dato set di scrittura contiene aggiornamenti per un file o per molti altri.
Dettagli d’implementazione. In questo capitolo, per prima cosa discuteremo come le directory sono implementate. Dopo, vedremo i dettagli di come file system specifici gestiscono i dettagli di memorizzazione o di lettura dati in storage persistenti implementando differenti indici di struttura, mappe di spazio libero, e località euristiche.
13.2 Naming data
Come raffigurato nella figura soprastante, per accedere ad un file, il file system per prima cosa traduce il “file named” con il suo numero relativo. Per esempio, il file chiamato /home/tom/foo.txt potrebbe essere
conosciuto internamente come 66212871. Il file system usa le directory per memorizzare il mapping fra il “file named-human” e il suo relativo numero, e organizza gerarchicamente le directory cosicché gli utenti possono raggruppare file “in relazione tra di loro” e directory.
Implementare le directory in modo da fornire una gerarchia, mappando “file named” -> “file numero” dovrebbe essere facile. Usi i file per memorizzare directory. Così, se il sistema ha bisogno di determinare il numero di un file, deve soltanto aprire il file directory appropriato e ricercare il file-name/file-numero fin quando non trova quello corretto.
Per esempio, nella figura sottostante si illustra il contenuto di una directory.
Per aprire il file “foo.txt”, il file system dovrebbe ricercare questo file nella directory, trovare la voce “foo.txt”, e vedere che il file “foo.txt” ha il numero 871.
Certamente, se usassimo i file per memorizzare i contenuti delle directory come /home/tom, avremmo ancora il problema di trovare i file directory. Come illustrato nella figura sottostante
Figura 13.
il numero del file per la directory /home/tom può essere trovato eseguendo una lookup del nome “tom” all’interno della directory “home”, e la directory “home” a sua volta può essere trovata facendo una lookup nella root directory “/”.
Gli algoritmi ricorsivi hanno bisogno di un caso base – non possiamo scoprire le directory root cercando in qualche altra directory. Questa soluzione mette d'accordo il numero della root directory prima di eseguire le lookup. Per esempio, Il Fast File System di Unix (FFS) e molti altri Unix e Linux file system usano due root directory per il file system.
Così, per leggere il file /home/tom/foo.txt nella figura 13.3, dobbiamo per primo leggere la root directory leggendo il numero del file directory tra i 2 disponibili. In questo file, cercheremo il nome home memorizzato nel file con il numero 88026158. Leggendo quest’ultimo troviamo che il numero di file directory per “tom” è 5268830. Infine, leggendo il file 5268830 e cercando il nome “foo.txt”, vediamo che il file “foo.txt” è il numero 66212871.
Attraverso la lookup un numero di file può essere trovato attraverso differenti step, aspettandoci che ci sia località (Ex. quando un file in una directory è acceduto, altri file nella stessa directory saranno acceduti presto), il caching ridurrà il numero di accessi al disco per la maggior parte delle lookup.
Directory API. Il file system usa file per memorizzare le informazioni delle directory, potremmo usare le API standard per i file (open/read/close/write) per accedere alle directory?
No. Le directory usano API speciali perché devono controllare il contenuto dei file. Per esempio, il file system deve prevenire che le applicazioni corrompano la lista per il mapping “file named” -> “file number”, che potrebbe influire sulle performance di lookup e aggiornamenti. Come altro esempio, il file system dovrebbe imporre l’invariante che ogni “file number” in una directory valida riferisce un file già esistente.
Il file system perciò fornisce special system call per modificare i file di directory. Per esempio, piuttosto che usare la system call “write” per aggiungere un nuova entry nella directory, le applicazioni usano la chiamata create. Limitando gli aggiornamenti, queste chiamate garantiscono che i file di directory possono essere sempre controllati dal file system. Questo chiamate associano inoltre la creazione e la rimozione di un file e la rispettiva entry all’interno del file directory, così che le posizioni del file directory riferiscono sempre al file e che tutti i file hanno al più una posizione nella directory.
Nelle API descritte nell’Overview del Capitolo 11, le altre chiamate che modificano i file directory sono mkdir, link, unlink e rmdir.
Il file system ricerca il nodo della prima entry la cui chiave hash supera la chiave di destinazione, quindi segue il puntatore offset per arrivare alla foglia desiderata (nodo figlio). Il puntatore file offset nel record delle foglie punta alla posizione di destinazione all’interno della directory.
Nell’implementazione XFS, le posizioni della directory sono memorizzate nella prima parte del file directory. La radice dell’albero si trova in un offset noto all'interno del file. La dimensione fissata internamente e i nodi foglia sono memorizzati dopo la radice, e posizioni di dimensione dinamica di una directory sono memorizzate all’inizio del file. Partendo dalla radice, ogni nodo dell’albero include puntatori ai figli memorizzati all’interno del file.
Hard e Soft link. Molti file system permettono ad un dato file di avere nomi multipli. Per esempio, come illustrato nella figura sottostante hw1.txt della directory mike e hw1.txt della directory tom possono riferire lo stesso file.
Hard link sono posizioni multiple di un file directory che mappa differenti path name allo stesso numero di file. Poiché un numero di file può apparire in più directory, il file system deve assicurare che un file è cancellato soltanto quando l’ultimo hard link ad esso è stato rimosso.
Per implementare il garbage collector, il file system usa un “contatore di riferimenti” memorizzando tutti i link che riferiscono un file number. Quando un file è creato, il suo contatore di riferimento è ad 1, ogni qual volta vi è un hard link in aggiunta ad un file, il suo contatore viene incrementato di uno, lo stesso accade quando viene rimosso un hard link decrementando il suo contatore di riferimenti; quando quest’ultimo arriva a 0, il file sottostante viene rimosso e le sue risorse vengono marcate come libere.
Piuttosto che mappare il file name con il suo file number, esistono i soft link o link simbolici i quali sono posizioni della directory che mappano un nome con un altro.
Per esempio, nella figura sottostante mostra una directory che contiene 3 nomi che riferiscono tutti lo stesso file. Le posizioni foo.txt e bar.txt sono hard link allo stesso file – numero 66212871; bar.txt è un soft link per foo.txt.
Da notare che se rimovessimo la posizione foo.txt dalla directory utilizzando la system call unlink , il file potrebbe ancora essere aperto usando il nome bar.txt, ma se provassimo ad aprirlo, quest’ultimo genererebbe un errore.
File metadata. Molti file system memorizzano i metadati di un file (ex. diritti di accesso, tempo, ID proprietario, permessi, grandezza) in un file header che può essere trovato con il file number. Si potrebbe immaginare di memorizzare i metadati all’interno delle posizioni di un file directory. Perché viene fatto raramente?
Nel file system che supporta gli hard link , memorizzare metadati nelle posizioni di una directory potrebbe essere problematico. Per esempio, ogni qual volta un attributo del file, come la sua dimensione, cambia, tutte le posizioni del file directory che matchano quell’hard link devono essere trovate e aggiornate. Un altro esempio, se i metadati fossero memorizzati nelle posizioni del file directory, sarebbe duro mantenere un reference count per il file. Il file system FAT di Microsoft memorizza i metadati nelle posizioni della directory, però non supporta gli hard link.
13.3 File: Trovare dati
Una volta che il file system ha tradotto il “file name” nel “file number” usando le directory, il file system deve poter trovare i blocchi che appartengono al file. Questo aggiunge requisiti funzionali, e tali implementazioni si pongono i seguenti obiettivi:
I costruttori di file system hanno affrontato una grande scommessa per affrontare tali obiettivi.
Richiamando ciò che abbiamo detto nella sezione 13.1:
All’interno di questi framework, lo spazio per un file system è molto grande. Per capirne il trade-off e capire come lavorano i più comuni file system, esamineremo 4 casi che illustrano le tecniche e gli approcci largamente usati al giorno d’oggi.
13.3.1 FAT: Linked List
system, permettendo di essere letti e scritti da qualsiasi pc che esegue un qualsiasi sistema operativo moderno.
Alcune variazioni del file system FAT sono anche usate da applicazioni per organizzare i dati all’interno dei file. Per esempio, i file di Microsoft .doc prodotti dalla versione di Microsoft Word 1997 fino alle 2007 erano composti da molti pezzi interni. il formato .doc crea un file system simile a FAT all'interno del file .doc per gestire gli oggetti nel file .doc.
Il file system, comunque, è limitato in molti modi. Per esempio,
Similmente, le dimensioni del file sono codificate a 32 bit, così ciascun file non può essere più grandi di 2^32 -1 byte (sotto i 4GB).
13.3.2 FSS: Fixed tree
Il Fast File System Unix (FSS) mostra delle idee importanti sia per l’indicizzazione dei blocchi del file così che possono essere localizzati velocemente, sia per il piazzamento dei dati su disco in modo da garantire la località.
In particolare, la struttura di indicizzazione di FSS, chiamata indicizzazione multilivello, è una struttura ad albero che permette al file system di allocare ogni blocco del file ed è efficiente per i file piccoli e grandi.
Con la flessibilità fornita dall’FSS, quest’ultimo impiega due località euristiche - block group placement ( blocco di posizionamento di gruppo) e reserve space (spazio riservato) – che insieme di solito forniscono un buon layout del disco.
Struttura d’indicizzazione. Per mantenere traccia dei blocchi dati che appartengono ad ogni file, L’FSS usa un albero di dimensioni fissate e asimmetrico chiamato multilevel index , illustrato nella figura sottostante
Figura 13.
Ogni file è un albero con blocchi dati di dimensione fissa (ex. 4KB) come le sue foglie. Ogni albero che rappresenta un file è radicato in un inode che contiene i metadati del file (ex. il proprietario, i diritti di accesso, il tempo di creazione, ultima modifica, e se il file è una directory o no).
Un file inode (root) contiene un array di puntatori per localizzare i blocchi dati del file (foglie). Alcuni di questi puntatori puntano direttamente ai dati che risiedono nelle foglie dell’albero, altri puntano a nodi interni all’albero. Tipicamente, un inode contiene 15 puntatori. I primi 12 sono puntatori diretti e puntano ai primi 12 blocchi del file.
Il 13° puntatore è un puntatore indiretto , il quale punta ad un nodo dell’albero interno chiamato blocco indiretto ; un blocco indiretto è un blocco regolare di storage il quale contiene un array di puntatori diretti.
Per leggere il 13° blocco di un file, per prima cosa devi leggere l’inode per leggere il puntatore indiretto, dopo viene letto il blocco indiretto per trovare il puntatore diretto, e infine viene letto il blocco dati. Con 4KB blocchi e 4-byte come puntatori, un blocco indiretto può contenere 1024 puntatori diretti, i quali permettono al file di crescere di oltre 4MB.
Il 14° puntatore è chiamato double indirect block (puntatore indiretto doppio); quest’ultimo è un array di puntatori indiretti, ognuno dei quali punta a un blocco indiretto. Con 4KB blocchi e 4-byte per blocco, un puntatore indiretto può contenere 1024 puntatori indiretti, ciascuno dei quali punta a 1024 puntatori diretti. Quindi avremo (1024*1024) blocchi dati.
Infine, il 15° puntatore è il triple indirect pointer ( puntatore indiretto triplo) che punta a puntatori indiretti tripli che contengono un array di puntatori indiretti doppi. Con 4KB di blocchi e 4-byte per blocco avremo (102410241024) blocchi dati (4TB)
Tutti gli inode, costruiti come menzionato in precedenza, sono memorizzati in un inode array , il quale è memorizzato in una posizione fissata del disco. Un numero di file, chiamato inumber in FSS, è una posizione all’interno dell’ inode array: per aprire il file (ex. foo.txt), dobbiamo cercare nella directory del file per trovare il suo numero (ex. 91854), poi cercare la posizione appropriata nell ’inode array (Ex. 91854) per trovare i metadati.
FFS multilevel index ha 4 caratteristiche principali:
L’alto grado di nodi ha senso su un disco dove si vuol minimizzare il numero di seek, il costo della letture di molti kilobyte di dati sequenziali non è molto alto rispetto alle letture del primo byte, e i dati i dati devono essere letti e scritti almeno un settore alla volta.
L’alto grado di nodi migliora anche l’efficienza per letture sequenziali e scritture – una volta che il blocco indiretto viene letto, centinaia di blocchi dati possono essere letti prima che abbiamo bisogno del prossimo blocco indiretto. L’esecuzione tra le letture di doppi blocchi indiretti quindi sono ancora più frequenti.
Comparato a un albero dinamico può aggiungere livelli di puntatori indiretti sopra un blocco man mano che un file cresce, il principale vantaggio di una struttura fissa è la facilità d’implementazione.