High Performance File System


Obiettivi di progetto e realizzazione del nuovo Sistema di gestione dei File ad Alte Prestazioni

Traduzione di Maurilio Longo, testo originale (c) 1989 Microsoft Corporation


Prefazione

Sebbene lo High Performance File System (il metodo nativo di formattazione delle partizioni in OS/2) sia disponibile sin dalla versione 1.2 di OS/2 (1989), ancora oggi molti utenti installano OS/2 su una partizione FAT, un po' per pigrizia un po' perché timorosi di non riuscire a gestire eventuali problemi che si dovessero presentare sul nuovo tipo di file system.

Eppure lo HPFS ha moltissimi vantaggi sulla FAT, anzi è stato sviluppato proprio nel preciso intento di superare i problemi che la FAT, già nel 1989, cominciava a creare; non solo, ma nelle specifiche del progetto HPFS sono state tenute in estrema considerazione tutte le peculiarità che un file system destinato a un ambiente multitasking e multithreading come OS/2 doveva possedere fin dalla nascita al fine di ottimizzare le prestazioni, lo sfruttamento dello spazio disponibile e, nel contempo, ridurre al minimo i possibili problemi.

Questo articolo contiene la traduzione di un testo sotto copyright Microsoft (sebbene liberamente prelevabile da internet) in quanto fu proprio compito di Microsoft l'ideare lo HPFS quando ancora era in società con IBM e lo sviluppo di OS/2 veniva portato avanti da entrambe.

Il testo ha qualche piccolo anacronismo e, laddove questo può ingenerare dubbi o perplessità, sono intervenuto con delle brevi note, tuttavia nella grandissima parte questo testo è attuale anche perché la FAT è ancora tra noi, magari con un nome un po' differente (tipo VFAT o FAT32), ma tutti i suoi limiti sono rimasti invariati e, nel contempo, lo HPFS ha ancora oggi innegabili vantaggi.

Mi auguro che questa lettura spinga, coloro tra di voi che ancora sono recalcitranti, ad impiegare lo HPFS per formattare la partizione che contiene OS/2 e, magari, anche quella/e che contengono gli applicativi OS/2.

*****  Computer Library Periodicals, Jan 1990 : Doc #14753  *****

Journal:Microsoft Systems Journal  Sept 1989  v4 n5 p1(13)

        * Full Text COPYRIGHT Microsoft Corp. 1989.
-------------------------------------------------------------------------
Title:  Design goals and implementation of the new High Performance File
        System.
Author: Duncan, Roy.

[...]
-------------------------------------------------------------------------

Introduzione

