Você está na página 1de 43

The Virtual File

System (VFS)

Andrey Matheus Coppieters


Profº. Vitor Santos
Sistemas Operacionais I
Arquivos - Introdução
? Necessidade de armazenamento de informações que
precisam estar disponíveis após eventual “restart” do
sistema.
? Meio físico comum utilizado: disco rígido. Para
ler/gravar no disco é necessário saber informações
sobre: a superfície, a trilha e o setor.
? O device driver faz a conversão do que o S.O.
enxerga, virtual e unidimensional (array de blocos),
para o endereçamento real de 3 campos. A
linearização do disco é realizada através da
numeração dos setores, de forma optimizada, tal que
blocos próximos no array virtual correspondam setores
próximos entre si fisicamente.
? No Linux, cada dispositivo, inclusive os discos rígidos,
corresponde à um arquivo especial no sistema. No
caso dos discos, há um regra fixa para nomenclatura.
/dev/hda
hda1 – 1ª partição do HD Master da 1ª IDE
hdc2 – 2ª partição do HD Master da 2ª IDE
sda1 – 1ª partição do 1º disco SCSI
sdb3 – 3ª partição do 2º disco SCSI

? Há uma árvore única para todos os discos --> /


(dispositivo raiz = root device)

? Para que um disco possa ser usado é necessário


montá-lo na árvore pré-montada pelo S.O. Esta
árvore é automaticamente montada no boot do sistema.
? Montar um dispositivo significa torná-lo acessível a
partir de um determinado ponto na árvore.
Geralmente, estes pontos de montagem são criados no
diretório /mnt
? Ao montar um dispositivo em um diretório, o contéudo
daquele torna-se inacessível.
? A vantagem desta organização em uma árvore única,
sem menção à partições físicas ou discos, é que o S.O.
desconhece a localização física dos arquivos, ou
seja, em qual disco estão gravados.
? Uma característica interessante é a Montagem Remota,
que consiste em montar na árvore de uma máquina
partições lógicas de outras máquinas, de uma rede,
que parecerão indiferentes aos usuários em relação
às partições locais.
? Arquivo – conceito lógico: é uma seqüência de bytes.
? As chamadas de sistema básicas que lidam com
arquivos são: ler, escrever, criar, excluir, renomear e
abrir.
? Nos S.O.’s que usam o nome do arquivo como seu
identificador, não há a necessidade da existência das
chamadas ”Abrir” e “Fechar”. No caso do Linux,
onde o identificador do arquivo é um número, estas
chamadas são úteis, fazendo a associação com nome
e as devidas validações: se o arquivo existe, se o
usuário tem acesso, etc. A vantagem de se fazer a
validação em uma chamada à parte (“Abrir”) é que em
caso de múltiplos acessos fazemos uma única
validação, não havendo a necessidade desta
verificação a cada leitura/escrita.
? No Linux, a chamada “Fechar” não faz o
salvamento do contéudo em disco e, sim,
simplesmente libera o espaço em RAM no qual
o S.O. estava utilizando para fazer a associação
entre o número do arquivo e o seu nome
(metadata).
? Há duas formas de acesso à um arquivo:
Seqüencial - modo mais usual.
Aleatório (Randômico) – acesso aos
arquivos de dados através do uso de
arquivos de índices, que guardam uma
associação entre cada índice e um registro
de dados no arquivo de dados a ser
acessado.
Sistema de Arquivos
? É o módulo do sistema que implementa a política de
alocação dos arquivos no disco.

- Alocação contínua – arquivos devem ser alocados


continuamente. A estrutura de dados para localização
dos arquivos é bastante simples neste caso.

Problemas: mover arquivos de um lugar para outro


devido aos seu crescimento. Fragmentação do disco
decorrente desta movimentação.
? Alocação “Linkada”(encadeada) – ao final de cada
bloco do disco há a informação de controle gravada que
indica o próximo bloco do disco que faz parte daquele
arquivo.

Problema: ineficiente para o acesso randômico.

Exemplos: FAT (File Allocation Table) – há uma


