Struttura interna del sistema operativo Linux
CAP.8: Il file system
Primitive per la gestione dei file
28/10/2013
File System

Il gestore del file system è quel componente del Sistema
Operativo che realizza i servizi di gestione dei file
–


file: unità di archiviazione in memoria di massa.
Il file system rappresenta quindi la struttura logica della
memoria di massa (organizzazione e memorizzazione dei
file) ed è costituito da un insieme di primitive del Sistema
Operativo e relative strutture dati di supporto.
Le astrazioni fornite dal file system sono:
•
•
•
•
File, link e operazioni sui file
Directory e file speciali
Attributi e politiche di accesso
Mapping del file system logico sui dispositivi fisici
-2-
File (i)

Il concetto di file offre una visione logica omogenea delle informazioni
memorizzate.
–

Un file è costituito da:
–
–
–

La visione logica non dipende dal tipo di dispositivo fisico su cui le
informazioni vengono memorizzate
una sequenza di byte, che rappresenta l’insieme di informazioni omogenee;
un nome simbolico;
un insieme di attributi.
Un file in UNIX può
–
–
–
contenere dati o programmi (file ordinario)
contenere riferimenti ad altri file (directory)
rappresentare l’astrazione di un dispositivo periferico (file speciale)
-3-
File (ii)

Nome:
–

nome simbolico univoco nella directory con cui ci si riferisce ad esso
Attributi:
–
Tipo: definisce il tipo dei dati contenuti (estensione del nome, opzionale)
–
Locazione (implicito): è un riferimento alla posizione fisica sul dispositivo
–
Dimensione: dimensione dei dati contenuti espressa in byte o blocchi
–
Protezione: definisce le politiche di gestione degli accessi
–
Ora e Data: indicano il momento della creazione, ultima modifica o
ultimo accesso
–
Proprietario: indica il nome dell’utente che ha creato il file
-4-
Gestione del file system


L’immagine del file system è memorizzata in memoria di massa
attraverso il concetto di volume. Un volume è composto da una
sequenza di blocchi di dimensione fissa (512Byte).
Per rendere più efficienti gli accessi a file, il Sistema Operativo
mantiene in memoria centrale una parte delle strutture dati per la
gestione dei file. Tra queste vedremo:
–
Tabella dei file aperti per ogni processo
•
–
Contiene un elemento per ogni file aperto da un certo processo.
L’indice della tabella è costituita dal file descriptor.
Tabella globale dei file aperti nel sistema
•
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
(offset) nel file, il numero di link al file e un riferimento al file su
disco
-5-
Primitive per la gestione dei file (1)

Sui file possono essere compiute diverse operazioni, che vengono
svolte attraverso richieste di servizi al sistema operativo (system
call), invocabili anche da programma:
creat, open, close, write, read,…



Per operare su un file è necessario:
–
aprirlo, se il file esiste già
–
crearlo (cioè aggiungerlo al file system), se il file 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 (fd file descriptor)
Le funzioni di lettura e scrittura, e altre ancora, usano come
riferimento il descrittore e operano su sequenze di byte a partire da
un byte specifico, la cui posizione è contenuta dall’indicatore di
posizione corrente nel file (offset nel file)
-6-
Primitive per la gestione dei file (2)







Creazione di un file: fd = creat(file_name, mode);
Apertura di un file:
fd = open(file_name, O_RDONLY|O_WRONLY|O_RDWR, mode)
Chiusura di un file aperto: close(fd)
Scrittura di dati in un file già creato/aperto: write(fd, buf, num_byte);
Lettura dati da un file già creato/aperto: read(fd, buf, num_byte);
Riposizionamento all’interno del file:
new_offset = lseek(fd, offset, base);
Duplicazione di un descrittore di un file: fd2=dup(fd1);

Creazione di un nuovo riferimento (link) ad un file:
link(old_file_name, new_file_name);
Eliminazione di un link: unlink(nome_file);

Creazione di un file speciale: mknod (pathname, type, major, minor)

-7-
Funzioni del linguaggio C per la gestione dei file





Il linguaggio C dispone di una libreria standard di ingresso e uscita, che
definisce le funzioni C per le operazioni sui file:
fopen, fread, fwrite, fclose, fputs, fgets, ecc.
In linguaggio C il riferimento a file è dato da un puntatore
file * file_pointer
Le funzioni C usano il file pointer e invocano i servizi messi a disposizione dal
sistema operativo
Le implementazioni delle funzioni C su un certo Sistema Operativo
definiscono le modalità di chiamata dei servizi di Sistema Operativo
(primitive o System Call) e il legame tra il file pointer e il file descriptor.
Attenzione: fopen e simili possono avere comportamenti differenti da un
sistema operativo ad un altro (ad es. Unix System V e Linux Red Hat 7.2).
-8-
Organizzazione del file system
Strutturazione gerarchica del file system

Un file system è organizzato in:
–
–
Partizioni: contengono insiemi di file correlati
Directory: una partizione è suddivisa in directory. Le directory
contengono informazioni sui file o directory in esse contenuti e
fungono da indice.
•
–


Root Directory: directory accessibile direttamente e
autonomamente dal file system
File (ordinari): contengono effettivamente i dati o i programmi
Pathname assoluto (nome completo di un file): è il nome (percorso)
ottenuto concatenando tutti i nomi delle directory che devono
essere percorsi dalla root fino al file. Es: /usr/nome_file
Pathname relativo: è il nome del file nella directory a cui
appartiene. Es: nome_file
- 10 -
Directory