Lo High Performance File System (HPFS d'ora in poi), che sta facendo la sua prima apparizione nella versione 1.2 del sistema operativo OS/2, nacque nella divisione reti della Microsoft e venne progettato da Gordon Letwin, capo progetto del sistema operativo OS/2. Lo HPFS è stato progettato in modo da soddisfare le richieste di vieppiù potenti PC, dischi fissi e reti per diversi anni a venire, nonché come piattaforma adatta per linguaggi, applicazioni e interfacce utente orientati agli oggetti.

Lo HPFS è un argomento complesso dal momento che incorpora tre aspetti distinti sebbene tra loro interconnessi di un file system. In primo luogo lo HPFS è un metodo per organizzare i dati su un dispositivo di memorizzazione a blocchi con accesso casuale. Inoltre è un modulo software che traduce le richieste, orientate ai file, di un programma in richieste, di più basso livello, comprensibili a un driver di dispositivo usando diverse tecniche originali tese a ottimizzare le prestazioni. Infine lo HPFS è una dimostrazione pratica di una nuova e importante caratteristica di OS/2 che va sotto il nome di file system installabile.

Questo articolo introduce i tre aspetti dello HPFS. Ma, per prima cosa, pone lo HPFS nella giusta prospettiva analizzando alcuni dei problemi che hanno portato alla sua nascita.

FAT File System

La cosiddetta FAT, usata fino ad ora in tutte le versioni del sistema operativo MS-DOS e nelle prime due versioni di OS/2 (v1.0 e 1.1), deriva sia dai primi linguaggi di programmazione prodotti da Microsoft sia dal sistema operativo CP/M scritto in origine da Digital Research per i microcomputer basati su 8080 e Z80. Da entrambi i progenitori ha ereditato caratteristiche che si sono via via tramutate in difetti all'approssimarsi di questa nuova era caratterizzata da multitasking, modalità protetta, memoria virtuale ed enormi dischi fissi.

La FAT si basa sulla Tabella di Allocazione dei File, da cui prende il nome. Ogni volume logico ha la sua FAT che svolge due importanti funzioni: contiene le informazioni sull'allocazione di ogni file del volume sotto forma di liste collegate di unità d'allocazione (clusters [gruppi n.d.t.] di settori, multipli di potenze di due) e indica quali unità d'allocazione sono disponibili per la creazione di un nuovo file o l'estensione di uno esistente.

La FAT venne inventata da Bill Gates e Marc McDonald nel 1977 come metodo di gestione dello spazio su disco per il Microsoft Disk Basic sviluppato per NCR. Tim Paterson, a quel tempo impiegato della Seattle Computer Products (SCP), venne a conoscenza della FAT quando la sua compagnia condivise uno stand con Microsoft alla National Computer Conference nel 1979. Paterson, successivamente, incorporò la FAT nel file system dello 86-DOS, un sistema operativo per le schede con cpu 8086 e bus S-100 della SCP. Lo 86-DOS fu infine acquistato dalla Microsoft e utilizzato come base su cui sviluppare lo MS-DOS v1.0 che venne reso disponibile insieme al primo PC IBM nell'agosto del 1981.

La FAT, quando venne concepita, era un metodo intelligente di gestione dei dischi, soprattutto perché i floppy su cui era utilizzata difficilmente avevano una dimensione superiore al megabyte. Su dischi di questo tipo la FAT era sufficientemente piccola da poter essere tenuta sempre in memoria, consentendo un accesso casuale molto veloce a qualsiasi punto di un file. E, in questo, era molto superiore al metodo usato dallo CP/M per tenere traccia dello spazio su disco, metodo in cui l'informazione sui settori assegnati a un file poteva essere distribuita su più elementi della directory i quali, a loro volta, erano sparsi casualmente sull'intera directory del disco.

Tuttavia, portata sui dischi fissi, la FAT cominciò ad apparire più come un difetto che non come una caratteristica. Divenne troppo grande per poter essere contenuta interamente in memoria e pertanto doveva essere caricata a pezzi, cosa che comportava movimenti superflui delle testine del disco, mentre un programma scorreva un file, degradando le prestazioni del sistema. In più, dal momento che l'informazione sullo spazio libero nel disco era sparpagliata su molti settori della FAT, era scomodo allocare lo spazio occupato da un file in modo contiguo e, così, la frammentazione dei file era un'ulteriore ostacolo a delle buone prestazioni. Infine, l'uso, sui dischi fissi, di cluster relativamente grandi comportava lo spreco di un grossa quantità di spazio dal momento che, in media, viene sprecato mezzo cluster per file. (Alcuni server di rete usano cluster anche da 64Kb.)

Le restrizioni che la FAT impone sui nomi dei file e delle directory provengono dal CP/M. Mentre Paterson scriveva lo 86-DOS una delle sue principali preoccupazioni era di rendere facile la conversione dei programmi dal CP/M al suo nuovo sistema operativo. Perciò adottò i limiti sui nomi e le estensioni che aveva il CP/M affinché i campi dei File Control Blocks [Blocchi di Controllo del File n.d.t.] (FCB) fossero praticamente uguali a quelli del CP/M. La dimensione del campo contenente il nome e del campo contenente l'estensione venne utilizzata anche per la struttura che definisce un elemento di directory sul disco. A tempo debito lo 86-DOS divenne MS-DOS e i programmi per MS-DOS proliferarono al di la delle più rosee aspettative. Il formato 8.3 per i nomi dei file divenne irrimediabilmente parte integrante del sistema dal momento che, inizialmente, la maggior parte dei programmi utilizzava la struttura dei FCB.

Negli ultimi due anni [1988, 89 n.d.t.] Microsoft e IBM hanno provato soluzioni coraggiose al fine di prolungare la vita utile della FAT, diminuendo le restrizioni sulle dimensioni di un volume, migliorando le strategie di allocazione, tenendo in memoria i pathname [percorsi identificativi di un file su disco n.d.t.] e spostando tabelle e buffer nella memoria espansa. Ma queste sono solo misure temporeggiatrici, poiché le strutture dati fondamentali utilizzate dalla FAT semplicemente non sono adatte a gestire grandi dispositivi ad accesso casuale.

Lo HPFS risolve i problemi della FAT cui abbiamo accennato oltre a diversi altri, ma non è in alcun modo derivato dalla FAT. Chi ha sviluppato lo HPFS è partito da un foglio bianco e ha disegnato un file system in grado di sfruttare completamente un ambiente multitasking e di far fronte a qualsiasi tipo di dispositivo di massa che si può presumere venga reso disponibile nei microcomputer nel corso del prossimo decennio.

Struttura di un Volume HPFS

Un volume HPFS è una partizione di nuovo tipo - il tipo 7 - e può coesistere sullo stesso disco con i diversi tipi di partizione FAT definiti nel passato. I volumi HPFS sui compatibili IBM usano settori da 512 byte e hanno una dimensione massima di 2199 Gb (2^32 settori). [L'attuale realizzazione dello HPFS prevede una dimensione massima di 512 Gb n.d.t.] Sebbene non ci sia una particolare ragione per non formattare in HPFS anche i floppy, Microsoft ha intenzione di continuare a usare la FAT sui floppy nell'immediato futuro. (Questo assicura che gli utenti riusciranno a trasportare facilmente i file tra sistemi MS-DOS e OS/2).

Un volume HPFS ha pochissime strutture fisse. I settori 0-15 di un volume (8 Kb) formano il BootBlock e contengono il nome del volume, un identificativo a 32 bit e un programma per il bootstrap [procedura d'avvio n.d.t.]. Il bootstrap è relativamente sofisticato (almeno confrontandolo con quello dello MS-DOS) e può utilizzare lo HPFS in maniera limitata al fine di rintracciare sul disco i file necessari, ovunque si trovino.

I settori 16 e 17 vanno rispettivamente sotto il nome di SuperBlock e SpareBlock. Il SuperBlock è modificato solo dai programmi di gestione del disco. Contiene puntatori alle bitmap [mappe di bit n.d.t.] che rappresentano lo spazio libero, alla lista dei blocchi rovinati, alla zona dei blocchi directory e alla directory radice. Contiene anche la data dell'ultimo controllo e riparazione svolto con CHKDSK /F. Lo SpareBlock contiene diversi puntatori e flag [indicatore, generalmente sotto forma di bit in una word o doubleword n.d.t.] che vedremo in seguito; viene modificato, sebbene di rado, durante il funzionamento del sistema.

Il resto del disco viene diviso in zone da 8 Mb. Ognuna di queste zone ha la sua bitmap che tiene traccia dello spazio libero, ogni bit rappresenta un settore. Un bit è 0 se il settore è in uso, 1 se è libero. Le bitmap sono collocate alternativamente all'inizio e alla fine di una zona cosicché le bitmap di due zone sono tra loro adiacenti. Questo comporta che la massima quantità di spazio contiguo che può essere allocato per un file è di 16 Mb. Una zona, posta più o meno al centro della parte utile del disco, è chiamata zona dei blocchi directory ed è utilizzata in modo particolare (vedremo dopo quale). Resta da osservare che la dimensione delle zone è una caratteristica dell'attuale realizzazione e potrebbe cambiare in versioni successive del file system.

File e Fnode

Ogni file o directory su un volume HPFS è collegato a un oggetto fondamentale del file system chiamato Fnode (da pronunciarsi come 'eff node'). Ogni Fnode occupa un solo settore e contiene: informazioni usate internamente dal file system per il controllo e lo storico dell'accesso, attributi estesi e liste di controllo dell'accesso (di cui parleremo più avanti), la lunghezza e i primi 15 caratteri del nome del file o directory associato e una struttura d'allocazione. Un Fnode si trova sempre vicino al file o directory che rappresenta.

La struttura d'allocazione all'interno di un Fnode cambia a seconda delle dimensioni e del grado di contiguità del file o directory che rappresenta. Lo HPFS vede un file come un insieme di una o più serie, o successioni, di uno o più settori contigui. Ogni serie è definita da una coppia di doubleword - un numero a 32 bit per il settore d'inizio e un numero a 32 bit per la lunghezza in settori (questo tipo di codifica viene detta run-length). Dal punto di vista di un programma applicativo, tuttavia, le successioni sono invisibili e il file appare come un flusso ininterrotto di byte.

Lo spazio riservato per l'informazione sull'allocazione all'interno di un Fnode è sufficiente a contenere i puntatori a otto serie di settori grandi al massimo 16 Mb ciascuna. (Questo massimo non è un limite inerente al file system, ma il risultato della dimensione di una zona e della posizione in cui viene posta la bitmap che indica lo spazio libero). File ragionevolmente piccoli o molto contigui possono perciò essere descritti completamente all'interno di un Fnode.

Lo HPFS usa un metodo innovativo per tenere traccia della posizione di file troppo grandi o frammentati per essere contenuti nelle 8 serie che trovano posto in un Fnode. La struttura d'allocazione del Fnode diventa la radice per un B+ Tree [Albero binario bilanciato in cui i nodi intermedi contengono solo riferimenti, in genere multipli, ad altri nodi e non valori n.d.t.] di settori d'allocazione che, a loro volta, contengono i puntatori effettivi alle serie di settori che compongono il file. Lo Fnode radice ha spazio per 12 elementi. Ogni elemento, o settore d'allocazione, è in grado di contenere, oltre a diverse informazioni di controllo, fino a 40 puntatori a serie di settori. Perciò, nella corrente realizzazione, un B+ Tree di allocazione a due livelli può descrivere un file di 480 (12 * 40) serie di settori con una dimensione massima teorica di 7,68 Gb (12 * 40 * 16 Mb) (sebbene il puntatore a 32 bit con segno che viene passato alla DosChgFilePtr limiti la dimensione effettiva massima di un file a 2 Gb).

Nell'improbabile eventualità che un B+ Tree a due livelli non riesca a rappresentare un file altamente frammentato, il file system può aggiungere livelli addizionali all'albero secondo le necessità. I settori d'allocazione nei livelli intermedi sono in grado di contenere fino a 60 nodi non terminali del B+ Tree, il che vuol dire che la capacità di rappresentazione di questa struttura raggiunge rapidamente valori quasi al di là della comprensione. Per esempio, un B+ Tree di settori d'allocazione a tre livelli riesce a descrivere un file con qualcosa come 28.800 (12 * 60 * 40) serie di settori.

La codifica run-length e i B+ Tree di settori d'allocazione sono un metodo efficiente (con riguardo alla memoria) per descrivere la posizione e dimensione di un file, ma hanno anche altri vantaggi importanti. La trasformazione della posizione logica all'interno di un file in un numero di settore è estremamente veloce: il file system necessita solamente di attraversare la lista (o il B+ Tree di liste) di puntatori alle serie finché trova l'intervallo corretto. A questo punto per identificare il settore all'interno della serie basta un semplice calcolo. La codifica run-length rende anche particolarmente semplice estendere logicamente il file nel caso che il settore appena assegnato sia contiguo al precedente ultimo settore; si tratta semplicemente di incrementare, nel puntatore all'ultima serie del file, la doubleword della dimensione e di azzerare il bit opportuno nella bitmap che rappresenta lo spazio libero.

Indirizzari

Le directory, come i file, sono ancorate a un Fnode. Il puntatore allo Fnode per la directory radice si trova nel SuperBlock. Gli Fnode, per le directory diverse da quella radice, si trovano scorrendo gli elementi di tipo subdirectory presenti nelle directory di livello superiore.

Le directory non hanno limite sulla dimensione e sono composte da blocchi di 2 Kb detti blocchi directory, i blocchi directory sono allocati sotto forma di 4 settori contigui sul disco. Il file system cerca di allocare i blocchi directory nella zona dei blocchi directory che si trova circa al centro dello spazio utile del disco. Quando la zona dei blocchi directory è piena i blocchi directory vengono allocati ovunque ci sia spazio disponibile.

Ogni blocco directory da 2 Kb contiene uno o più elementi della directory. Un elemento della directory contiene svariati campi, tra cui i marcatori di data e ora, un puntatore allo Fnode, un contatore d'uso utilizzato da programmi di manutenzione del disco, la lunghezza del nome del file o directory, il nome e un puntatore al B Tree [Albero binario bilanciato n.d.t.]. Ogni elemento inizia con una word [un valore a 16 bit n.d.t.] che contiene la dimensione dell'elemento. Questo consente di avere una quantità variabile di spazio libero alla fine di ogni elemento che può venire utilizzato da versioni speciali del file system e consente di attraversare molto velocemente il blocco directory.

Il numero di elementi in un blocco directory varia in funzione della lunghezza del nome degli elementi stessi. Se la lunghezza media del nome è di 13 caratteri, un blocco directory medio è in grado di contenere circa 40 elementi. Gli elementi di un blocco directory sono ordinati in base al valore numerico delle lettere nel campo che contiene il nome (col che vengono messi in ordine alfabetico rispetto all'alfabeto degli U.S.A). L'ultimo elemento in un blocco directory è un elemento particolare che segna la fine del blocco.

Quando una directory diviene troppo grande per essere contenuta in un solo blocco la sua dimensione viene accresciuta dall'aggiunta di nuovi blocchi da 2 Kb organizzati in un B Tree. Nella ricerca di uno specifico nome il sistema attraversa un blocco directory finché o trova una corrispondenza o trova un nome lessicalmente maggiore di quello ricercato. In quest'ultimo caso il file system recupera il puntatore al B Tree dall'elemento. Se non c'è alcun puntatore la ricerca ha avuto esito negativo, altrimenti il file system recupera tramite il puntatore il successivo blocco directory nell'albero e continua la ricerca.

Quattro calcoli forniscono alcuni dati molto interessanti. Dati 40 elementi per blocco, un albero di due livelli di blocchi directory è in grado di contenere 1640 elementi, un albero di tre livelli ne può contenere l'incredibile numero di 65.640. In altre parole è possibile trovare un file (o verificarne l'assenza) in una directory che ne contenga 65.640 usando un massimo di tre accessi al disco - il numero effettivo di accessi in realtà dipende dal contenuto della cache [una zona di memoria del sistema usata come memoria di transito durante le operazioni di I/O n.d.t.] e dalla posizione del nome del file nel B Tree di blocchi directory. E c'è una bella differenza tra questo risultato e quello che si ottiene in un file system FAT dove, nel caso peggiore, è necessario leggere più di 4000 settori per poter stabilire l'esistenza (o la non esistenza) di un file in una directory con lo stesso numero di file.

Al di là dell'effetto sulle operazioni di apertura e ricerca dei file, la struttura a B Tree delle directory ha altri interessanti risvolti. La creazione, cancellazione o il cambiamento del nome di un file può dar luogo ad una serie di operazioni complesse dovute alla creazione o cancellazione di blocchi directory o allo spostamento di un nome da un blocco directory a un altro al fine di mantenere l'albero bilanciato. In realtà un'operazione di rinomina potrebbe in teoria non essere completata per mancanza di spazio sul disco anche se il file in sè non aumenta di dimensione. Per evitare questo tipo di problemi lo HPFS conserva un piccolo numero di blocchi liberi che vengono utilizzati in caso di un'emergenza dovuta a una directory; il puntatore a questo gruppo di blocchi liberi è conservato nello SpareBlock.

Attributi Estesi

Gli attributi di un file sono un tipo di informazione sul file che viene mantenuta dal sistema operativo al di fuori dell'area normalmente occupata dai file. Il file system FAT supporta solo pochi semplici attributi (read only, system, hidden, archive [solo lettura, sistema, nascosto e archivio n.d.t.]) che sono in effetti flag salvati nell'elemento della directory che riguarda il file in questione; questi attributi sono ispezionati o modificati attraverso l'uso di apposite funzioni e non sono accessibili attraverso le normali chiamate per l'apertura, lettura o scrittura dei file.

Lo HPFS supporta, per ragioni storiche, i medesimi attributi della FAT, ma tuttavia fornisce il supporto anche per un nuovo tipo di informazioni associate ai file ed estremamente generiche che va sotto il nome di Attributi Estesi (EA). Ciascun attributo esteso è concettualmente simile ad una variabile d'ambiente avendone la forma

nome-valore
tuttavia la parte valore può essere sia una stringa null-terminated (ASCIIZ) sia dei dati binari. In OS/2 1.2 ogni file o directory può avere fino a 64 Kb di attributi estesi. Questo limite potrebbe essere tolto in una successiva versione di OS/2.

Gli EA vengono conservati in modi diversi. Se gli EA associati a un file o a una directory sono sufficientemente piccoli, vengono inseriti direttamente nello Fnode. Se la dimensione totale degli EA è troppo grande, vengono inseriti all'esterno dello Fnode in una serie di settori e un B+ Tree di settori d'allocazione viene creato per descrivere le serie. Se un singolo EA è troppo grande viene messo all'esterno dello Fnode in un B+ Tree tutto suo.

Le funzioni delle API [Interfaccia per i Programmi Applicativi n.d.t.] del kernel [il nucleo base di un sistema operativo n.d.t.] DosQFileInfo e DosSetFileInfo sono state espanse con nuovi livelli d'informazione che permettono ad un programma applicativo di manipolare gli EA dei file. Le nuove funzioni DosQPathInfo e DosSetPathInfo vengono usate per scrivere gli EA associati a un pathname qualsiasi. Un programma applicativo può sia chiedere il valore di uno specifico EA (fornendo il nome da trovare) sia ottenere tutti gli EA associati a un file o directory in un colpo solo.

Sebbene i programmi applicativi potranno cominciare a sfruttare i vantaggi degli EA non appena lo HPFS sarà reso disponibile, il supporto per gli EA, nei progetti a lungo termine della Microsoft, è un tassello fondamentale per dei file system orientati agli oggetti. Negli EA si può immagazzinare qualsiasi tipo d'informazione, dal nome dell'applicazione che ha creato il file al nome di file dipendenti, da delle icone a del codice eseguibile. Durante l'evoluzione dello HPFS le sue capacità di manipolazione degli EA diverranno sicuramente più sofisticate. È facile immaginare, ad esempio, che future versioni delle API potrebbero essere estese con funzioni per gli EA analoghe alla DosFindFirst e DosFindNext e gli EA stessi essere organizzati in B Tree.

Devo far qui notare che la versione dello HPFS che sarà inclusa in LAN Manager, oltre agli EA, fornirà il supporto per un'altra classe di informazioni associate ai file chiamate Liste di Controllo dell'Accesso (ACL). Le ACL hanno lo stesso aspetto generico degli EA e vengono gestite in maniera simile, ma vengono usate per conservare i diritti d'accesso, le parole d'ordine e altre informazioni utili in un ambiente di rete e multiutente.

File System Installabili

Il supporto per file system installabili è stata una delle caratteristiche, di OS/2 versione 1.2, attese con più impazienza. Renderà possibile l'accesso a più strutture di volume incompatibili - FAT, HPFS, CD ROM e forse anche UNIX - sullo stesso sistema OS/2 e nello stesso tempo; semplificherà la vita di chi pone in essere reti e aprirà la porta ad una rapida evoluzione e innovazione dei file system. Comunque, i file system installabili sono, al momento, rilevanti solo per lo HPFS che ne fa uso e consentono di renderlo un componente opzionale. Il file system FAT è ancora compreso nel kernel di OS/2, così come era in OS/2 1.0 e 1.1, e vi rimarrà come file system per la compatibilità anche nel prossimo futuro.

Il driver di un file system installabile (FSD) ha molte analogie con i driver di dispositivo. Un FSD risiede su disco in un file che ha la stessa struttura di una libreria a collegamento dinamico (DLL), in genere con una estensione .SYS o .IFS, e viene caricato durante l'inizializzazione del sistema in corrispondenza di un comando IFS= nel CONFIG.SYS. I comandi IFS= sono eseguiti nell'ordine in cui appaiono e rispettano l'ordine dei comandi DEVICE= che caricano i driver di dispositivo. In tal modo è possibile caricare un driver per un dispositivo non standard e, successivamente, un driver per file system da un volume su quel dispositivo, e cosi' via.

Il kernel, una volta che il FSD è stato caricato e inizializzato, comunica con lui in termini di richieste logiche relative ad aperture, letture, scritture, ricerche su, chiusure e via dicendo, di file. Il FSD traduce queste richieste - usando delle strutture di controllo e tabelle che trova sul volume stesso - in richieste di lettura o scrittura di settori che poi passa a speciali funzioni del kernel chiamate File System Helpers (FsHlps). Il kernel, a sua volta, passa le richieste di I/O al driver di dispositivo appropriato e ritorna il risultato al FSD.

La procedura che il sistema operativo impiega per associare un volume a un FSD è denominata installazione dinamica e funziona nel modo seguente: ogniqualvolta si verifica il primo accesso a un volume o dopo che è stato bloccato per potervi accedere direttamente e quindi sbloccato (per esempio a seguito di un'operazione di FORMAT), OS/2 fornisce delle informazioni d'identificazione prese dal volume a ciascuno dei FSD finché uno non riconosce l'informazione. Quando un FSD rivendica il volume, questo viene in stallato e tutte le successive richieste di I/O per quel volume sono rigirate a quel FSD.

Considerazioni sulle Prestazioni

Lo HPFS combatte i potenziali colli di bottiglia, nel trasferimento dati dai dischi, a diversi livelli. Fa uso di strutture dati avanzate, allocazione di settori contigui, gestione intelligente della cache, letture in avanti e scritture posticipate al fine di incrementare le prestazioni.

In primo luogo, lo HPFS usa strutture adatte per ciascun compito che deve eseguire: sofisticate strutture dati (B Tree e B+ Tree) per un veloce accesso casuale ai nomi dei file, delle directory e alle liste di settori allocati ai file o directory; strutture semplici e compatte (bitmap) per localizzare blocchi di spazio libero di dimensione appropriata. Le procedure che manipolano queste strutture dati sono scritte in assembler e sono state ottimizzate oltre l'immaginabile, ponendo particolare cura alle procedure che lavorano sulle bitmap alla ricerca di configurazioni di bit a 1 (settori non utilizzati).

Poi, l'obiettivo fondamentale dello HPFS - la sua direttiva prima per così dire - è quello di assegnare, laddove possibile, settori consecutivi ai file. Il tempo necessario a muovere le testine di lettura/scrittura dei dischi da una traccia a un'altra è di molto superiore a qualsiasi altra possibile causa di attesa, perciò lo HPFS svolge un notevole lavoro nel tentativo di minimizzare questo tipo di movimenti allocando lo spazio richiesto dai file in modo che sia contiguo e mantenendo le strutture di controllo quali gli Fnode e le bitmap dello spazio libero vicino agli oggetti che controllano. File molto contigui aiutano il file system a richiedere un numero minore di operazioni, con un maggior numero di settori per richiesta, al driver del dispositivo e consentono di fruttare le capacità di trasferimento multisettore del controller del disco e di ridurre il numero di interrupt da servire a seguito del completamento di un'operazione di I/O.

Ovviamente non è un lavoro semplice tentare di mantenere contigui i file in un sistema multitasking dove diversi file vengono modificati contemporaneamente. Una strategia usata dallo HPFS è di distribuire sul disco i file appena creati - in zone separate, se possibile - cosicché i settori allocati per i file, quando questi crescono, non siano interlacciati. Un'altra strategia consiste nel preallocare 4 Kb di spazio contiguo ogniqualvolta il file deve essere ingrandito, liberando lo spazio allocato in eccesso quando il file viene chiuso. Se un'applicazione è a conoscenza della dimensione finale che avrà il file che sta creando, può comunicarlo al file system specificando la dimensione iniziale che deve avere il nuovo file. A questo punto il file system cercherà nelle bitmap che indicano lo spazio libero una serie di settori consecutivi in grado di contenere il nuovo file. Nel caso non ci sia un simile spazio libero cercherà due spazi grandi la metà e così via.

Lo HPFS si appoggia su diverse tecniche di gestione della cache al fine di diminuire il numero di richieste di trasferimento da/per il disco che deve fare. Ovviamente trasferisce nella cache i settori così come faceva la FAT. Ma, a differenza del file system FAT, lo HPFS può gestire delle cache molto grandi in maniera efficiente ed è in grado di modificare la gestione, file per file, a seconda di come il file viene utilizzato. Lo HPFS trasferisce nella cache anche i pathname e le directory, anzi gli elementi delle directory vengono mantenuti in memoria in maniera anche più compatta ed efficiente.

Un'altra tecnica usata dallo HPFS per migliorare le prestazioni è quella di leggere in anticipo i dati di cui ritiene che un programma avrà bisogno. Ad esempio quando un file viene aperto il file system leggerà e trasferirà nella cache lo Fnode e i primi settori del file stesso. Se il file è un programma eseguibile, o le informazioni sulla storia dell'utilizzazione nello Fnode mostrano che, successivamente all'apertura, si è normalmente avuta una lettura sequenziale dell'intero file, il file system leggerà in anticipo e trasferirà nella cache una parte molto più grande del file. Quando un programma esegue richieste di lettura relativamente piccole, allora il file system recupera i dati dal file in blocchi da 2 Kb e mette nella cache la parte eccedente la richiesta, consentendo così di soddisfare la maggior parte delle richieste direttamente dalla cache.

Infine, il supporto che OS/2 fornisce per il multitasking consente allo HPFS di sfruttare pesantemente le cosiddette lazy write(talvolta chiamate scritture posticipate o all'indietro) per migliorare le prestazioni. Quando un programma esegue una richiesta di scrittura su disco, i dati vengono piazzati nella cache e quel buffer della cache viene marcato come 'sporco' (ovvero in uno stato inconsistente rispetto ai dati presenti sul disco). Quando il disco è inattivo o la cache è piena di buffer sporchi, il file system, per mezzo di un thread facente parte di un processo che gira in background (demone), scrive i buffer sporchi su disco a partire da quelli modificati da più tempo.

In generale le lazy write consentono a un programma di essere più veloce in quanto le operazioni di lettura non sono interrotte in attesa del completamento di quelle di scrittura. Inoltre, per programmi che ripetutamente leggono, modificano e scrivono un piccolo insieme di record, si ottiene che molte operazioni di scrittura su disco non necessarie o ridondanti vengano eliminate. Ci sono dei rischi, ovviamente, nell'usare le lazy write, pertanto un programma può rinunciarvi, file per file, attivando il flag di scrittura diretta nel parametro che indica la modalità di apertura di un file nella DosOpen, oppure forzare la scrittura dei dati su disco, sempre file per file, utilizzando la funzione DosBufReset.

Resistenza ai guasti

L'uso estensivo che lo HPFS fa delle lazy write comporta l'inderogabile conseguenza che lo HPFS deve essere in grado di recuperare facilmente errori di scrittura in qualsiasi circostanza tranne la più disastrosa. Dopo tutto, nel momento in cui si viene a sapere che c'è stato un errore di scrittura, l'applicazione è già da un pezzo passata a fare altro convinta di avere una copia corretta dei dati su disco. Gli errori possono essere rilevati dallo hardware (tipo il 'settore non trovato' che viene ritornato dal controller del disco) oppure dal driver del disco al posto dello hardware durante una lettura di verifica a seguito di una scrittura.

Il sistema principale di gestione degli errori di scrittura è detto hotfix [correzione a caldo n.d.t.]. Quando viene rilevato un errore il file system prende un blocco libero da un gruppo disponibile proprio per i casi di hotfix, scrive i dati in tale blocco e quindi aggiorna la mappa degli hotfix. (La mappa degli hotfix è semplicemente una serie di coppie di doubleword laddove ogni coppia contiene il numero del settore rovinato e il numero del settore che lo rimpiazza nello hotfix. Il puntatore alla mappa degli hotfix si trova nello SpareBlock.) A questo punto la mappa degli hotfix viene scritta su disco e un messaggio di avvertimento indica all'utente che c'è qualcosa che non va nel disco.

Il file system, ogni volta che richiede al driver del disco una lettura o scrittura di un settore, esegue una scansione della mappa degli hotfix e sostituisce al numero di ogni settore rovinato quello del settore che contiene effettivamente i dati. Questa conversione a parte dei numeri di settore non è gravosa, come invece sembra, dal momento che la lista degli hotfix deve essere controllata solo quando c'è un'operazione di lettura o scrittura fisica di un settore sul disco, e non ogni volta che c'è un accesso alla cache.

Uno dei compiti di CHKDSK consiste proprio nello svuotare la mappa degli hotfix. Per ogni blocco di rimpiazzo presente nella mappa degli hotfix alloca un nuovo settore in una posizione favorevole per il file che contiene tale settore e muove i dati dal blocco dello hotfix al settore appena allocato, infine aggiorna l'informazione sull'allocazione del file (cosa che può richiedere il bilanciamento degli alberi d'allocazione ed altre operazioni complesse). Quindi aggiunge il settore difettoso alla lista di tali settori, rimette il settore di hotfix a disposizione del gruppo di settori destinato a tale compito, cancella il riferimento a tale hotfix dall'apposita mappa e salva su disco la mappa così aggiornata.

Ovviamente gli errori di scrittura che si riescono ad identificare e sistemare al volo non sono l'unico tipo di calamità che può abbattersi su un file system. I progettisti dello HPFS hanno dovuto tenere in considerazione anche gli inevitabili danni che posso essere causati da cadute della corrente, blocchi di programmi, virus maligni e cavalli di Troia, per non parlare di quegli utenti che spengono la macchina senza prima eseguire l'apposita procedura di chiusura presente nella Scrivania. (L'apposita procedura di chiusura richiede al file system di riportare su disco tutte le modifiche ancora presenti nella cache, aggiornare le directory e svolgere qualunque altro compito necessario per mettere il disco in uno stato consistente.)

Lo HPFS si difende dall'utente che usa in maniera troppo brutale il Grosso Interruttore Rosso [nei primi PC dell'IBM l'interruttore d'accensione era a forma di leva, rosso, ed era posto sul lato destro della macchina n.d.t.] mantenendo il flag DirtyFS nello SpareBlock di ogni volume HPFS. Tale flag viene azzerato solo quando tutti i file su quel volume sono stati chiusi e tutti i buffer della cache marcati come sporchi sono stati scritti su disco o, nel caso del volume da cui si esegue l'avvio del sistema (dal momento che il file di swap e OS2.INI non sono mai chiusi), quando si esegue l'apposita procedura di chiusura e questa ha completato il suo compito.

Il file system controlla il flag DirtyFS di ogni volume HPFS durante la sequenza di avvio di OS/2 e, se lo trova attivato, non consente ulteriori accessi a quel volume se prima non viene eseguito CHKDSK. Se il flag DirtyFS è attivato nel volume d'avvio, il sistema si rifiuta di partire; l'utente, allora, dovrà riavviare OS/2 in modalità di manutenzione da un dischetto ed eseguire CHKDSK per controllare ed eventualmente riparare il volume d'avvio. [Nelle attuali versioni di OS/2 questa procedura è stata resa automatica e non occorre più riavviare il sistema con il dischetto n.d.t.]

Lo HPFS è stato pensato in modo da massimizzare la probabilità di riuscire a recuperare i dati nell'eventualità di un vero e proprio disastro, quale la perdita del SuperBlock o della directory radice. Tutti gli oggetti cruciali per i file - inclusi gli Fnode, i settori d'allocazione e i blocchi directory - sono doppiamente collegati sia ai 'genitori' sia ai 'figli' e contengono un identificatore a 32 bit univoco. Gli Fnode contengono anche la parte iniziale del nome dei loro file o directory. Pertanto, CHKDSK è in grado di ricostruire un intero volume scorrendolo metodicamente alla ricerca di Fnode, settori d'allocazione e blocchi directory e usando le informazioni trovate per ricostruire i file e le directory e, successivamente, le bitmap che indicano lo spazio libero.

Programmi Applicativi e lo HPFS

Ogni versione di OS/2 rilasciata finora ha portato con sè dei cambiamenti fondamentali per i programmatori di applicativi che hanno imparato il loro mestiere nell'ambiente dello MS-DOS. Con OS/2 1.0, tali programmatori, si sono confrontati per la prima volta con la memoria virtuale, il multitasking, le comunicazioni tra processi e le restrizioni che la modalità protetta pone nell'indirizzamento e nel controllo diretto dello hardware e si sono trovati a dover padroneggiare nuovi e potenti concetti quali la suddivisione dei programmi in thread e il collegamento dinamico. Con OS/2 Versione 1.1 la posta in gioco è stata ulteriormente innalzata. Ai programmatori è stato offerta una potente interfaccia grafica per l'utente, indipendente dallo hardware, ma hanno dovuto ristrutturare pesantemente le loro applicazioni per adattarle ad un ambiente controllato dagli eventi e basato sul passaggio di oggetti e messaggi.

Con OS/2 1.2 è giunto il momento di lasciare per strada molte delle abitudini e supposizioni, della programmazione relativa ai file, che ci si porta dietro dall'ambiente dello MS-DOS. Un'applicazione che voglia avvantaggiarsi completamente dello HPFS deve consentire l'uso di nomi di file, o directory, lunghi, senza particolare struttura, che hanno al loro interno maiuscole e minuscole, con poche restrizioni sulla presenza di punteggiatura e, inoltre, deve accorgersi e gestire la presenza di EA e ACL. Dopo tutto, affinché gli EA siano di una qualche utilità, le applicazioni non potranno aggiornare un file semplicemente rinominando il vecchio e creandone uno nuovo, ma dovranno anche copiare gli EA.

Comunque le modifiche necessarie per la versione 1.2 di OS/2 non richiedono strani espedienti per essere messe in pratica. Una nuova funzione delle API, DosCopy, aiuta le applicazioni a creare copie - in pratica duplica un file esistente insieme agli eventuali EA associati. Gli EA possono anche essere manipolati esplicitamente per mezzo delle funzioni DosQFileInfo, DosSetFileInfo, DosQPathInfo e DosSetPathInfo. Gli applicativi dovrebbero, durante l'esecuzione, chiamare la DosQSysInfo per sapere la lunghezza massima di un pathname nel sistema, e assicurarsi che i buffer usati dalle DosChDir, DosQCurDir e funzioni correlate siano larghi a sufficienza. Allo stesso modo i buffer usati dalle funzioni DosOpen, DosMove, DosGetModName, DosFindFirst, DosFindNext e similari devono consentire l'uso di nomi lunghi. Qualunque logica di controllo che si basi sul caso delle lettere dei nomi o sull'occorrenza di un solo punto all'interno del nome del file deve essere ripensata o eliminata.

Le altre modifiche nelle API non avranno effetto sull'applicativo medio. Le funzioni DosQFileInfo, DosFindFirst e DosFindNext adesso ritornano tutti e tre gli insiemi di tempi e date (di creazione, ultimo accesso, ultima modifica) associati a un file su un volume HPFS, tuttavia pochi programmi hanno, in ogni caso, la necessità di gestirli. DosQFsInfo serve, come prima, per ottenere il nome associato ai volumi o le caratteristiche del disco, e anche l'uso di DosSetFsInfo per il nome dei volumi non è cambiato. Ci sono poi alcune funzioni delle API totalmente nuove quali la DosFsCtl (analoga della DosDevIOCtl ma utile per comunicazioni tra un'applicativo e il FSD), DosFsAttach (una chiamata per eseguire una specie di collegamento esplicito) e la DosQFsAttach (per determinare quale file system possiede un dato volume); tuttavia queste funzioni sono pensate principalmente per programmi di utilità per il disco.

Al fine di prevenire possibili danni ai file su HPFS, da parte di vecchi programmi per OS/2 o di programmi MS-DOS in esecuzione nella finestra di compatibilità, un nuovo flag è stato definito nell'intestazione dei file EXE al fine di segnalare se ne è previsto l'uso sotto HPFS. L'applicativo, se il flag non è attivato, sarà in grado, su un volume HPFS, di accedere, ricercare o creare solamente file compatibili con la convenzione 8.3 dei nomi della FAT. Se invece il flag è attivato, allora OS/2 consentirà all'applicativo l'accesso a tutti i file su una partizione HPFS, poiché darà per scontato che il programma sa come maneggiare nomi lunghi e senza una struttura specifica e si prende cura di conservare gli eventuali EA e ACL presenti.

Conclusioni

Lo HPFS risolve tutti gli storici problemi del file system FAT. Inoltre, consegue prestazioni elevate anche in casi estremi - molti piccoli file o pochi molto grandi - utilizzando strutture dati avanzate e tecniche quali la gestione intelligente della cache, letture in anticipo e scritture posticipate. Lo spazio su disco viene usato al meglio poiché la gestione si basa sui settori. Gli attuali programmi applicativi richiederanno delle modifiche per sfruttare a fondo il supporto che lo HPFS fornisce per gli EA e i nomi di file lunghi, tuttavia tali modifiche non sono difficili da fare. Tutti i programmi applicativi trarranno comunque vantaggio dalle migliorate prestazioni e minore uso della CPU dello HPFS, sia che siano modificati sia che non lo siano.

Questo articolo si basa su una versione non definitiva dello HPFS, sul quale erano ancora incorso modifiche e miglioramenti. Pertanto la versione definitiva delloHPFS potrebbe avere alcune differenze di dettaglio rispetto a quanto scritto. Ed.

[La parte in corsivo è un'annotazione dell'autore dell'articolo originale n.d.t.]


a cura di Maurilio Longo

- [ Pagina precedente ] - - [ Sommario ] - - [ Just WARP! homepage ] - - [ Pagina successiva ] -