tabela que associa os arquivos aos seus blocos iniciais.
Enquanto que a tabela FAT, carregada em memória, é
usada pelo S.O. para consultar o encadeamento dos
blocos do arquivo desejado. Não é mais necessário
acessar aos blocos anteriores ao bloco-alvo no disco.
Seu uso é vantajoso desde que seja uma estrutura
pequena, armazenada por completo na RAM.
Com o aumento da capacidade dos discos, a tabela
FAT aumenta de tamanho (há uma entrada na tabela
para cada bloco físico), sendo parte de sua estrutura
salva em disco, o que tornou seu uso mais ineficiente,
voltando a enfrentar os problemas do acesso randômico
com a alocação encadeada. A estrutura deve estar
toda em RAM para que o percorrimento encadeado
seja eficiente.

? Alocação por extensão (NTFS) – usada pelo Windows


NT. O S.O. aloca uma extensão para o arquivo
conforme a sua necessidade. Há uma estrutura de
controle por arquivo que contém as informações de
bloco inicial, quantidade de blocos na extensão e o
número do bloco do arquivo na extensão. Há
preocupação com a fragmentação do arquivo no disco, o
que irá gerar o crescimento da estrutura de controle.
? Alocação por Indexação (usada pelo Linux)
- Há uma estrutura de controle para cada arquivo
(INODE), a qual é carregada em memória à medida que
é feita chamada “Abrir”.

- O INODE é uma estrutura de tamanho fixo, que


contém as informações dos 10 primeiros blocos do
arquivo. Solução eficiente encontrada para trabalhar-
se com alocação indexada.

- Para arquivos pequenos, é fácil a a localização dos


blocos físicos. Para arquivos maiores (>10 blocos), são
utilizados os artifícios do Bloco de Indireção (contém o
endereço de um bloco que contém as demais entradas
do restante do arquivo) e do Bloco de Dupla Indireção
(aponta para os 256 blocos de indireção).
? O Linux identifica o INDOE de um arquivo através da
estrutura denominada “Diretório” (um outro arquivo)
que contém os nomes dos arquivos e as
associações com seus respectivos INODES. No
Windows não há INODES, logo a estrutura de diretório
contém o nome dos arquivos e todas as suas
informações de bloco inicial e dados de controle.

? O “Superbloco” é uma estrutura de controle única que


contém metadados sobre o sistema de arquivos, tais
como a lista de blocos livres.

? O Linux tem uma estrutura simples e eficiente para


tratamento de arquivos, visto que a maioria ocupa
menos que 10 blocos no disco. Além disso, também é
bastante eficiente no acesso à arquivos maiores, com o
uso do mecanismo de indireção.
? Sistemas de arquivos do Linux
? minix-FS
? ext
? ext2 ? padrão oficial atual
? ext3 ? = ext2 + “journaling” (snap shots do
sistema de arquivos para recuperação em
caso de falhas – “blocos abertos”)

? reiserFS ? tamanho do bloco é manipulável


Endereça arquivos > 2GB

? JFS ? padrão IBM

? XFS ? padrão da SGI. Tamanho de bloco


manipulável.
Endereça arquivos > 2GB
Interface Comum para Sistemas de
Arquivos - VFS

?O VFS (Virtual File System) é o


mecanismo que permite que chamadas
de sistemas genéricas, tais como open( )
e read( ),possam ser executadas
independentemente do sistema de
arquivos usado ou do meio físico.
?O VFS (também conhecido como Virtual
File Switch) é um sub-sistema do Kernel
que implementa as interfaces para que
os programas de usuários acessem ao
sistema de arquivos.

? Todos os sistemas de arquivos


existentes baseiam-se no VFS para co-
existir e interagir entre si.
Camada de Abstração para o Sistema
de Arquivos
?É uma implementação do Kernel sobre
sua interface para sistema de arquivos à
baixo nível.

? Permiteque o Linux suporte diferentes


sistemas de arquivos, apesar das suas
diferenças.
? Provê um modelo comum capaz de representar
todas as características genéricas de um
sistema de arquivos.

? Define um conjunto básico de conceitos de


interfaces e estruturas de dados que todos
os sistemas de arquivos suportam: arquivos,
diretórios, operações como criação e remoção.

? O código real do sistema de arquivos oculta os


detalhes da implementação.

? Para a camada VFS e para o resto do Kernel,


todos os sistemas de arquivos parecem
iguais.
? Os sistemas de arquivos são implementados de forma a
prover as abstrações, tanto de interface quanto de
estrutura de dados, que a camada VFS espera.

