File System
Il File System e quel componente del SO che realizza i servizi di gestione dei file.
File: unità di archiviazione in memoria di massa (costituito da una sequenza di byte).
Rappresenta la struttura logica della memoria di massa (organizzazione e memorizzazione
dei file) ed è costituito da un insieme di funzioni di SO e relative strutture dati di supporto.
Virtual File System: interfaccia unica per gestire diversi FS che mette a disposizione le API
che consentono l'utilizzo indipendente delle chiamate di sistema.
Le astrazioni fornite dal file system sono:
• File, link e operazioni su file
• Directory e file speciali
• Attributi e politiche di accesso
• Mapping del file system logico sui dispositivi fisici
Volume
I dispositivi di memorizzazione non volatile possono essere suddivisi in porzioni dette
partizioni; ogni partizione può essere funzionalmente considerata come un dispositivo logico
indipendente.
L'indirizzamento dei dati si basa sul concetto di LBA.
LBA è uno schema di indirizzamento nel quale l'intero dispositivo è rappresentato come un
vettore lineare di blocchi.
Volume: partizione di qualsiasi dispositivo di memorizzazione non volatile di massa dotato
di uno schema d'indirizzamento LBA.
Il blocco costituisce l'unità fondamentale di informazione che viene trasferita con una sola
operazione tra il disco e la memoria centrale.
Interazione con la memoria
L'accesso ai dati su disco è un'operazione misurata in millisecondi, i tempi di esecuzione
delle istruzioni in nanosecondi.
FS e gestione memoria (in particolare page cache) devono collaborare.
Quando il VGS o un FS vuole leggere un blocco su un volume, lo richiede in realtà alla Page
Cache:
• Se il blocco è già in page Cache, questa restituisce immediatamente l'indirizzo di
memoria del blocco;
• In caso contrario la Page Cache alloca lo spazio necessario in una pagina e richiede al
gestore a blocchi di leggere il blocco dal dispositivo nella pagina allocata.
File
Costituito da:
• Sequenza di byte
• Nome simboli e univoco all'interno del directory
• Insieme di attributi (tipo, locazione nel dispositivo, dimensione, protezione, time stamp,
proprietario)
Un file in LINUX può:
• Contenere dati o programmi (file normale)
• Contenere riferimenti ad altri file (file direttore)
• Rappresentare l'astrazione di un dispositivo periferico (file speciale)
Calcolatori Pagina 1
Tutte le operazioni sul contenuto del file richiedono il trasferimento in/da memoria di byte e
partono dalla posizione corrente nel file, aggiornandola.
Operazioni:
• Creazione, apertura, chiusura, cancellazione
• Lettura, scrittura
• Riposizionamento
Modello d'utente
• Accesso al singolo file: funzioni utilizzate per scrivere e leggere informazioni sui
singoli file (creat, open, close, fsync, read, write, lseek, ecc.)
• Organizzazione della struttura complessiva dei file: funzioni utilizzare per
organizzare i file nei directory (folder, cartelle) e volumi (unlink, link, mkdir, mknod,
dup, ecc.)
Modello per l'accesso al singolo file
L'accesso a un file può avvenire secondo due modalità:
1. La mappatura di una VMA sul file tramite mmap()
2. Le system calls classiche di accesso ai file, simile alle funzioni della libreria C standard.
(Il VFS dovrà implementare entrambe le modalità).
Funzioni per la gestione dei file
Per operare su un file è necessario:
• Aprirlo, se il file esiste già
• Crearlo (inserirlo nel file system) se il fine non esiste
Le funzioni di apertura e creazione richiedono come parametro il nome del file e restituiscono
un intero non negativo chiamato descrittore del file.
Le funzioni di lettura e scrittura (e altre ancora), utilizzano come riferimento il descrittore del
file e operano su sequenza di byte a partire da un byte specifico, la cui posizione è contenuta
dall'indicatore di posizione corrente.
Gestione dei file
L'immagine del file system è memorizzata in memoria di massa.
Il SO mantiene in memoria centrale una parte delle strutture dati per gestire i file.
A questo livello interessa mettere in evidenza:
• Tabella dei file aperti per ogni processo:
vettore che contiene informazioni sui file aperti da un certo processo (l'indice del
vettore rappresenta il descrittore del file).
• Tabella globale dei file aperti nel sistema:
vettore che contiene un elemento per ogni file aperto nel sistema.
Ogni elemento viene referenziato tramite gli elementi delle tabelle dei file aperti
dei processi e contiene, tra le altre, l'indicatore di posizione corrente nel file, il
numero di processi in accesso (link) al file e un riferimento (i-node) al file su
disco.
Creat viene aggiunto un nuovo file al file system.
int creat(char *nomefile, int permessi)
Operazioni richieste:
Allocazione dello spazio su disco
Aggiunta dei riferimenti al file nel file system
Restituisce un intero che rappresenta il descrittore del file.
Open individua la posizione del file sul disco sulla base del nome
int open(char *nomefile, int tipo, int permessi)
Permessi: Calcolatori Pagina 2
Permessi:
Gestisce i permessi di accesso
Tipo: O_RDONLY (solo lettura)
O_WRONLY (solo scrittura)
O_RDWR (lettura e scrittura)
Entrambe le funzioni implicano l'aggiornamento della tabella globale dei file aperti e della
tabella dei file aperti dal processo.
Lettura e Scrittura
int read(int fd, char buffer[], int numero_byte)
int write(int fd, char buffer[], int numero_byte)
Accedono al file tramite descrittore (ottenuto da create o open) e restituiscono il numero di
caratteri effettivamente letti/scritti, aggiornando l'indicatore di posizione corrente.
Buffer; variabile per dati che devono essere scritti su file o che ven
Il file system mantiene un indicatore alla posizione in cui deve essere effettuata la scrittura
successiva.
Riposizionamento
int lseek(int fd, long offset, int riferimento)
Sposta la posizione degli indicatori di lettura e di scrittura.
Le operazioni consentite dipendono dal tipo di accesso al file, e spesso viene mantenuto dal
file system un solo indicatore di posizione, valido sia per scrittura che per lettura.
Riferimento: 0 p=inizio file + offset
1 p=pos. prec. + offset
2 p=fine file + offset
Duplicazione
Crea un nuovo descrittore associato ad un file già aperto con open.
fd2=dup(fd1)
Fork() condivide automaticamente tutti i file aperti dal padre con il figlio.
close() e fsync()
Elimina il legame tra descrittore e file.
int close(int fd)
Restituisce l'esito dell'operazione di chiusura.
Questo però non garantisce che i dati scritti in memoria vengano trasferiti immediatamente su
disco.
Per far sì che questo accada è necessario invocare la fsync.
int fsync(int fd)
Questa operazione scrive su disco tutti i dati del file che sono stati modificati in memoria.
link() e unlink()
Per associare un nuovo nome ad un file esistente:
int link(char *nome, char *nuovo_nome)
Crea una nuova entry nel direttore che contiene nuovo_nome.
Non crea un nuovo descrittore, ma incrementa di 1 i riferimenti (link) a quel file.
Per eliminare un link ad un file specificato tramite nome (decrementare di 1 il numero di
riferimenti, si usa:
int unlink(char *nome) Calcolatori Pagina 3
int unlink(char *nome)
Se esiste un solo link, il file viene eliminato dal file system.
In questo caso le azioni necessarie sono:
• Deallocazione dello spazio sul dispositivo fisico
• Aggiunta dello spazio deallocato alla lista dello spazio disponibile sul dispositivo
• Rimozione del descrittore del file dal file system
Organizzazione complessiva dei file
I file sono organizzati in una struttura ad albero i cui nodi sono detti cataloghi (directory,
cartelle, folder ecc.)
Per semplificare la gestione dei file, i nomi dei file sono inseriti nei cataloghi.
Un cataloghi non è altro che un file dedicato a contenere i nomi di altri file e le informazioni
necessarie al sistema per accedere tali file.
I file dedicati a servire come catalogo sono detti di tipo catalogo, mentre i file che
contengono normali informazioni sono detti di tipo normale.
La struttura dei cataloghi sii basa sull'esistenza di un unico catalogo principale, detto radice
(root) che il sistema è in grado di identificare e accedere autonomamente, e che può contenere
riferimenti sia a file normali che file catalogo, e così via.
Il nome completo (pathname) di un file di qualsiasi tipo è costituito dal concatenamento dei
nomi di tutti i cataloghi sul percorso che porta dalla radice al file stesso, separati dal simbolo
"/".
Directory
I direttori sono dei file e quindi sono caratterizzati da nome e diritti d'accesso.
Contengono informazioni sui file e direttori in essi contenuti (nome, attributi, proprietario).
Forniscono una corrispondenza tra nomi di file e file stessi.
Il loro contenuto può essere visto come una tabella, con una entry per ogni file/directory
contenuto.
Ogni entry è del tipo:
<riferimento al file/directory su disco, nome file/directory>
Operazioni sulle directory
Sulle directory, cosi come sui file, è possibile compiere alcune operazioni:
• Ricerca di un file: sulla base di un nome o una espressione regolare consente di
recuperare le informazioni su uno o più file.
• Creazione di un file: alla directory viene aggiunto un elemento che raccoglie
informazioni sul nuovo file.
• Rimozione di un file: eliminazione di un descrittore di file. Il descrittori deve essere
prima individuato tramite una operazione di ricerca.
• Elenco dei file: produce l'elenco dei nomi ed eventualmente altre informazioni relative
ai file memorizzati.
• Rinomina un file: modifica il nome di un file già presente nella directory.
Il descrittore deve essere prima individuato tramite una operazione di ricerca.
Per creare una directory si usa la funzione mknod().
Periferiche e file speciali
In unix le periferiche sono viste come file speciali, simulate come file nel direttorio /dev.
Sulle periferiche è possibile eseguire open, read e write (purché ne abbia senso), close ma
non creat (per crearli si usa mknod).
Ogni programma, all'esecuzione, dispone già di 3 descrittori di file: stdin, stdout, stderr
associati rispettivamente alla tastiera e al video.
Nella tabella dei file aperti di un processo, i primi 3 elementi sono associati a questi
descrittori.
Area buffer/cache e gestori dei dispositivi a blocchi
Calcolatori Pagina 4
Area buffer/cache e gestori dei dispositivi a blocchi
Il file system svolge le sue funzioni appoggiandosi a due componenti:
• Il gestore dei buffer/cache gestisce le zone di memoria destinate a contenere blocchi
dei file che sono stati letti da disco.
• Il gestore del disco (disk driver) che disaccoppia il dispositivo logico da quello fisico.
Il gestore dei buffer/cache gestisce la Page cache (zona di memoria centrale) con il principio
di tenere in memoria il più a lungo possibile i blocchi letti da disco.
Quando il file system richiede la lettura di un blocco di un file passa la richiesta al gestore dei
buffer/cache.
Se il blocco del file è già nella page cache, il gestore dei buffer lo fornisce al file system, in
caso contrario il file system identifica l'LBA del blocco da caricare e richiede al gestore di
allocare spazio e di caricare il blocco.
Il gestore dei buffer interagisce con il disk driver, accodando la richiesta di trasferimento che
sarà soddisfatta in maniera ottimale dal driver in funzione delle operazioni fisiche su disco.
Volumi
In LINUX esiste un unico albero di directory con un'unica radice (indicata da /).
Diversi volumi, cioè partizioni dotate del loro FS, sono rappresentati da nodi dell'albero detti
mount_point.
Il sottoalbero la cui radice è un mount_point descrive la struttura interna del volume, mentre
la posizione del mount_point nell'albero generale lo rende raggiungibile partendo da /.
Per inserire un nuovo volume è necessario compiere due operazioni:
• Associare un FS al volume (device)
• Montare il volume in un opportuno mount_point.
Modello del Virtual File System
Il modello del VFS deve rappresentare due tipi di informazioni:
• Le informazioni relativamente statiche contenute nei file e cataloghi memorizzati nei
diversi volumi.
Queste informazioni sono presenti sui dischi e quindi permangono anche dopo lo
spegnimento del sistema.
Vengono caricate in memoria in base alle esigenze.
• Le informazioni dinamiche associate ai file e cataloghi aperti durante il funzionamento
del sistema, ad esempio la posizione corrente di un file.
Strutture dati
Il modello del VFS si basa su un certo numero di strutture dati:
• Struct dentry : ogni istanza di questa struttura rappresenta una directory nel VFS.
• Struct inode: ogni istanza di questa struttura rappresenta uno e un solo file fisicamente
esistente nei volumi, e contiene i cosiddetti metadati del file.
• Struct file: ogni istanza di questa struttura rappresenta un file aperto nel sistema.
Queste struttura dati contengono, oltre ai campi utilizzati per rappresentare i contenuti
specifici, dei puntatori che permettono di collegarle in modo da rappresentare in forma di
strutture dati le informazioni necessarie a caratterizzare lo stato corrente dei file nel modello
del VFS.
Le principali tra tali strutture dati sono:
• La struttura dei cataloghi (directory)
• La struttura di accesso dai processi ai file aperti
La struttura dei cataloghi del modello del VFS è costituita esclusivamente da istanza di struct
dentry che rappresentano i nodi dell'albero dei direttori.
Struttura di accesso dai processi ai file aperti
Ogni descrittore di processo contiene 2 puntatori rilevanti ai file dell'accesso ai file.
Il descrittore di processo è definito dalla struct task_struct:
Calcolatori Pagina 5
Le istante di struct fs_struct contengono i parametri che caratterizzano i singoli FS registrati
nel sistema.
Il campo fs è un puntatore alla lista dei FS utilizzati dal processo e permette quindi di
reperire, nei momenti in cui servono, le informazioni specifiche relative al FS.
Il campo files è un puntatore a una struttura files_struct
Il componente fondamentale di questa struttura è un array di dimensione fissa fd_array (che
chiameremo anche tabella dei file aperti dal processo).
Questo array contiene un elemento per ogni file aperto dal processo.
Ogni elemento è un puntatore a un'istanza di struct file
Il primo puntatore serve a collegare tutti i file aperti in una lista e non è utilizzato dalla
struttura di accesso.
F_pos rappresenta la posizione corrente del file che viene aggiornata dinamicamente.
Il puntatore rilevante per costruire la struttura di accesso è f_dentry, che punta all'istanza di
dentry che è stato utilizzato per aprire il file.
Numero di aperture contemporanee e contatore f_count
Diverse righe nell'ambito di uno stesso processo o di più processi possono puntare allo stesso
file; in tal caso tutte le operazioni sui relativi descrittori condividono la posizione corrente.
Il contatore dei riferimenti f_count indica i descrittori che puntano contemporaneamente sul
file.
Il modo più comune per generare due descrittori che puntano allo stesso file è costituito da
dup o fork.
L'operazione fork, creando un processo figlio identico al padre, duplica la tabella dei file
aperti del processo e quindi determina l'esistenza di descrittori in diversi processi che
puntano allo stesso file.
L'apertura indipendente da parte di un processo R in un file già aperto da parte di P crea una
nuova istanza di struct file, con posizione corrente indipendente.
L'i-node è tuttavia condiviso, perché si tratta dello stesso file fisico.
La struttura a valle dei descrittori, costituita da istanze di dentry e inode, è considerata
eliminabile solo quando il contatore di f_count diventa 0.
Struct inode
Un file è rappresentato nel VFS da un'istanza della struct inode.
La corrispondenza tra file e (istanze di) inode è rigorosamente biunivoca.
Un inode contiene tutte le metainformazioni necessarie a caratterizzare il file.
Calcolatori Pagina 6
L'esistenza di una lista dei dentry (i_dentry) che fanno riferimento al file è dovuta al fatto che
un file può avere più di un nome nella struttura dei cataloghi.
Il superblocco di un FS è un struttura dati che contiene la definizione delle caratteristiche
generali del FS stesso.
Quindi il puntatore i_sb permette di risalire da un file al FS che lo gestisce.
Le strutture di tipo _operations i_op e i_fop contengono i puntatori alle funzioni dello
specifico FS che implementano le funzioni generali del VFS.
Queste 2 strutture sono rese accessibili direttamente dal inode di ogni file per rendere più
immediata la loro invocazione.
Le 2 strutture danno accesso rispettivamente alle funzioni del FS specifico per la gestione
dell'organizzazione complessiva dei file e cataloghi e alle operazioni di accesso al singolo
file:
• La struct inode_operations contiene puntatori alle implementazioni specifiche di
operazioni quali create, mknod, link, unlink, mkdir, rmdir, …
• La struct file_operations contiene puntatori alle implementazioni specifiche di
operazioni quali open, read, write, lseek…
L'implementazione di queste funzioni appartiene allo specifico FS, ma deve ovviamente
rispettare la struttura dei prototipi indicata in questa struct.
Il campo struct address_space *i_mapping contiene alcune informazioni fondamentali per
realizzare le operazioni di trasferimento dei dati dal volume alla memoria.
Accesso ai dati di un file
Nel modello di utente l'accesso ai dati di un file avviene tramite le operazioni read e write
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
Scarica il documento per vederlo tutto.
-
Calcolatori elettronici
-
Calcolatori Elettronici - Sistemi Operativi
-
Architettura dei calcolatori
-
Calcolatori elettronici e sistemi operativi