Le directory sono dei file (d) e quindi sono caratterizzati da
– nome e diritti d’accesso
Contengono informazioni sui file e directory in esse
contenuti (nome, attributi, proprietario)
Forniscono una corrispondenza tra nomi di file/directory e
file/directory stessi su disco.
Il contenuto di una directory può essere visto come una
tabella, con una entry per ogni file/directory in essa
contenuto. Ogni entry è del tipo:
<nome_file/nome_dir, riferimento>
- 11 -
Contenuto di una directory
Nome_file/
Nome_directory
Riferimento: (i-node)
posizione file/dir su disco
. (direttorio corrente)
3
.. (direttorio padre)
2
usr
4
nome_file_1
7
nome_file_2
8
…..
….
- 12 -
Operazioni su directory

Sulle directory, così 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 nuovo file
Rimozione di un file: Eliminazione di un descrittore di file. Il descrittore
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 di un file: Modifica il nome di un file già presente nella
directory. Il descrittore deve essere prima individuato tramite una
operazione di ricerca.
Copia di un file
Per creare una nuova directory si usa la funzione mkdir ( )
- 13 -
Organizzazione delle directory

Tutti i file sono contenuti in una sola directory
–

Struttura molto semplice ma presenta alcuni problemi (unicità dei nomi,
ricerca inefficiente, accesso indifferenziato per tutti gli utenti)
Directory su due livelli
•
•
–
–
Directory principale: (root) contiene un elenco di directory, uno per
ogni utente
Directory utente: contiene i file di un singolo utente (home).
I singoli utenti vedono e gestiscono solo i file nella propria
directory home
La gestione della root è affidata ad un amministratore del sistema
(root, administrator, superuser).
- 14 -
Organizzazione a due livelli




Quando un utente richiede l’accesso ad un file, il file system ne cerca il
nome nella home dell’utente.
Per accedere ai file di altri utenti si utilizza il path name cioè la
composizione del nome dell’utente e del nome del file.
Spesso gli applicativi sono accessibili a tutti gli utenti e memorizzati in una
directory specifica (bin).
I file vengono prima cercati nella directory dell’utente quindi, se la ricerca
fallisce, nella directory degli applicativi
bin
gcc
tcsh
emacs
mike
test
bill
data
- 15 -
john
foo
gnu
data
Directory ad albero





Estensione del caso precedente ad un numero arbitrario di livelli
Un utente accede ai file attraverso il pathname (assoluto o relativo)
Per semplificare l’accesso ai file viene definito il concetto di current
working directory (cwd) cioè di directory corrente
I file vengono cercati nella directory corrente. Se un file non è nella
directory corrente:
–
Si usa il suo path name assoluto
–
Si cambia la directory corrente
Il sistema operativo offre alcuni comandi per gestire la cwd:
– cd <dir>: Change Directory. La directory dir diviene la cwd
– pwd: Print Working Directory. Mostra il nome della cwd
- 16 -
Esempio di directory ad albero
bin
gcc
tcsh
mike
test
aax
data
bill
data
jhon
foo
type
gnu
mary
her
- 17 -
mom
work
much
data
Periferiche e file speciali





In Unix le periferiche sono viste come file speciali, contenute nella
directory /dev.
Sulle periferiche è possibile eseguire operazioni come open, read e
write (purché abbia senso), close ma non si può usare creat.
Per creare un nuovo file speciale si usa la funzione mknod ( )
Ogni programma, all’esecuzione, dispone già di 3 descrittori di file:
stdin (0), stdout (1), stderr (2)
associati rispettivamente alla tastiera (0) e al video (1) e (2).
I descrittori standard possono essere ridiretti su altri file. Ad esempio:
close (1); /* chiude lo standard output e libera il
descrittore 1 */
fd = open (“./outputfile”, O_WRONLY);
/* il descrittore 1 viene associato a ouputfile, quindi ogni
operazione su 1 viene eseguita su outputfile */
- 18 -
Protezione e diritti di accesso
Protezione e diritti d’accesso


I dati memorizzati nei file di un file system necessitano di
protezione da accessi impropri (riservatezza, modifica o
eliminazione accidentale di dati importanti)
Definizione di una politica di accesso e relativa implementazione
•

Alcune banali politiche di accesso sono:
– Ogni utente accede solo ai propri file
– Ogni utente accede a tutti i file
Accesso controllato: si definiscono regole di accesso ai file sulla
base di:
–
–
–
l’identità degli utenti e del gruppo di lavoro dell’utente
la proprietà dei file
il tipo di operazione richiesta:
lettura, scrittura, esecuzione, eliminazione, ecc.
- 20 -
Protezione: Liste di accesso



L’accesso e le operazioni consentite dipendono dall’identità
dell’utente
Ad ogni file è associata una lista di accesso che indica quali
operazioni sono consentite a quali utenti
Quando un’operazione viene richiesta il sistema operativo controlla
la lista di accesso per verificare se:
–
–

il richiedente è previsto;
il richiedente ha il permesso di compiere quel tipo di operazione.
Questa soluzione presenta alcuni svantaggi:
–
–
–
le liste di accesso possono essere di dimensioni notevoli;
le liste devono essere create e mantenute per ogni file;
il tempo di accesso ad un file si allunga.
- 21 -
Protezione: UNIX (i)


UNIX adotta una soluzione semplificata delle liste di
accesso
Gli utenti sono identificati in base a:
–
–

Username: Identificativo dell’utente
Group:
Identificativo di gruppo, condiviso da più utenti
Gli utenti sono raggruppati in tre classi:
–
–
–
Owner:
Group:
All:
Solo il proprietario del file
Solo i membri del gruppo del proprietario del file
Tutti gli utenti
- 22 -
Protezione: UNIX (ii)

Le operazioni su file sono raggruppate in tre classi:
–
–
–

Read:
Lettura, copia
Write: Scrittura, modifica, eliminazione
Execute: Esecuzione
Ad ogni file sono associati:
–
–
–
Owner
Group
Control access list
- 23 -
Protezione: UNIX (iii)