Exemplo
write (f, &buf, len);
? O VFS foi construído para trabalhar com sistemas de
arquivos do Linux, que implementam naturalmente
os conceitos já na organização das informações no
disco: informações de um arquivos são armazenados
em um bloco específico em separado (INODE),
diretórios são tratados como arquivos, informações
de controle são centralizadas no Superbloco.

? Sistemas de arquivos como FAT e NTFS devem prover


uma abstração destes conceitos, tal que sejam
suportados pelo Linux.
Objetos do VFS e suas Estruturas de Dados
? O VFS é orientado à objetos. Como o kernel é programado em C, as
estruturas de dados são simuladas nesta linguagem, contendo dados e
ponteiros para funções do sistema de arquivos que operam sobre os
dados.

? Os 4 objetos primários do VFS:

? Objeto Superbloco ? corresponde ao superbloco do sistema de


arquivos, gravado em um setor especial do disco.

? Objeto Inode ? representa um arquivo específico

? Objeto Dentry ? representa uma entrada de diretório (“parte do


path”)

? Objeto File ? representa a associação de um arquivo aberto à


um processo.
? Em cada um destes 4 objetos primários, há um objeto
específico para operações (“operations object”), o qual
descreve quais métodos o Kernel invoca sobre aqueles
objetos. Os objetos de operação são implementados
como uma estrutura de ponteiros para funções do
Kernel que operam sobre o objeto pai, e estão
identificados abaixo:
? super_operations – contém os métodos que o Kernel invoca
sobre um sistema de arquivos.
? inode_operations – contém os métodos que o Kernel invoca
sobre um arquivo.
? dentry_operations - contém os métodos que o Kernel invoca
sobre um diretório.
? file - contém os métodos que o Kernel invoca sobre um arquivo
“aberto”.
? Além dos 4 objetos primários, o VFS ainda
contém mais 5 objetos importantes a serem
citados:

? file_system_type – representa cada sistema de


arquivos existente, descrevendo suas funções.

? vfsmount– contém informações sobre o ponto de


montagem, como a sua localização.

? Objetos file_struct, fs_struct e namespace, que


descrevem o sistema de arquivos e os arquivos
associados à um processo.
O Objeto Superbloco
? Usado para armazenar informações sobre
um sistema de arquivos específico.
? É representado pela estrutura super_block,
definida em <linux/fs.h>, e que é instanciada
pela função alloc_super( ).
? Quando um sistema de arquivos é montado,
este invoca uma função que lê o Superbloco a
partir do disco e carrega as informações no
objeto Superbloco, em memória.
struct super_block {
struct list_head s_list; /* list of all superblocks */
dev_t s_dev; /* identifier */
unsigned long s_blocksize; /* block size in bytes */
unsigned long long s_maxbytes; /* max file size */
struct file_system_type s_type; /* filesystem type */
struct super_operations s_op; /* superblock methods */
struct dquot_operations *dq_op; /* quota methods */
struct quotactl_ops *s_qcop; /* quota control methods */
unsigned long s_flags; /* mount flags */
struct dentry *s_root; /* directory mount point */
struct list_head s_dirty; /* list of dirty inodes */
struct list_head s_io; /* list of writebacks */
struct hlist_head s_anon; /* anonymous dentries */
struct list_head s_files; /* list of assigned files */
struct block_device *s_bdev; /* associated block device */
struct list_head s_instances; /* instances of this fs */
char s_id[32]; /* text name */
void *s_fs_info; /* filesystem-specific info */
};
? O item mais importante do superbloco é a
estrutura s_op, que é a sua tabela de
operações.

? Todo item nesta estrutura é um ponteiro para


funções que operam sobre o objeto Superbloco.

? Para realizar uma operação sobre o seu


Superbloco, o sistema de arquivos segue os
ponteiros daquele até o método desejado.

sb -> s_op -> write_super (sb) ;


sb é um ponteiro para o Superbloco do sistema
de arquivos.
struct super_operations {
struct inode *(*alloc_inode) (struct super_block *sb);
void (*destroy_inode) (struct inode *);
void (*read_inode) (struct inode *);
void (*dirty_inode) (struct inode *);
void (*write_inode) (struct inode *, int); Todas estas funções
void (*put_inode) (struct inode *); são invocadas pelo
VFS, no contexto do
void (*drop_inode) (struct inode *);
processo!
void (*delete_inode) (struct inode *);
void (*put_super) (struct super_block *);
void (*write_super) (struct super_block *);
int (*sync_fs) (struct super_block *, int);
void (*write_super_lockfs) (struct super_block *);
void (*unlockfs) (struct super_block *);
int (*statfs) (struct super_block *, struct statfs *);
int (*remount_fs) (struct super_block *, int *, char *);
void (*clear_inode) (struct inode *);
void (*umount_begin) (struct super_block *);
int (*show_options) (struct seq_file *, struct vfsmount *);
};
O objeto Inode
? Representa toda a informação necessária ao Kernel para
manipulação de um arquivo ou diretório.

