Sistemas de Arquivos e Entrada/Saída
Professor: Gabriel Soares Baptista
Hoje veremos como o SO transforma blocos crus e dispositivos lentos em uma interface simples.
Interface vista pelo programa:
open, close, read, write, seekProblema central: como armazenar informações de forma persistente, encontrável, compartilhável e eficiente, mesmo quando o hardware só entende blocos, controladores, interrupções e erros?
Na aula anterior: memória virtual cria a ilusão de espaço grande, contínuo e privado.
Agora o problema muda:
Base: Tanenbaum, capítulo 4, seções 4.1 a 4.4, e capítulo 5, seções 5.1 a 5.3.
Quando você salva relatorio.txt, o que o sistema precisa lembrar?
O nome sozinho não basta. O sistema de arquivos precisa manter dados e metadados consistentes.
Um arquivo é uma unidade lógica de informação criada por processos e gerenciada pelo SO.
Ele evita que o programa lide diretamente com:
Para o programador: nome, conteúdo e operações.
Para o SO: metadados, blocos, permissões e relação com diretórios.
| Necessidade | Por que importa |
|---|---|
| Armazenar muita informação | O espaço de endereçamento do processo não é o lugar certo para todos os dados |
| Sobreviver ao processo | O arquivo continua existindo depois que o processo termina |
| Permitir compartilhamento | Vários processos podem acessar a mesma informação por uma interface comum |
Arquivos resolvem o que a memória principal não resolve sozinha: persistência, escala e compartilhamento.
Ao criar um arquivo, o processo dá um nome a ele.
Regras variam entre sistemas:
.c, .txt, .jpg, .pdf indicam convençõesEm UNIX, extensão costuma ser convenção.
Em ambientes gráficos, extensão costuma ajudar a escolher o programa que abrirá o arquivo.
Um nome como foto.jpg sugere uma imagem JPEG.
Mas o sistema de arquivos pode não verificar isso.
O conteúdo real depende de:
Conclusão: extensão é pista, não prova.
Tanenbaum apresenta três formas clássicas de enxergar arquivos.

| Estrutura | Ideia | Onde aparece |
|---|---|---|
| Sequência de bytes | SO não interpreta o conteúdo | UNIX, Linux, Windows modernos |
| Sequência de registros | Arquivo lido e escrito em registros | Sistemas antigos de grande porte |
| Árvore de registros | Registros buscados por chave | Processamento comercial |
Sequência de bytes:
Sequência de registros:
Árvore de registros:
Sequência de bytes é a opção mais flexível.
Vantagem:
Desvantagem:
| Tipo | Como funciona | Exemplo |
|---|---|---|
| Sequencial | Lê ou escreve na ordem atual | Processar um log linha por linha |
| Aleatório | Move a posição atual e acessa dali | Buscar registro de cliente em uma base |
Primeiros sistemas: acesso sequencial combinava com fitas magnéticas.
Com discos: acesso aleatório se tornou viável.
Em UNIX e Windows, seek altera a posição atual do arquivo.
Arquivos têm conteúdo e metadados.
| Atributo | O que representa |
|---|---|
| Proteção | Quem pode ler, escrever ou executar |
| Proprietário | Usuário responsável |
| Tamanho | Quantidade atual de bytes |
| Tempos | Criação, último acesso e última modificação |
| Flags | Somente leitura, oculto, temporário, sistema |
Operações comuns: create, delete, open, close, read, write, append, seek, get attributes, set attributes, rename.
open Faz?Abrir um arquivo não significa ler todos os dados imediatamente.
open prepara o sistema para acessos futuros:
Depois disso, read e write usam esse descritor.
abrir entrada.txt para leitura
criar saida.txt para escrita
enquanto houver bytes na entrada:
ler um bloco da entrada
escrever esse bloco na saída
fechar os dois arquivos
O programa não precisa saber onde estão os blocos físicos de entrada.txt.
O SO converte pedidos de bytes em:
Um sistema com milhares de arquivos não pode ser uma única lista plana.
Diretórios:
A informação associada pode ser:
Sistemas modernos usam diretórios em árvore.
Isso permite organização por usuário, aplicação ou projeto.

| Tipo | Ideia | Exemplo |
|---|---|---|
| Absoluto | Começa na raiz | /usr/ast/caixapostal |
| Relativo | Começa no diretório atual | caixapostal |
Diretório de trabalho: referência usada por caminhos relativos.
Se o diretório atual é /usr/ast, então caixapostal e /usr/ast/caixapostal apontam para o mesmo arquivo.
Nomes especiais:
. é o diretório atual.. é o diretório pai| Operação | Função |
|---|---|
create | Cria diretório vazio |
delete | Remove diretório, geralmente se estiver vazio |
opendir | Abre diretório para leitura |
readdir | Retorna próxima entrada |
closedir | Fecha diretório |
rename | Renomeia uma entrada |
link | Faz um arquivo aparecer por outro nome |
unlink | Remove uma entrada de diretório |
Em UNIX, remover arquivo é remover uma ligação nome → arquivo. Por isso: unlink.
| Tipo | Como funciona | Consequência |
|---|---|---|
| Link rígido | Duas entradas apontam para a mesma estrutura interna | Arquivo só desaparece quando o último nome é removido |
| Link simbólico | Pequeno arquivo guarda caminho para outro arquivo | Pode atravessar sistemas de arquivos, mas pode quebrar |
Links rígidos tornam o sistema mais parecido com um grafo acíclico do que com uma árvore pura.
Link simbólico quebrado não é arquivo corrompido: o link existe, mas a resolução do caminho falha.
Agora olhamos o sistema de arquivos pelo lado de quem implementa.
Disco simplificado: sequência de blocos.
Perguntas que o sistema precisa responder:

