Memória VirtualTopSincronização em MultiprocessadoresSistemas de Arquivos

Sistemas de Arquivos

Ficheiros em Unix

Noções fundamentais:

Organização de arquivos

Arquivos contém dados:

Directório

Atributos de Ficheiros

Descriptores de ficheiros

Descriptores vs. Arquivos

I/O em Unix

Acesso pode ser sequencial ou "random":

Mais I/O

Sistemas de Arquivos

Ficheiros Especiais

fstat() permite verificar o tipo de um ficheiro:

Múltiplos Sistemas de Ficheiros

Torna-se necessário suportar vários sistemas de ficheiros (s5fs, ufs, fat, NFS, ...).

Ideia:

Nó-v em Solaris

Nó-v representa um arquivo aberto:

Vfs em Solaris

Vfs representa um sistema de arquivos aberto:

Implementação de Nós-V: objectivos

Ideia é poder usar a interface em sistemas de arquivos muito diferentes:

Relação entre nós-v e ficheiros abertos

Processo pode aceder um nó-v ou via:

  1. via file descriptor;
  2. via lookup do nome.

Alocação de FD:

Nó-V em Detalhe

Cada nó-v tem as seguintes estruturas:

Objecto Vfs

Campos:

Campos Dependentes da Implementação

vop_open() vop_close()
vop_read() vop_write() vop_ioctl()
vop_getattr() vop_setattr() vop_access()
vop_lookup() vop_create() vop_remove()
vop_link() vop_rename()
vop_mkdir() vop_rmdir() vop_readdir()
vop_symlink() vop_readlink() vop_inactive()
vop_rwlock() vop_rwunlock() vop_realvp()
vop_getpage() vop_putpage()
vop_map() vop_poll()

Operações da interface no vfs:
vfs_mount() vfs_umount()
vfs_root() vfs_statvfs() vfs_sync()

Montagem de FS

SVR4 usa vfssw[], um switch global com as características de cada FS:

  1. mount() primeiro obtem o vnode do ponto de montagem com lookuppn(): nó-v tem que ser directório e nenhum outro FS pode estar montado nele;
  2. Procura entrada em vfssw[], dado tipo de FS;
  3. Chama vsw_init(), específico ao FS;
  4. Aloca novo vfs;
  5. Inclui vfs na lista comandada por rootvfs.
  6. vfs_op para vfsops de vfssw[];
  7. Instala vfs_vnodecovered para nó-v do mount point;
  8. vfs_vfsmountedwhere do nó-v aponta para vfs;
  9. chama VFS_MOUNT();

VFS_MOUNT()

Cada FS tem que implementar VFS_MOUNT() à sua maneira:

  1. Verificar permissões;
  2. Alocar e inicializar objeto privado;
  3. colocar um ptr. para ele em vfs -> vfs_data;
  4. aceder ao directório raiz do FS e inicializar seu nó-v.

FS locais usam superbloco, FS distribuidos chamam o servidor.

Travessia do nome

lookuppn() recebe um nome e retorna um ptr para nó-v:

  1. se não for último componente, usa v_type para saber se nó-v inicial é directório.
  2. Se componente é .. e cwd raíz, apanhe o componente seguinte.
  3. se componente é .. e cwd VROOT, acesse v_vfsp -> vfs_vnodecovered.
  4. Chame VOP_LOOKUP() no directório corrente: retorna ptr. para nó-v do arquivo e obtém um hold.
  5. se componente não fôr encontrado:
    1. se fôr último, retorne sucesso, passando ptr para o pai e mantendo hold;
    2. senão ENOENT.
  6. se v_vfsmountedhere != NULL encontre o vfs correspondente e chame vfs_root() para encontrar o nó-v raiz.
  7. Se v_type == VLNK, traduza com VOP_SYMLINK(), junte a tradução e reinicialize (se caminho absoluto, comece da raíz):
  8. Liberta directório (segurado ou por VOP_LOOKUP ou por inicialização.
  9. Volte ao principio e procure novo componente.
  10. Se procurou todos, mantenha o hold e devolva um ptr para o nó-v.

Cache de Acesso a Directórios

VOP_LOOKUP

erro = VOP_LOOKUP(vp, compname, &tvp, ...,

tvp tem o resultado:

open()

  1. aloca um fd.
  2. aloca um objecto ficheiro.
  3. chama lookuppn() para encontrar o nó-v.
  4. Chama VOP_ACCESS para verificar permissões.
  5. Verifica se operação é ilegal (abrir um directório ou executável activo para escrita).
  6. Se O_CREAT e ficheiro não existe, chama VOP_CREATE() no directório pai, senão ENOENT.
  7. Chama VOP_OPEN, que geralmente não faz nada.
  8. Se O_TRUNC, chama VOP_SETATTR para colocar tamanho a 0.
  9. Inicializa o objecto ficheiro.
  10. Retorna o índice do fd.

Análise

SVR4 e Solaris:

VFS em 4.4BSD

Optimizações:

VFS em OSF/1

VFS em Linux

Superblocos

Operações

inode_operations

create() lookup()
link() unlink() symlink()
mkdir() rmdir() mknod()
rename() readlink()
readpage() writepage() bmap()
truncate() permission() smap()
updatepage() revalidate()

file_operations

llseek() read() write()
readdir() poll() ioctl()
mmap() open() release()
fsync() fasync() check_media_change()
revalidate() lock()

FS e dentries

Manipulação de dentries:

dentry_operations

Partições s5fs

Campos do nó-i

O Superbloco

Inclui:

Nós-i no Kernel

Nó-i em memória inclui:

Lookup

  1. lookuppn() usa VOP_LOOKUP() para encontrar componente que chama s5lookup().
  2. s5lookup() primeiro procura na cache;
  3. Senão, anda no directório;
  4. se encontrar obtém o número do nó-i e chama iget() para o encontrar;
  5. se nó-i na tabela de hash, tudo bem; senão
  6. aloca nó-i e inicializa lendo do disco;
  7. aloca e inicializa nó-v;
  8. retorna um ptr. para nó para lookuppn().
Apenas iget() aloca e inicializa nós-i.

File I/O

Recebemos FD, user address e count:

write() é semelhante mas:

Alocação de Nós-I

Análise de s5fs

Introdução a FFS

Mais FFS

FFS: Análise

EXT2

ext2fs:

Buffer Cache

Originalmente usada para evitar acesso a disco:

Funcionamento da Buffer Cache

Buffer Header

Consistência

Problema se houver crash:

Problemas com Sistemas Tradicionais

Desempenho:
layout de FFS ou EXT2 não usa banda total do disco:
Recuperação de crash:
não é garantida;
Segurança:
Permissões Unix (ACL seria melhor?)
Tamanho:
Arquivos têm que caber em partição, existem limites arbitrários.

Journaling

Escrever tudo num arquivo append-only, o log:

Log-Structured

Estrutura de BSD LOG-FS

LFS: Escrita

LFS: Análise

Logging de Meta-Dados


vitor@cos.ufrj.br

Memória VirtualTopSincronização em MultiprocessadoresSistemas de Arquivos