? Um inode representa cada arquivo no sistema de


arquivos. Porém o objeto só é instanciado em memória
no momento que o arquivo é “aberto” (acessado)

? A informação é obtida pela leitura do inode que está


gravado em disco.

? Se um sistema de arquivos não trabalhar com inodes,


deve obter esta informação do local onde estiver
armazenada. Geralmente, nestes casos, a informação é
gravado no próprio arquivo.

? O objeto inode é representado pela struct inode, definida


em <linux/fs.h>
struct inode {
struct hlist_node i_hash; /* hash list */
struct list_head i_list; /* list of inodes */
struct list_head i_dentry; /* list of dentries */
unsigned long i_ino; /* inode number */
umode_t i_mode; /* access permissions */
unsigned int i_nlink; /* number of hard links */
uid_t i_uid; /* user id of owner */
gid_t i_gid; /* group id of owner */
kdev_t i_rdev; /* real device node */
loff_t i_size; /* file size in bytes */
struct timespec i_atime; /* last access time */
struct timespec i_mtime; /* last modify time */
unsigned long i_blksize; /* block size in bytes */
unsigned long i_blocks; /* file size in blocks */
unsigned short i_bytes; /* bytes consumed */
struct inode_operations *i_op; /* inode ops table */
struct file_operations *i_fop; /* default inode ops */
struct super_block *i_sb; /* associated superblock */
struct address_space *i_mapping; /* associated mapping */
struct address_space i_data; /* mapping for device */
unsigned long i_state; /* state flags */
unsigned int i_flags; /* filesystem flags */
};
O item mais importante é o inode_operations, que
descreve as funções implementadas pelo sistema de
arquivos que podem ser invocadas pelo VFS para operar
sobre um inode.

Operações sobre inode são invocadas da forma abaixo,


onde i referencia um inode específico:

i -> i_op -> truncate (i)

No exemplo acima, esta função é chamada pelo VFS para


modificar o tamanho de um arquivo na proporção desejada.
struct inode_operations {
int (*create) (struct inode *, struct dentry *,int);
struct dentry * (*lookup) (struct inode *, struct dentry *);
int (*link) (struct dentry *, struct inode *, struct dentry *);
int (*unlink) (struct inode *, struct dentry *);
int (*symlink) (struct inode *, struct dentry *, const char *);
int (*mkdir) (struct inode *, struct dentry *, int);
int (*rmdir) (struct inode *, struct dentry *);
int (*mknod) (struct inode *, struct dentry *, int, dev_t);
int (*rename) (struct inode *, struct dentry *,
struct inode *, struct dentry *);
int (*readlink) (struct dentry *, char *, int);
int (*follow_link) (struct dentry *, struct nameidata *);
int (*put_link) (struct dentry *, struct nameidata *);
void (*truncate) (struct inode *);
int (*permission) (struct inode *, int);
int (*setattr) (struct dentry *, struct iattr *);
int (*getattr) (struct vfsmount *, struct dentry *, struct kstat *);
int (*setxattr) (struct dentry *, const char *,
const void *, size_t, int);
ssize_t (*getxattr) (struct dentry *, const char *, void *, size_t);
ssize_t (*listxattr) (struct dentry *, char *, size_t);
int (*removexattr) (struct dentry *, const char *);
};
O Objeto Dentry
? O VFS trata diretórios como arquivos.

? Exemplo: /bin/vi
bin e vi são arquivos, ambos representados pelo
objeto inode.

? Para facilitar a realização de operações específicas


sobre diretórios, o VFS usa o conceito de “entrada de
diretório” (dentry).

? O dentry é um componente específico do path. No


exemplo, /, bin e vi são objetos dentry. O VFS instancia
estes objetos “on the fly”, quando há anecessidade de
realizar operações sobre diretórios. Os objetos dentry
podem portanto ser diretórios, arquivos ou até pontos de
montagem.
? Ao contrário das demais estruturas vistas anteriormente,
o objeto dentry não corresponde a qualquer estrutura
de dados armazenada em disco. O VFS cria este
objeto “on the fly”, a partir da string de representação do
path.