| Estrutura | Papel |
|---|---|
| MBR | Código inicial e tabela de partições |
| Bloco de inicialização | Carrega o SO daquela partição, quando aplicável |
| Superbloco | Parâmetros fundamentais do sistema de arquivos |
| Espaço livre | Informa quais blocos podem ser usados |
| I-nodes | Metadados e endereços dos blocos |
| Diretório-raiz | Ponto inicial da árvore |
| Dados | Arquivos e diretórios |
O superbloco é especialmente importante.
Ele guarda parâmetros essenciais para interpretar a partição.
Se for perdido ou corrompido, o sistema pode não saber:
Sem superbloco confiável, o restante do disco pode virar bytes sem contexto.
Cada arquivo ocupa uma sequência contínua de blocos no disco.

Vantagens:
Problemas:
Lista encadeada: cada bloco aponta para o próximo.
Vantagem:
Problema:
FAT melhora isso:
Em sistemas com i-nodes, cada arquivo possui sua própria estrutura de metadados.

O i-node guarda:
Arquivos pequenos são baratos; arquivos grandes continuam possíveis.
Considere um arquivo nos blocos físicos $4$, $7$ e $12$.
Na FAT:
| Bloco | Próximo |
|---|---|
| $4$ | $7$ |
| $7$ | $12$ |
| $12$ | fim |
No i-node:
| Ponteiro do i-node | Bloco apontado |
|---|---|
| direto 1 | $4$ |
| direto 2 | $7$ |
| direto 3 | $12$ |
Diferença central: FAT é global e indexada por blocos; i-node é por arquivo.
FAT:
I-node:
Ambos aceitam arquivos espalhados. A diferença é onde fica o mapa dos blocos.
Diretório precisa mapear nomes para informação que localiza o arquivo.
| Estratégia | Como funciona |
|---|---|
| Atributos na entrada | Entrada guarda nome, atributos e endereços de disco |
| Entrada aponta para i-node | Entrada guarda nome e número do i-node; atributos ficam no i-node |
Nomes longos e variáveis criam desafios:
Arquivos são divididos em blocos de tamanho fixo.
| Bloco pequeno | Bloco grande |
|---|---|
| Desperdiça menos espaço no último bloco | Reduz quantidade de blocos por arquivo |
| Pode exigir mais buscas e metadados | Melhora leitura sequencial |
| Economiza espaço em arquivos pequenos | Pode desperdiçar espaço em arquivos pequenos |
Conflito clássico: espaço vs tempo.
O melhor tamanho depende da carga de trabalho: vídeos grandes e milhões de arquivos pequenos pedem decisões diferentes.
Para reutilizar espaço, o sistema precisa saber quais blocos estão livres.

| Técnica | Ideia | Vantagem | Custo |
|---|---|---|---|
| Lista encadeada | Blocos livres listados em estruturas encadeadas | Pode usar os próprios blocos livres | Dificulta encontrar blocos próximos |
| Mapa de bits | Um bit por bloco indica livre ou ocupado | Compacto e facilita achar sequências | Precisa ser mantido e consultado |
Em sistemas multiusuário, o SO pode impor cotas.
Cota limita:
Objetivo:
Sistemas de arquivos precisam ser rápidos e sobreviver a falhas.
Problema: operações simples exigem várias escritas reais.
Remover arquivo em sistema parecido com UNIX pode exigir:
Se o sistema cai no meio, estruturas podem discordar entre si.
Se cai depois de remover a entrada do diretório:
Se cai depois de liberar blocos, mas antes de remover a entrada:
Consistência exige coordenar várias estruturas.
Ferramentas como fsck examinam redundâncias do sistema de arquivos.