La control access list è formata da tre gruppi di bit:
Ogni gruppo di bit si riferisce ad una delle tre classi di utenti
(owner, group, all)
–
Ogni bit del gruppo si riferisce ad una delle tre operazioni (rwx)
–
owner
group
all
owner
group
all
rwx
rwx
rwx
rwx
rwx
rwx
111
101
101
7
5
5
execute
write
read
- 24 -
Organizzazione logica e fisica del file system
Mapping del file system logico sul dispositivo fisico

Il file system svolge le sue funzioni accedendo ai
dispositivi fisici (dischi) tramite l’invocazione di routine
messe a disposizione dal gestore del disco (disk driver)
–

Il driver del disco fornisce una interfaccia di accesso ai dati su
disco nascondendone le caratteristiche fisiche
Il disco, a livello di file system, è rappresentato da un
dispositivo logico, chiamato volume composto da un
array di blocchi
–
Il blocco è una porzione di disco costituita da un numero intero
di byte che viene trasferita in memoria con un’unica operazione
- 26 -
Struttura del dispositivo fisico: tracce e settori

Traccia (track): sequenza circolare di bit scritta mentre il disco
compie una rotazione completa:
–
–

Settore (sector): parte di una traccia corrispondente a un settore
circolare del disco:
–
–
–

la larghezza di una traccia dipende dalla dimensione della testina e
dall’accuratezza con cui la si può posizionare; la densità radiale va da 800
a 2000 tracce per centimetro (5-10 µm per traccia);
tra una traccia e l’altra c’è un piccolo spazio di separazione (gap).
un settore contiene 512 byte di dati, preceduti da un preambolo, e seguiti
da un codice di correzione degli errori;
la densità lineare è di circa 50-100kbit per cm (0.1-0.2 µm per bit);
tra settori consecutivi si trova un piccolo spazio (intersector gap).
Formattazione: operazione che predispone tracce e settori per la
lettura/scrittura.
- 27 -
Spazi tra
tracce
Settore
Tracce
Spazi tra
record
- 28 -
Testina di
lettura/scrittura
(una per superficie)
Superficie 7
Superficie 6
Superficie 5
Superficie 4
Superficie 3
Superficie 2
Superficie 1
Direzione del
movimento
Superficie 0
Le tracce in grigio formano un “cilindro”
- 29 -
Prestazioni dei dischi

Tempo di acceso (ms o 10-3s)
–
Seek time
•
•
–
Latency
•
•

la testina deve arrivare alla traccia giusta;
dipende dalla meccanica (5-15 ms, 1 per tracce adiacenti).
il disco deve ruotare fino a portare il dato nella posizione giusta;
dipende dalla velocità di rotazione (5400-10800 RPM  2.7-5.4ms).
Transfer Rate (MBps)
–
Velocità di trasferimento del disco
•
•
–
dipende dalla densità di registrazione e dalla velocità di rotazione;
un settore di 512 byte richiede fra 25 e 100 µsec (5-20 MB/sec).
Velocità di trasferimento del sistema di controllo
•
SCSI vs. EIDE
- 30 -
Struttura del dispositivo logico: Volume



UNIX gestisce i file system a livello logico considerandoli come
dispositivi logici (volumi) identificati da un numero
Il volume è composto da una sequenza di blocchi logici (vettore di
blocchi), di dimensioni fisse pari a un multiplo di 512 byte
(configurabile a livello di sistema).
La conversione tra indirizzi del dispositivo logico (volumi e blocchi) e
indirizzi fisici (tracce e settori) è realizzata dal driver del disco.

Ogni volume è autonomo e contiene il proprio file system

Ogni volume viene visto come device logico
- 31 -
Blocco di un volume




Il blocco è l’unità di informazione trasferita con un solo accesso a
disco, quindi è un multiplo del settore. In generale, la dimensione
di un blocco è pari a 512 Byte.
Un blocco può essere letto o scritto in una zona di memoria centrale
di pari dimensione (buffer)
Il gestore dei buffer (buffer cache - parte del gestore della memoria
virtuale) gestisce le aree di buffer cercando di minimizzare le
letture multiple a disco
Quando il file system richiede la lettura di un blocco interagisce con
il gestore dei buffer che, a sua volta, può interagire con il disk
driver
- 32 -
Struttura logica di un file



Il file è visto dal file system come una sequenza di blocchi logici
numerati in sequenza a partire dal Blocco 0 all’interno del file
Le operazioni read, write etc. fanno riferimento alla posizione
corrente nel file (offset del byte nel file)
Ad esempio: ricerca del byte 520 (posizione corrente nel file):
–
–
Blocco = 520 div 512  Blocco 1
Offset nel blocco = 520 % 512 (resto della divisione)  Offset 8
Offset =8
Blocco 0
Blocco 1
Blocco 2
0
512
1024
- 33 -
1350
1536
Tecnica di allocazione dei blocchi logici
di un file nel volume
File
Posizione corrente:
520
Byte
520
Blocchi del File
Blocco 0 del file
La corrispondenza tra i
blocchi logici di un file e i
blocchi del volume in cui
viene memorizzato dipende
dalla tecnica di allocazione
Byte 8
Blocchi del
volume
0
….
45
….
123
124
- 34 -
Blocco 1
del file
Blocco 2 del file
Volume
Offset del byte nel volume
Tecnica di allocazione: UNIX i-node






