4.8 Il VFS

GNU/Linux ha la possibilità di utilizzare vari filesystem (v. tab. 4.2) grazie alla presenza di un filesystem virtuale, il VFS (Virtual FileSystem). Questo strato di software (in gergo abstraction layer), presente nel kernel, permette al sistema di supportare vari filesystem senza “conoscerli”, infatti esso mette a disposizione delle applicazioni che girano sul sistema, un’interfaccia composta da una serie di funzioni che non fanno riferimento ad uno specifico filesystem (v. fig. 4.10). Tali funzioni chiamano poi delle opportune routine che devono essere implementate dal driver dello specifico filesystem considerato. Il tutto viene gestito a basso livello, in maniera trasparente al sistema. I driver per la gestione dei vari tipi di filesystem devono comunque rispettare determinate regole per potersi integrare con il VFS.


pict
Figura 4.10: Schematizzazione del VFS.

Grazie al VFS, tutti i filesytem utilizzati da GNU/Linux hanno la stessa struttura logica, ovvero vengono presentati all’utente tutti nella stessa maniera.

Per la gestione del filesystem virtuale, il VFS utilizza strutture dati, come superblock e inode, analoghe a quelle di ext2. Ogni filesystem montato (v. sez. 4.9) è rappresentato da un superblock, che tra le varie informazioni contiene quelle seguenti

Ogni oggetto del filesystem reale è rappresentato da un inode del VFS, che tra le varie informazioni contiene quelle seguenti Più in dettaglio, la struttura di un inode del VFS è riportata di seguito (sintassi C)

struct inode {
 kdev_t                       i_dev;
 unsigned long                i_ino;
 umode_t                      i_mode;
 nlink_t                      i_nlink;
 uid_t                        i_uid;
 gid_t                        i_gid;
 kdev_t                       i_rdev;
 off_t                        i_size;
 time_t                       i_atime;
 time_t                       i_mtime;
 time_t                       i_ctime;
 unsigned long                i_blksize;
 unsigned long                i_blocks;
 unsigned long                i_version;
 unsigned long                i_nrpages;
 struct semaphore             i_sem;
 struct inode_operations      *i_op;
 struct super_block           *i_sb;
 struct wait_queue            *i_wait;
 struct file_lock             *i_flock;
 struct vm_area_struct        *i_mmap;
 struct page                  *i_pages;
 struct dquot                 *i_dquot[MAXQUOTAS];
                                                                        
                                                                        
 struct inode                 *i_next, *i_prev;
 struct inode                 *i_hash_next, *i_hash_prev;
 struct inode                 *i_bound_to, *i_bound_by;
 struct inode                 *i_mount;
 unsigned short               i_count;
 unsigned short               i_flags;
 unsigned char                i_lock;
 unsigned char                i_dirt;
 unsigned char                i_pipe;
 unsigned char                i_sock;
 unsigned char                i_seek;
 unsigned char                i_update;
 unsigned short               i_writecount;
 union {
    struct pipe_inode_info   pipe_i;
    struct minix_inode_info  minix_i;
    struct ext_inode_info    ext_i;
    struct ext2_inode_info   ext2_i;
    struct hpfs_inode_info   hpfs_i;
    struct msdos_inode_info  msdos_i;
    struct umsdos_inode_info umsdos_i;
    struct iso_inode_info    isofs_i;
    struct nfs_inode_info    nfs_i;
    struct xiafs_inode_info  xiafs_i;
    struct sysv_inode_info   sysv_i;
    struct affs_inode_info   affs_i;
    struct ufs_inode_info    ufs_i;
    struct socket            socket_i;
    void                     *generic_ip;
 } u;
};
Le routine di gestione del filesystem reale, hanno l’onere di tenere aggionate le strutture del VFS.

Il kernel, inoltre, utilizza degli specifici buffer, inode cache e directory cache (parti della memoria centrale, molto veloci rispetto alla memoria di massa), che velocizzano le operazioni sul filesystem. Quando si vuol accedere ad un file o una directory, il VFS controlla se il relativo inode è presente nella inode cache. Se lo è accede direttamente a quello, altrimenti chiama la routine che effettua l’accesso all’inode sullo specifico filesystem sul quale esso risiede (anche il filesystem specifico utilizza un proprio meccanismo di caching). Una volta recuperato, questo viene memorizzato nella inode cache in maniera tale che un eventuale ulteriore accesso ad esso avvenga senza più coinvolgere il filesystem specifico sul quale esso risiede. Se la inode cache risulta piena vengono rimossi gli inode acceduti meno di frequente per far posto ai nuovi inode da memorizzare. Inoltre, ogni volta che si accede ad una directory, il VFS controlla che il suo contenuto non sia già stato memorizzato nella directory cache. In caso affermativo accede direttamente al suo contentuo, altrimenti chiama la routine che effettua l’accesso alla directory nello specifico filesystem sul quale essa risiede. Una volta recuperata, il suo contenuto (le varie dentry) viene memorizzato nella directory cache, in maniera tale che un eventuale ulteriore accesso ad essa avvenga senza più coinvolgere lo specifico filesystem nel quale essa risiede.