? Há uma flag, “Dentry State”, que indica o status de um


objeto dentry:

? usado – corresponde a um inode válido e indica que há um ou


mais usuários para aquele objeto

? não usado – o VFS não está usando o objeto no momento,


apesar do inode correspondente ser válido.

? negativo – o objeto está associado a um inode inválido porque


o inode foi apagado ou porque o path sequer jamais exisitiu.
? Dentry Cache (dcache) – após o VFS resolver
todo o nome que compõem o path e atingir o
seu final, o Kernel armazena os objetos dentry
daquele path na Dentry Cache, a qual consiste
de 3 partes:

? Listade objetos dentry com o status “usado” para um


único inode, visto que este pode ter múltiplos links;

? Uma lista duplamente encadeada de objetos dentry


“menos recentemente usados” com status “não-
usado” ou “negativo”;

? Uma tabela hash para resolver rapidamente a


associção entre um dado caminho e o objeto dentry;
struct dentry {
atomic_t d_count; /* usage count */
unsigned long d_vfs_flags; /* dentry cache flags */
spinlock_t d_lock; /* per-dentry lock */
struct inode *d_inode; /* associated inode */
struct list_head d_lru; /* unused list */
struct list_head d_child; /* list of dentries within */
struct list_head d_subdirs; /* subdirectories */
struct list_head d_alias; /* list of alias inodes */
unsigned long d_time; /* revalidate time */
struct dentry_operations *d_op; /* dentry operations table */
struct super_block *d_sb; /* superblock of file */
unsigned int d_flags; /* dentry flags */
int d_mounted; /* is this a mount point? */
void *d_fsdata; /* filesystem-specific data */
struct rcu_head d_rcu; /* RCU locking */
struct dcookie_struct *d_cookie; /* cookie */
struct dentry *d_parent; /* dentry object of parent */
struct qstr d_name; /* dentry name */
struct hlist_node d_hash; /* list of hash table entries */
struct hlist_head *d_bucket; /* hash bucket */
unsigned char d_iname[DNAME_INLINE_LEN_MIN]; /* short name */
};
? A estrutura dentry_operations especifica os métodos
que o VFS invoca sobre as entradas de diretório em um
sistema de arquivos, sendo definida em
<linux/dcache.h>

struct dentry_operations {
int (*d_revalidate) (struct dentry *, int);
int (*d_hash) (struct dentry *, struct qstr *);
int (*d_compare) (struct dentry *, struct qstr *,
struct qstr *);
int (*d_delete) (struct dentry *);
void (*d_release) (struct dentry *);
void (*d_iput) (struct dentry *, struct inode *);
};
O Objeto File
? Assim como o objeto dentry, o objeto file não corresponde
realmente a um dado salvo em disco.
? É usado para representar um arquivo que foi aberto por um
processo, fazendo parte da representação daquele arquivo
carregada em memória.
? Representa a visão de um processo sobre o arquivo aberto.
Como um arquivo pode ser manipulado por vários processos, ao
mesmo tempo, é natural haver vários objetos file associados a
um único arquivo.
? O objeto file possui um ponteiro (f_dentry) para um objeto
dentry, o qual por sua vez possui um ponteiro para um objeto
inode, que representa na realidade o arquivo que fôra aberto.
Obviamente, os objetos dentry e inode são únicos para um
arquivo.

? É representado pela struct file, definida em <linux/fs.h>


struct file {
struct list_head f_list; /* list of file objects */
struct dentry *f_dentry; /* associated dentry object */
struct vfsmount *f_vfsmnt; /* associated mounted fs */
struct file_operations *f_op; /* file operations table */
atomic_t f_count; /* file object's usage count */
unsigned int f_flags; /* flags specified on open */
mode_t f_mode; /* file access mode */
loff_t f_pos; /* file offset (file pointer) */
struct fown_struct f_owner; /* owner data for signals */
unsigned int f_uid; /* user's UID */
unsigned int f_gid; /* user's GID */
int f_error; /* error code */
struct file_ra_state f_ra; /* read-ahead state */
unsigned long f_version; /* version number */
void *f_security; /* security module */
void *private_data; /* tty driver hook */
struct list_head f_ep_links; /* list of eventpoll links */
spinlock_t f_ep_lock; /* eventpoll lock */
struct address_space *f_mapping; /* page cache mapping */
};
? Asoperações associadas à struct file são
as familiares chamadas de sistemas que
formam a base das chamadas padrão do
Linux.