Un volume contiene l’immagine del file system ad esso associato.
Il sistema operativo UNIX utilizza lo schema di allocazione indicizzata
combinata dei blocchi logici dei file sui blocchi del volume
La tecnica è realizzata mediante una lista (i-list) i cui elementi sono
chiamati i-node (index-node).
Ogni i-node contiene la lista degli attributi e degli indirizzi dei blocchi fisici
del disco a cui sono associati i blocchi logici del file. Dato il numero dell’inode (i-number) si può localizzare la posizione del file/dir calcolandone
l’indirizzo su disco
Un file esiste nel file system se esiste il corrispondente i-node nella i-list.
La lista degli i-node ha dimensione prefissata in fase di configurazione del
sistema operativo (quindi i numero massimo di i-node che possono essere
creati in un volume risulta prefissato).
- 35 -
Struttura di un volume (1)
Blocco
di boot
Super
block
Lista i-node
Blocchi dati
Un volume è suddiviso in 4 aree distinte:
1.
2.
3.
4.
Blocco 0 o blocco di boostrap: contenuto tipicamente nel primo settore del
disco, contiene il codice di inizializzazione del sistema operativo (altrimenti
è comunque allocato ma non utilizzato)
Blocco 1 o Superblock: contiene le informazioni globali del file system (es.
dimensione del volume, numero di blocchi liberi nel volume, ecc.)
Lista degli i-node: Ogni elemento della lista è un i-node che contiene la
lista degli indirizzi dei blocchi dati del file su disco
Blocchi di dati: blocchi che contengono il contenuto dei file e dei direttori.
Nel caso di una directory, il corrispondente blocco contiene una tabella con
la lista di file/direttori in essa contenuti rappresentati dalla coppia
< nome_file/nome_dir, i_node >
- 36 -
Struttura di un volume (2)




Ogni file ordinario, directory o file speciale ha associato un i-node
–
i-node: struttura contenente 64 byte di informazioni
Gli i-node dei file in un disco sono memorizzati in sequenza numerica
e costituiscono la i-list (lista degli i-node).
Ogni i-node è accessibile attraverso l’indice (i-number) relativo alla
sua posizione all’interno della i-list.
In una directory, i file/directory contenuti sono rappresentati da una
tabella le cui entry sono costituite dalla coppia:
<nome_file|nome_dir, i_node >
- 37 -
Esempio (1)

Il contenuto di una directory può essere visto come una tabella con una
entry per ogni file/directory in essa contenuto:
<nome_file|nome_dir, i_node >
/usr
root
bin
usr
.
6
..
1
f1
10
f2
20
sub_dir
40
/usr/sub_dir
sub_dir
pwd
cwd
f1
f2
f4
f5
- 38 -
.
40
..
6
f4
1024
f5
520
Esempio (2)
10 (file1)
Blocco
di boot
Super
block
910
1040
Lista i-node
blk
910
blk
1040
Conte
nuto
file1
Conti
nuaz.
file1
Blocchi dati
Esempio: file1 (associato a i-node 10) costituito da 2 blocchi (910 e 1040)
- 39 -
Esempio (3)
6 (/usr)
Blocco
di boot
Super
block
800
10 (file1)
910
1040
Lista i-node
blk
800
blk
910
blk
1040
F1 |10
Conte
nuto
file1
Conti
nuaz.
file1
Blocchi dati
Esempio: Directory /usr (associata a i-node 6) contenente file1
(associato a i-node 10) costituito da 2 blocchi (910 e 1040)
- 40 -
Informazioni contenute nell’i-node (64Byte)