Podem encontrar:
Funciona, mas pode ser lento em discos grandes porque precisa varrer muitas estruturas.
Sistema com journaling registra no diário o que pretende fazer antes de modificar estruturas principais.
Exemplo: remover temp.log.
transação: remover temp.log
ação 1: remover entrada do diretório
ação 2: liberar i-node k
ação 3: marcar blocos b1, b2, b3 como livres
Depois que a entrada está segura no disco, o sistema executa as ações reais.
Após queda, a recuperação lê o journal e sabe o que completar ou verificar.
Operações registradas precisam ser idempotentes.
Idempotente: pode ser repetida sem mudar o resultado além da primeira execução.
Exemplo: marcar bloco $n$ como livre só é seguro se repetir isso não adicionar o mesmo bloco duas vezes a uma lista.
Journaling não é backup:
Tanenbaum também discute sistemas de arquivos estruturados em log.
Ideia:
Diferença para journaling:
| Técnica | Ideia principal |
|---|---|
| Sistema estruturado em log | Organizar o disco como grande log para melhorar escrita |
| Journaling | Registrar intenções para recuperar consistência após falha |
Disco é muito mais lento que memória.
Mesmo com alta taxa de transferência, há latência de busca, rotação, fila e controlador.

Cache de blocos:
Algoritmos como LRU podem decidir quais blocos remover.
Mas sistemas de arquivos têm preocupação extra: consistência.
Blocos críticos:
Se metadados sujos ficam só na cache e o sistema cai, o sistema de arquivos pode ficar inconsistente.
Política de cache não é apenas desempenho; também é risco.
| Estratégia | Ideia | Consequência |
|---|---|---|
| Escrita adiada | Junta alterações e grava depois | Melhora desempenho, aumenta risco de perda recente |
| Escrita direta | Grava blocos modificados imediatamente | Mais segurança, mais E/S |
sync periódico | Força blocos sujos para o disco em intervalos | Limita janela de perda |
| Journaling | Registra transações antes de aplicar mudanças | Recupera consistência mais rápido |
Não existe política grátis: reduzir risco costuma custar desempenho.
Leitura antecipada:
Localidade:
Desfragmentação:
Em SSDs:
Conclusão: otimizações pensadas para HDs nem sempre fazem sentido em SSDs.
O sistema de arquivos depende de E/S.
Para ler um bloco, ele conversa com camadas mais baixas que sabem lidar com:
Tanenbaum divide dispositivos em duas categorias principais.
| Tipo | Característica | Exemplos |
|---|---|---|
| Bloco | Blocos endereçáveis independentemente | Disco, SSD, Blu-ray, pendrive |
| Caractere | Fluxo de caracteres ou bytes | Teclado, impressora, mouse, serial |
Dispositivo possui parte física e parte eletrônica.
A parte eletrônica é o controlador.
O SO geralmente conversa com o controlador, não com cada detalhe físico.
Controlador expõe registradores para:
Exemplo: perguntar se o dispositivo está pronto ou mandar iniciar uma leitura.
Há duas formas clássicas de acessar registradores de dispositivos.
| Abordagem | Como funciona |
|---|---|
| Espaço de E/S separado | Instruções especiais acessam portas de E/S |
| E/S mapeada em memória | Registradores aparecem como endereços de memória |
Na E/S mapeada em memória, driver acessa registradores como posições especiais de memória.
Cuidado: registradores de dispositivo não devem ser tratados como memória comum em cache.
Cache poderia devolver valor antigo e esconder mudança real do dispositivo.
| Técnica | Quem faz o trabalho | Vantagem | Problema |
|---|---|---|---|
| E/S programada | CPU verifica e transfere dados | Simples | Pode desperdiçar CPU em espera ocupada |
| Interrupção | Dispositivo interrompe quando precisa de atenção | Libera CPU entre eventos | Muitas interrupções custam caro |
| DMA | Controlador transfere entre dispositivo e memória | Reduz cópias e interrupções | Exige hardware e coordenação |

No DMA, a CPU programa o controlador com:
Depois:
DMA é especialmente útil para transferências maiores.
Imagine imprimir uma sequência de caracteres.
| Método | O que acontece |
|---|---|
| E/S programada | CPU envia um caractere e fica perguntando se a impressora aceita o próximo |
| Interrupção | CPU envia um caractere e faz outra coisa; impressora interrompe quando pronta |
| DMA | CPU prepara um buffer; controlador transfere e interrompe apenas ao final |
Interrupção não é gratuita:
Se ocorrer a cada byte, pode ficar cara.
Cada camada esconde detalhes da camada inferior e oferece interface mais regular para a superior.

| Camada | Responsabilidade |
|---|---|
| Processo do usuário | Chama E/S, formata dados, usa bibliotecas e spooling |
| Software independente | Nomeia dispositivos, protege acesso, gerencia buffer |
| Driver | Traduz operações abstratas em comandos do controlador |
| Tratador de interrupção | Acorda driver ou processo quando operação termina |
| Hardware | Executa operação física |
Um programa que chama read não deveria saber se os dados vêm de:
Drivers contêm conhecimento específico do dispositivo:
Drivers podem ser carregados dinamicamente.
O restante do kernel não deve ser reescrito para cada dispositivo novo.
Software independente de dispositivo cuida de:
No UNIX, dispositivos aparecem como arquivos especiais em /dev.
Buffers suavizam diferenças de velocidade entre produtor e consumidor.
Spooling coloca trabalhos em fila para dispositivos dedicados, como impressoras.
Quando um processo executa read(fd, buffer, n):
fdAvaliação C3!