? Os sistemas de arquivos não são


obrigados a implementar todos estes
métodos, bastando configurá-los para
NULL quando estes não forem
interessantes.
struct file_operations {
struct module *owner;
loff_t (*llseek) (struct file *, loff_t, int);
ssize_t (*read) (struct file *, char *, size_t, loff_t *);
ssize_t (*aio_read) (struct kiocb *, char *, size_t, loff_t);
ssize_t (*write) (struct file *, const char *, size_t, loff_t *);
ssize_t (*aio_write) (struct kiocb *, const char *, size_t, loff_t);
int (*readdir) (struct file *, void *, filldir_t);
unsigned int (*poll) (struct file *, struct poll_table_struct *);
int (*ioctl) (struct inode *, struct file *, unsigned int, unsigned long);
int (*mmap) (struct file *, struct vm_area_struct *);
int (*open) (struct inode *, struct file *);
int (*flush) (struct file *);
int (*release) (struct inode *, struct file *);
int (*fsync) (struct file *, struct dentry *, int);
int (*aio_fsync) (struct kiocb *, int);
int (*fasync) (int, struct file *, int);
int (*lock) (struct file *, int, struct file_lock *);
ssize_t (*readv) (struct file *, const struct iovec *,
unsigned long, loff_t *);
ssize_t (*writev) (struct file *, const struct iovec *,
unsigned long, loff_t *);
ssize_t (*sendfile) (struct file *, loff_t *, size_t,
read_actor_t, void *);
ssize_t (*sendpage) (struct file *, struct page *, int,
size_t, loff_t *, int);
unsigned long (*get_unmapped_area) (struct file *, unsigned long,
unsigned long, unsigned long,
unsigned long);
int (*check_flags) (int flags);
int (*dir_notify) (struct file *filp, unsigned long arg);
int (*flock) (struct file *filp, int cmd, struct file_lock *fl);
};
Estruturas de dados associadas aos File Systems
? Além dos objetos primários apresentados, o Kernel usa
mais algumas estruturas para a manipulação de dados
relacionados aos sistemas de arquivos.

? File_system_type – objeto usado para descrever uma variante


específica de um sistema de arquivos (ext3 ou XFS). Há apenas
uma estrutura destas para cada sistema de arquivos,
independentemente de quantas instâncias daquele estão
montadas no sistema.

? Vfsmount – objeto criado no momento em que o sistema de


arquivos é montado. É usado para representar uma instância
montada, específica, de um sistema de arquivos. Esta estrutura
está definida em <linux/mount.h>
Estruturas de dados associadas a um Processo
? Cada processo no sistema possui sua própria lista de
arquivos acessados, o sistema de arquivos raiz, o diretório
corrente de trabalho, etc. Há 3 estruturas que interligam a
camada VFS aos processos:
? Files_struct – estrutura apontada na entrada “files” no descritor do
processo. Contém uma variável (array “fd”) que aponta para a lista de
arquivos abertos por aquele processo. Este array tem 32 entradas,
mas outro array pode ser alocado pelo Kernel, em tempo de execução,
caso o processo necessite acessar mais arquivos.

? Fs_struct - estrutura apontada no campo “fs” no descritor do processo,


que contém informações do sistema de arquivos relacionadas ao
processo, tais como o diretório corrente de trabalho e o diretório raiz do
processo.

? Namespace - estrutura apontada no campo “namespace” no descritor


do processo, que possibilita que cada processo tenha uma visão única
do sistema de arquivos montado. À cada processo é dada uma cópia
do namespace (filesystem hierarchy).
Conclusão
? O Linux suporta uma grande variedade de sistemas de
arquivos (cerca de 50 no Kernel oficial);

? A camada VFS provê a estes sistemas de arquivos um


framework para a sua implementação e uma interface
para que trabalhem com chamadas de sistema padrão
do Linux;

? A camada VFS permite a implementação transparente


de novos sistemas de arquivos para o Linux, além de
permitir que estes interoperem através das chamadas
de sistema padrão.
OBRIGADO !!!

andrey@ufrj.br
acoppie@centroin.com.br

Você também pode gostar