Tipo di file: d directory, b file speciale per device a blocchi (es. disco), c file
speciale per device a caratteri
Proprietario del file (owner) e gruppo (group) del proprietario
Bit di protezione: Control Access List (9 rwx)
Numero di link (# riferimenti) al file fisico cioè allo stesso i-node
(rappresenta il numero di riferimenti allo stesso file fisico condiviso da parte
di più nomi simbolici creati con la primitiva link).
Dimensione del file in blocchi (se file ordinario o direttorio) e dimensione del
blocco
Puntatori ai blocchi dell’area dati: 13 indirizzi che referenziano in modo
diretto o indiretto i blocchi dati contenenti il file su disco. (Non sono
significativi nel caso di file speciale)
Data e ora in cui il file è stato letto e scritto per l’ultima volta (ultimo
accesso)
Data e ora dell’ultima modifica dell’i-node
- 41 -
Allocazione indicizzata negli UNIX i-node




I primi 10 indirizzi su disco rappresentano direttamente i puntatori ai blocchi del
file su disco (Indirizzamento diretto di 10 blocchi).
Per file di dimensioni maggiori, l’i-node contiene l’indirizzo di un blocco del
disco chiamato single indirect block (11) che a sua volta contiene altri 128
indirizzi di blocchi del disco (Nota: 1 blocco da 512Byte può contenere 128
indirizzi da 4Byte ciascuno)
(Indirizzamento indiretto di 128 blocchi)
Se questo non è sufficiente, l’i-node mette a disposizione un altro indirizzo,
chiamato double indirect block (12) che contiene l’indirizzo di un blocco che a
sua volta contiene una lista di 128 single indirect block. Ognuno di questi blocchi
punta a sua volta a 128 single indirect block (in pratica si realizza un doppio
livello di indicizzazione cioè un indirizzamento indiretto doppio di 128x128
blocchi)
Esiste anche un triple indirect block (13) nel caso la doppia indicizzazione non sia
sufficiente e sia necessario un terzo livello di indicizzazione: Indirizzamento
indiretto triplo di 128 x 128 x 128 blocchi
- 42 -
Rappresentazione dell’i-node
i-node
Data
Mode
Owner, group
Timestamp
Size
Number of blocks
Number of references
Data
Data
Data
Data
Data
Data
Data
Direct blocks (10)
Data
Data
11
12
13
Data
Single indirect blocks
Double indirect blocks
Triple indirect blocks
Data
- 43 -
Data
Contenuto del superblock

Il superblock contiene le informazioni necessarie a creare o
eliminare un file, ad aggiungere o togliere blocchi a un file
esistente:
–
dimensione del volume;
–
numero di blocchi liberi nel volume;
–
(parte iniziale della) lista dei blocchi liberi (free-list);
–
numero di elementi della lista dei blocchi liberi (free-list);
–
numero di elementi della lista degli i-node (i-list);
–
numero di i-node liberi (free i-nodes) ;
–
lista degli i-node liberi (free i-node list);
–
altre informazioni ausiliarie.
- 44 -
Gestione dello spazio libero (1)




Al momento della creazione del file system da associare ad un
volume (mkfs) viene allocata la lista (i-list) di dimensione fissa
contenente gli i-node.
La lista degli i-node (i-list) è costituita da una sequenza di i-node
utilizzati e i-node liberi (tipo di file =0)
Le posizioni degli i-node liberi sono riportate nella free i-node list
contenuta nel superblocco.
La lista dei blocchi liberi (free list) è una lista concatenata di
blocchi liberi. La parte iniziale della free list è contenuta nel
superblocco.
- 45 -
Gestione dello spazio libero (2)


All’atto della creazione e scrittura di un file è necessario individuare sul
disco il primo blocco libero da allocare al file
UNIX utilizza una lista concatenata di blocchi liberi – free list (in
genere il primo elemento della lista punta ad un’altra lista …)
lista dei blocchi liberi (parte contenuta nel superblock)
180
150
151
154
160
161
…
…
…
…
lista dei blocchi liberi (parte contenuta nel blocco 180)
240
… … … … … … … … … … … … … … … … … …
lista dei blocchi liberi (parte contenuta nel blocco 240)
280
… … … … … … … … … … … … … … … … … …
- 46 -
Strutture dati per la gestione del file system
Strutture dati del file system (1)
Per la gestione efficiente del file system, il sistema operativo
dispone di tre tabelle residenti in memoria centrale :

Tabella dei descrittori dei file aperti per processo
–

Tabella globale dei file aperti
–
–

Esiste una tabella per ogni processo attivo nel sistema
Tabella globale del sistema operativo che contiene una riga per ogni file
aperto nel sistema;
Ogni elemento viene referenziato tramite gli elementi delle tabelle dei
file aperti per processo
Tabella degli i-node (detti anche in-core i-node)
–
Tabella globale del sistema contenente una copia in memoria degli inode del volume relativi a file e directory aperte per maggiore
efficienza nei riferimenti.
- 48 -
Tabella dei descrittori dei file aperti per processo




Tabella associata ad ogni processo utente e costituita da un
elemento (riga) per ogni file aperto dal processo
Indice della tabella = descrittore del file (fd)
Per convenzione, per ogni processo vengono aperti automaticamente
3 descrittori di file associati ai primi tre elementi della tabella:
stdin (0), stdout (1), stderr (2) associati rispettivamente alla
tastiera (0) e al video (1 e 2)
Ogni entry (riga) della tabella contiene un puntatore o indice della
riga della tabella globale dei file aperti relativa al file
fd1
0
stdin
1
stdout
2
stderr
3
…
…
…
- 49 -
Tabella globale dei file aperti


Indice della tabella = Puntatore/i proveniente/i dalle tabelle dei
descrittori dei file aperti dei processi
Ogni entry(riga) della tabella contiene:

Offset nel file: Indicatore della posizione corrente nel file da
usare per il prossimo accesso. Valore calcolato come numero di
byte dall’origine del file

Modalità di apertura del file (READ|WRITE|RW)

Numero di riferimenti da parte dei processi a questo file
condiviso

Puntatore o indice al corrispondente i-node nella tabella degli inode
- 50 -
Tabella degli i-node




Tabella globale del sistema contenente una copia in memoria degli i-node
(detti anche in-core i-node) del volume per maggiore efficienza
nell’accesso ai file aperti
Ogni entry (riga) della tabella contiene una copia in memoria degli i-node
statici presenti su disco nella i-list.
Ogni entry (riga) della tabella contiene anche il contatore al Numero di
riferimenti che indica il numero di istanze del file che sono attivi
Oltre alla copia delle informazioni presenti nel corrispondente i-node
statico, sono presenti informazioni riguardanti lo stato dell’i-node.
Es.: se ci sono processi in attesa di accedere all’i-node, se i-node è stato
modificato e deve quindi essere riscritto su disco, se il contenuto del file è
stato modificato e quindi i suoi blocchi devono essere scritti su disco.
- 51 -
Esempio (1): P0 apre il file F (fd1) e il file G (fd2)
Tabella dei descrittori di
file aperti per processo
P0
Tabella globale
dei file aperti
Tabella degli i-node
10
fd1
/usr/f1
fd2
20
Processo P0:
fd1 = open(“/usr/f1”);
fd2 = open(“/usr/f2”);
- 52 -
/usr/f2
Esempio (2): Apertura dello stesso
file da parte di più processi


Per uno stesso file vengono allocati tanti elementi (righe) nelle due tabelle
(privata e globale) quante sono le volte che il file viene aperto (dallo stesso
processo oppure da altri processi) che convergono ad uno stesso in-core inode.
Nel caso di apertura dello stesso file da parte di 2 processi vengono allocati
2 elementi nelle 2 tabelle private e 2 elementi nella tabella globale. Notare
che nella tabella globale i 2 elementi possono avere (offset, mode) con
valori diversi
Processo P0:
fd1 = open (“/usr/f1”);
Processo P1:
fd7 = open (“/usr/f1”);
- 53 -
Esempio (2): P0 apre il file F (fd1);
P1 apre lo stesso file F (fd7)
Tabella dei descrittori di
file aperti per processo
Processo P0
Tabella globale
dei file aperti
Tabella degli i-node
#rif =2
fd1
#rif =1
#rif =1
Processo P1
fd7
- 54 -
10
/usr/f1
Esempio (3): dup

Nel caso di apertura di un file F da parte di un processo P0 e di duplicazione
da parte dello stesso processo si ha che la dup:
–
–
Duplica il descrittore del file cioè duplica la riga nella tabella privata
che punta però allo stesso elemento nella tabella globale (con lo stesso
offset nel file)
Incrementa il contatore dei riferimenti al file nella tabella globale (ma
non si incrementa il numero di riferimenti all’i-node del file nella
Tabella degli i-inode)
Processo P0:
fd1 = open(“/usr/f1”);
fd3 = dup(fd1);
- 55 -
Esempio (3): P0 apre il file F (fd1);
P0 duplica il file F (fd3)
Tabella dei descrittori di
file aperti per processo
Processo P0
Tabella globale
dei file aperti
Tabella degli i-node
#rif =1
#rif =2
fd1
fd3
- 56 -
10
/usr/f1
Esempio (4)


P apre il file F;
P esegue una fork, generando Q;
–
–

Duplicazione della Tabella dei descrittori dei file aperti per
processo
Esiste una sola riga nella Tabella globale dei file aperti (con lo
stesso offset e incrementando di 1 il numero di riferimenti al
file) che punta allo stesso i-node del file
R apre lo stesso file F
–
Nuova entry (riga) nella Tabella dei file aperti di R e nuova entry
(riga) nella Tabella globale dei file aperti (con un nuovo offset e
nuovo numero di rif. al file pari a 1) che punta allo stesso i-node
del file (incrementando il numero di riferimenti all’i-node nella
Tabella degli i-node)
- 57 -
Esempio (4)
Indicatore
posizione corrente
P
Numero
di riferimenti
#rif =2
#rif =2
i-node F
Q
#rif =1
R
Tabella
degli i-node
Tabella globale
file aperti
- 58 -
Condivisione di file aperti da parte
di più processi

Punto fondamentale della gestione tramite Tabella globale dei file
aperti consiste nel permettere ad un processo padre e figlio di
condividere la stessa posizione (offset) nel file e di permettere ad
altri processi di condividere un file aperto avendo una loro posizione
(offset) nel file condiviso.
- 59 -
Esempio (5)




P apre il file F;
P esegue una dup;
P esegue una fork, generando Q;
R apre lo stesso file F.
- 60 -
Esempio (5)
Indicatore
posizione corrente
P
Numero
di riferimenti
#rif =4
#rif =2
i-node F
Q
#rif =1
R
Tabella
degli i-node
Tabella globale
file aperti
- 61 -
Primitive per la gestione dei file
Creazione - creat()





Descrizione:
–
Creazione di un file ordinario: Viene aggiunto un nuovo file al file system e
restituisce un intero che rappresenta il file descriptor da usare in una
seguente chiamata di sistema (read, write, lseek, …)
Prototipo:
int creat(const char *file_name, mode_t mode);
– mode: gestisce modalità di accesso per la configurazione dei bit di
protezione.
Utilizzo (sintassi della chiamata):
fd = creat(file_name, mode);
– fd: file descriptor o descrittore del file da usare in una successiva chiamata
Se file_name corrisponde ad un file già esistente  il contenuto del file viene
cancellato e la dimensione del file diventa nulla.
Nota: per la creazione di un file speciale si usa mknod e per la creazione di una
directory si usa mkdir.
- 63 -
Apertura - open()



Descrizione:
–
Apertura di un file ordinario: Sulla base del nome del file individua la
posizione del file su disco e restituisce un intero che rappresenta il file
descriptor da usare in una seguente chiamata di sistema (read, write,
lseek, …)
Prototipo:
int open(const char *file_name, int flags, mode_t mode);
– flags: tipo o modalità di apertura del file:
O_RDONLY lettura, O_WRONLY scrittura, O_RDWR lettura e scrittura
– mode: gestisce i permessi di accesso per la configurazione dei bit di
protezione.
Utilizzo:
fd = open(file_name, O_RDONLY|O_WRONLY|O_RDWR, mode);
– fd: file descriptor o descrittore del file
- 64 -
Scrittura - write ( )




Descrizione:
–
Aggiunge dati ad un file già creato/aperto. Per scrivere dati su un file è
necessario fornire descrittore (ottenuto tramite open / creat) e un
puntatore ai dati da scrivere. Restituisce il numero di caratteri
effettivamente scritti alla fine dell’esecuzione della primitiva
(ritorna -1 in caso di errore).
Prototipo:
int write(int fd, char buffer[ ], int num_byte);
Utilizzo:
byte_scritti = write(fd, buf, num_byte);
• byte_scritti: restituisce il numero di caratteri effettivamente scritti.
• fd: file descriptor o descrittore del file
• buf: indirizzo dell’area contenente i dati da scrivere nel file
• num_byte: numero byte da scrivere
Il file system mantiene un indicatore alla posizione (offset) nel file in cui deve
essere effettuata la lettura/scrittura successiva.
- 65 -
Lettura - read( )



Descrizione:
–
Preleva dati da un file già creato/aperto. Per leggere dati su un file è
necessario fornire il descrittore (ottenuto tramite open / creat) e un
puntatore ai dati da leggere. Restituisce il numero di caratteri
effettivamente letti alla fine dell’esecuzione della primitiva
(ritorna -1 in caso di errore).
Prototipo:
int read(int fd, char buffer[ ], int num_byte);
Utilizzo:
byte_letti = read(fd, buf, num_byte);
•
•
•
•

byte_letti: restituisce il numero di caratteri effettivamente letti.
fd: file descriptor o descrittore del file
buf: indirizzo dell’area dati del processo destinata a contenente i dati letti
num_byte: numero byte da leggere
Il file system mantiene un indicatore alla posizione (offset) nel file in cui deve
essere effettuata la lettura/scrittura successiva.
- 66 -
Riposizionamento - lseek ( )


Descrizione: Riposiziona l’indicatore di lettura / scrittura di un file aperto
(cioè riposiziona la posizione corrente nel file detta anche offset nel file) .
Prototipo:
long lseek(int fd, long offset, int base);
modifica la posizione corrente nel file fd e la restituisce come long int. La
nuova posizione corrente nel file new_offset viene calcolata sommando
all’argomento offset il valore di base dove:
•
•
•


base = 0: inizio file
base = 1: posizione corrente nel file
base = 2: fine file
Utilizzo:
new_offset = lseek(fd, offset, base);
In pratica permette l’accesso alla posizione new_offset nel file fd
ottenuta sommando all’argomento offset il valore di base
Esempi:
–
lseek(fd, 0L, 1): restituisce la posizione corrente - senza modificarla;
–
lseek(fd, 0L, 0): riposiziona all’inizio del file;
–
lseek(fd, 0L, 2): riposiziona alla fine del file.
- 67 -
Duplicazione - dup( )
–
–
Descrizione: Duplicazione di un descrittore associato ad un file già aperto. In
pratica si aggiunge una nuova riga nella tabella dei file aperti da quel
processo che punta allo stesso file aperto nella tabella globale.
Prototipo:
int dup(int old_fd);
–
Utilizzo:
fd1=open(…);
fd2=dup(fd1);
•
la posizione corrente nel file (offset) è comunque la stessa per i due o
più descrittori (esiste una sola riga nella tabella globale dei file aperti) e
si incrementa il numero dei riferimenti al file nella tabella globale (non
si incrementa il numero dei riferimenti all’i-node del file nella tabella
degli i-node).
- 68 -
Chiusura - close( )

Descrizione: Chiude un descrittore di file aperto cioè elimina il descrittore
dalla tabella dei file aperti dal processo. Decrementa il numero di riferimenti
al file nella tabella globale, e solo se non vi sono altri riferimenti, elimina
l’elemento (riga) dalla tabella globale dei file aperti e il corrispondente
puntatore alla tabella degli i-node.
–

Nota: L’i-node del file rimane allocato nella Tabella degli i-node perché potrebbero
esserci altri riferimenti all’i-node da parte di altri processi o da parte di altri link
simbolici e in generale per sfruttare il principio di località temporale degli accessi.
Prototipo:
–
int close(int fd)
fd : descrittore di un file aperto precedentemente
Restituisce un intero che rappresenta l’esito dell’operazione di chiusura:
0 = successo nella chiusura
-1 = errore di chiusura
Utilizzo:
close(fd)
–

- 69 -
Ridenominazione - link ( )


Descrizione: Per associare un nuovo nome ad un file già esistente (il
contenuto dei 2 file è condiviso e anche l’i-number dei due file è condiviso).
Crea una nuova entry nella directory che contiene il file. Non crea un nuovo
descrittore, ma incrementa di uno il numero di link a quel file nell’i-node
del file presente nella i-list ed eventualmente presente nella Tabella degli inode in memoria
Prototipo:
int link(char *nome_file, char *nuovo_nome_file);
Restituisce un intero che rappresenta l’esito dell’operazione.
Utilizzo:
link(old_file_name, new_file_name);
•


Nota: La primitiva link consente di associare un nuovo nome ad un file già esistente
(i-number e contenuto dei 2 file è condiviso) mentre per copiare un file esistente si
deve usare il comando cp che richiede l’allocazione di un nuovo file e del relativo
i-node
- 70 -
Unlink - unlink ( )




Descrizione: Per interrompere il link creato tra 2 file cioè eliminare un riferimento (link)
ad un file specificato tramite nome (e decrementa di uno il numero di riferimenti al file
nel corrispondente i-node).
Se esisteva un solo link al file, e nessun processo ha aperto il file, il numero dei link al
file diventa 0 e il file in pratica viene eliminato dal file system in quanto diventa
inaccessibile e i blocchi dati associati vengono rilasciati. In questo caso, le azioni
necessarie sono:
• Deallocazione dell’i-node del file dal file system che viene aggiunto alla free
i-node list;
• Deallocazione dei blocchi dati sul dispositivo fisico che viene aggiunto alla lista
dello spazio disponibile (free list).
Se esisteva un solo link al file, ma almeno un processo ha aperto il file, la unlink verrà
eseguita solo dopo che l’ultimo descrittore associato al file è stato chiuso (close)
Prototipo:
int unlink(char *nome_file);

Utilizzo:
unlink(nome_file);
- 71 -
Un esempio (i)
/* Esempio di uso delle primitive LINUX di gestione dei file */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
void main()
{
int fd1;
int i,pos;
char c;
/* apertura del file */
fd1=open("fileprova", O_RDWR);
/* visualizza posizione corrente */
printf("\npos= %ld \n", lseek(fd1,0,1));
/* scrittura del file */
for (i=0; i<20;i++)
{
c=i + 65; /*caratteri ASCII a partire da A*/
write(fd1, &c, 1);
printf("%c",c);}
/* visualizza posizione corrente; riportala a 0 */
printf("\npos= %ld \n", lseek(fd1,0,1));
lseek(fd1,0,0);
- 72 -
Un esempio (ii)
/* lettura e visualizzazione del
for (i=0; i<20;i++)
{
read(fd1, &c, 1);
printf("%c",c);}
printf("\n");
file */
/* posizionamento al byte 5 del file e stampa posiz.*/
printf("\npos= %ld\n", lseek(fd1,5,0));
/*lettura di 5 caratteri */
for (i=0; i<5;i++)
{
read(fd1, &c, 1);
printf("%c",c);}
printf("\n");
/*scrittura di 5 caratteri x*/
c= 'x';
for (i=0; i<5;i++)
{
write(fd1, &c, 1);}
- 73 -
Un esempio (iii)
/* lettura del file dall'inizio */
lseek(fd1,0,0);
for (i=0; i<20;i++)
{
read(fd1, &c, 1);
printf("%c",c);}
printf("\n");
/* chiusura file */
close(fd1);
}
- 74 -
Primitive per la gestione dei file e
strutture dati del file system
Primitive per la gestione dei file e strutture dati del file system:
open( )

open( ): la richiesta di apertura di un file al sistema operativo
prevede le seguenti operazioni:
–
–
Riserva una riga nella tabella globale dei file aperti e inizializza
il contatore dei riferimenti e l’offset nel file e aggiorna il
puntatore alla tabella degli i-node.
Riserva un riga nella tabella dei descrittori dei file aperti del
processo e vi scrive l’indice della riga della tabella globale dei
file aperti
•
–
L’allocazione di un nuovo elemento nella tabella privata avviene
cercando il primo posto libero
Restituisce al processo il descrittore (fd) costituito dal numero
della riga (indice del file) della tabella dei descrittori di file
aperti per processo
- 76 -
Primitive per la gestione dei file e strutture dati del file system:
open( )

open( ): cont.
–
–
Determina quale sia l’i-node corrispondente al file il cui pathname è stato
indicato nella richiesta e scrive il suo riferimento (puntatore) nella riga della
tabella globale dei file aperti associata al file
Per questa operazione il file system esegue una ricerca ordinata all’interno
delle directory del pathname. Per esaminare ogni directory (memorizzato in un
blocco di dati del volume) è necessario accedere all’i-node corrispondente
presente nella tabella degli i-node (eventualmente ricopiato dalla i-list) e
caricare in memoria il suo contenuto
- 77 -
Primitive per la gestione dei file e strutture dati del file system:
open( )

open ( ): cont.

Ad esempio “/dir1/file”
–
–
–
–
–
–
Ricerca dell’i-node di root e caricamento in memoria dei blocchi che
costituiscono root (generalmente, almeno l’i-node di root è sempre caricato
nella Tabella degli i-node in posizione prefissata)
Ricerca nella tabella di root della entry di dir1 (<i-node, dir1>) per ricavare
l’i-node
Ricerca dell’i-node di dir1 e caricamento in memoria dei blocchi che
costituiscono dir1
Ricerca in dir1 della entry di file (<i-node, file>) per ricavare l’i-node del file
Se i-node è già presente nella Tabella degli i-node (come in-core i-node)
aggiorna il puntatore dalla Tabelle globale dei file aperti
Se i-node NON è già presente nella Tabella degli i-node => Copia l’i-node del
file nella Tabella degli i-node (come in-core i-node) e aggiorna il puntatore
dalla Tabella globale dei file aperti
- 78 -
Primitive per la gestione dei file e strutture dati del
file system: creat( )

creat( ): la richiesta di creazione di un file al sistema operativo
prevede le seguenti operazioni:
–
–
–
–
–
–
–
–
Verifica che esista un i-node libero
Verifica che esistano dei blocchi liberi
Riserva una riga nella tabella globale dei file aperti e inizializza il
contatore dei riferimenti e l’indicatore di posizione
Riserva un riga nella tabella dei descrittori di file utente aperti del
processo e vi scrive l’indice della riga della tabella globale dei file aperti
Restituisce al processo un descrittore costituito dal numero della riga della
tabella dei descrittori di file utente aperti
Alloca l’i-node al file, inizializzando le informazioni in esso contenute e
aggiorna le informazioni relative alla i-list
Aggiorna il contenuto della directory che contiene il file
Scrive nella riga della tabella globale dei file aperti associata al file il
riferimento all’i-node corrispondente al file
- 79 -
Primitive per la gestione dei file e strutture dati del
file system: dup( )e fork( )

dup( ):
–
–

si generano due descrittori nella medesima tabella dei file aperti da
quel processo e che puntano allo stesso file
Esiste una sola riga nella tabella globale dei file aperti (con la stessa
posizione corrente nel file) che punta allo stesso i-node del file e si
incrementa di 1 il numero di riferimenti nella Tabella globale dei file
aperti.
fork( ):
–
–
Duplicazione delle tabelle dei file aperti per processo
Esiste una sola riga nella tabella globale dei file aperti (con lo stesso
offset del file e si incrementa di 1 il numero di processi che hanno il file
aperto nella Tabella globale dei file aperti) che punta allo stesso i-node
del file
- 80 -
Primitive per la gestione dei file e strutture dati del
file system: open( )

open( ) dello stesso file da parte di uno stesso processo:
–
–

Si allocano 2 righe nella Tabella dei file per processo
si allocano 2 righe nella tabella globale dei file aperti che puntano allo
stesso i-node del file nella Tabella degli i-node (che avrà numero di
riferimenti pari a 2)
open( ) dello stesso file da parte di 2 processi:
–
–
Si alloca 1 riga in ciascuna Tabella dei file per processo
si allocano 2 righe nella tabella globale dei file aperti che puntano allo
stesso i-node del file nella Tabella degli i-node (che avrà numero di
riferimenti pari a 2)
• Ogni processo ha un proprio offset nel file
- 81 -
Primitive per la gestione dei file e strutture dati del
file system: read( ) write( ) close( )

read( ) o write( ):
–

Deve essere fornito il descrittore del file che permette di seguire
i puntatori nelle tre tabelle e tramite l’i-node identificare i
blocchi di dati del file. Si aggiorna l’offset nella Tabella globale
dei file aperti.
close( ):
–
–
Il sistema operativo libera la corrispondente riga nella tabella dei
descrittori dei file aperti per processo
Decrementa il contatore dei riferimenti nella tabella globale dei
file aperti e se diventa zera, libera la riga nella tabella globale.
- 82 -