Buscar

Sistema de Arquivos

Prévia do material em texto

Sistemas de Arquivos 
 
Podemos pensar num disco como uma sequência linear de blocos fixos que possui 
operações de ler e escrever em um bloco k. 
Arquivos são unidades lógicas de informação criadas por processos. Um disco pode conter 
milhões destes de forma independente e é válido associar como se cada arquivo fosse um 
endereço no disco. 
Processos podem ler arquivos existentes ou criar novos. Informações inseridas nos 
arquivos devem ser ​persistidas e um arquivo só deve ser excluído se o proprietário dele 
explicitamente fizer. 
 
1. Arquivos 
 
Nomeação de Arquivos​: quando um processo cria um arquivo, ele lhe dá um nome. O 
arquivo ficará disponível mesmo se o processo for encerrado e pode ser acessado por 
outros arquivos através do seu nome. Regras de nomeação são específicas de cada 
sistema de arquivo, mas de maneira geral, uma sequência de caracteres e até mesmo 
símbolos especiais são válidos. Alguns sistemas de arquivos distinguem letras minúsculas 
de maiúsculas (o UNIX pertence ao primeiro, o MS-DOS ao segundo). Os sistemas de 
arquivos permitem nomes segmentados, como a ​extensão ​de um arquivo, que vem depois 
de um ponto (main.java) e essa extensão diz algo sobre o arquivo. O UNIX permite várias 
extensões (index.html.zip significa que o arquivo é uma página html compactada). 
Extensões são convenções, o SO não se importa com elas (mas um programa pode exigir). 
 
Estrutura de Arquivos​: ​o SO trata o arquivo como uma sequência de bytes. Qualquer 
abstração maior é feita em alto nível. Eles podem ser organizados como uma sequência de 
bytes, como uma sequência de registros (comum nos sistemas de cartão dos anos 80) ou 
como uma árvore. 
 
Tipos de Arquivos​: todos os SOs tem arquivos regulares e diretórios. ​Arquivos regulares 
são aqueles que contém informação do usuário. ​Diretórios ​são arquivos do sistema para 
manter a estrutura do sistema de arquivos. Arquivos especiais de caracteres (tipo ​c​, por ex 
/dev/tty​) são referentes a arquivos para E/S, e arquivos especiais de blocos (tipo ​b​, por 
ex ​/dev/sda​) são usados para modelar discos. Arquivos geralmente são escritos em 
ASCII. Isso facilita pois o arquivo pode ser lido como ele foi escrito em qualquer editor e 
programas que usam como entrada e saída podem ter uma interface mais fácil. Arquivos 
binários são mais difíceis e geralmente possuem uma estrutura que apenas o programa que 
lida com eles conhece. 
 
Acesso aos Arquivos: ​os primeiros SOs usavam um sistema de acesso sequencial, onde 
era possível apenas ler um arquivo do começo, não sendo possível pular ou ler fora de 
ordem (fazia sentido por causa das fitas magnéticas). Já nos discos, os arquivos são 
acessados de maneira aleatória e podem ser especificados de qual posição do arquivo 
 
 
devem abrir. Ou você usa uma função read passando a posição desejada ou uma o seek, 
que recebe a posição e vai para esta posição no arquivo atual. 
 
Atributos de Arquivos: ​nome​, ​data (criação, modificação)​. Proteção, senha, criador e 
proprietário são atributos referentes a segurança do arquivo. Há flags que possuem uso 
específico (como bit de arquivo oculto). 
 
Operações com Arquivos​: 
- create 
- delete 
- open 
- close 
- read: usado para ler, geralmente os bytes vem da posição atual 
- write: geralmente feito na posição atual, que é o final. Se este for o caso, o arquivo 
cresce, caso contrário, os bytes posteriores são sobrescritos e perdidos para sempre 
- append: tipo um write mas que só escreve no final 
- seek: para arquivos de acesso aleatório, reposiciona o cursor do arquivo para um 
local específico dele 
- get attributes: para os processos que precisam dos metadados dos arquivos 
- set attributes 
- rename 
 
2. ​Diretórios 
Usados para controlar os arquivos (eles em si são arquivos também). 
 
Sistemas de diretório em nível único​: basicamente um único diretório que contém todos 
os arquivos. Usado em sistemas antigos e em sistemas embarcados atuais (pequenos, 
simples). Era rápido para procurar arquivos por que só tinha um lugar para buscar mesmo. 
 
Sistemas de diretórios hierárquicos​: a idéia é que os arquivos sejam organizados em 
uma árvore de diretórios, onde cada subárvore contém arquivos que fazem sentidos 
estarem alí. 
 
Nomes de caminhos​: há duas maneiras. Na primeira, o arquivo recebe um nome de 
caminho absoluto, que é o caminho da raiz até ele (/usr/antunes/documents/oi.txt). Sempre 
começam com o diretório raiz e são únicos. A segunda maneira é chamada de nome de 
caminho relativo. Funciona quando um usuário diz que um diretório é o diretório atual de 
trabalho dele, então o nome dos arquivos não começam da raiz mas sim desse diretório. 
Cada processo tem seu próprio diretório de trabalho. 
 
Operações com diretórios​: create (cria vazio, exceto pelo "." e ".."), delete (apenas um 
diretório vazio pode ser removido), opendir (para ler um diretório, primeiro abre), closedir, 
readdir, rename, link (permite que um arquivo esteja em mais de um diretório), unlink. 
 
 
 
3. ​Implementação do Sistema de Arquivos 
Esquema do Sistema de Arquivos​: sistemas de arquivos podem ser armazenados em 
discos, que podem conter várias partições. No setor inicial do disco, há a MBR. Ela tem os 
endereços de início e fim de cada partição. O primeiro bloco do sistema de arquivos é o 
superbloco​. Ele contém todos os parâmetros-chave para o sistema de arquivos e é 
carregado na memória toda vez que o sistema operacional é carregado. Informações típicas 
no superbloco incluem um número mágico para identificar o tipo de sistema de arquivos, 
número de blocos e outras informações administrativas. O próximo bloco contém 
informações a respeito de blocos disponíveis, que pode ser seguido pelos i-nodes e depois 
o diretório raiz. Por fim, o restante do disco contém os demais arquivos e diretórios. 
 
Implementando arquivos​: a ​alocação contígua ​é o esquema mais simples de armazenar 
os arquivos, fazendo através de uma execução contígua de blocos de disco. Ela sempre 
começa a armazenar um arquivo no começo do bloco. Isso, porém, pode desperdiçar 
espaço se o arquivo não ocupar um bloco inteiro (isso leva a fragmentação). Suas 
vantagens são a facilidade de implementação (para buscar os blocos de um arquivo basta 
saber onde ele começa e somar da parte que você quer), além de ser muito rápido visto que 
os blocos estão em sequência, então a operação de leitura será realizada sem necessidade 
de novas rotações. A ​alocação por lista encadeada ​é outro esquema, onde os blocos são 
organizados como uma lista encadeada onde a primeira palavra do bloco é um apontador 
para o próximo. Essa técnica basicamente anula o problema de fragmentação, mas torna as 
consultas a endereços aleatórios extremamente custosa. Além disso, a quantidade de 
dados por bloco não é mais uma potência de dois (já que o bloco precisa guardar a 
referência do próximo), o que atrapalha o salvamento de dados pois os programas são 
preparados para lidar com dados dessa ordem. A ​lista encadeada usando uma tabela na 
memória​ ajuda a resolver os dois grandes problemas do método anterior. Agora, os blocos 
ficam com seu espaço inteiro para dados e a lista de encadeada de endereços de cada 
arquivo ficam guardados em uma tabela na memória. A busca não é tão lenta já que os 
dados estão em memória. O problema é que, para discos grandes, a tabela fica gigante. Era 
comum usar isso em sistemas antigos que tinhampouco armazenamento. Os ​i-nodes ​são 
estruturas de dados que resolvem esses problemas. Eles contém uma lista de atributos do 
arquivo, bem como os endereços do disco e precisam estar na memória apenas quando 
esses arquivos estão abertos. Assim, é escalável para grandes volumes. 
 
Implementando diretórios​: a principal função do sistema de diretórios é mapear o nome 
do arquivo ao endereço do bloco do disco. As informações sobre os arquivos do diretório 
podem ser colocadas na entrada do diretório ou em estruturas como o i-node. Porém, essas 
estruturas de tamanho variável podem gerar fragmentação de disco. Uma opção é tratar os 
arquivos com um cabeçalho de informações fixas no início do bloco e as informações 
variáveis, como o nome do arquivo, numa heap no final do bloco. Isso permite que, quando 
um arquivo seja removido, outro possa ser inserido sem problema. Buscas em diretórios 
com muitos arquivos podem se tornar lentas. Uma solução é usar uma função de 
espalhamento, onde dado o nome do arquivo, essa função irá calcular uma posição de onde 
o arquivo está. A ideia é semelhante a uma hashtable (apenas semelhante) e deve ser 
usada apenas quando sabe-se que o sistema conterá diretórios com muitos arquivos. 
 
 
 
Arquivos compartilhados​: um problema referente a arquivos compartilhados é como os 
blocos serão disponibilizados para os diferentes usuários. Se o sistema realizar uma cópia 
da informação dos blocos, a edição de um usuário não será refletido para outro e assim não 
há compartilhamento. Uma solução seria o uso de estruturas como os i-nodes, onde os 
usuários receberiam os i-nodes e as modificações seriam acrescentadas neles. Porém, isso 
pode levar a problemas caso o dono do arquivo o exclua e alguém esteja editando: o 
arquivo deve ser excluído e o usuário fica com um i-node inválido? Outra solução é o uso de 
ligações simbólicas, mas isso também gera complexidade para manter todos os links. 
 
Sistemas de arquivos estruturados em diário (logs): ​muitas operações simples em um 
disco apresentam um custo alto. Sempre que um arquivo novo é criado, vários blocos 
precisam ser escritos e se isso for feito aos poucos, a taxa de utilização do disco é baixa. 
Assim, a ideia desse sistema de arquivos é juntar as informações de escrita em memória e 
quando tiver um tamanho considerável, as guarda em disco. Esse salvamento é na forma 
de um diário, onde no início de cada diário há informações sobre o que foi escrito ali. Os 
i-nodes ainda existem e eles são indexados através de um mapa. Há uma rotina, chamada 
de ​limpador​, que é executada circularmente no diário para encontrar i-nodes e informações 
inválidas, a fim de excluí-las. 
 
Sistemas de arquivos journaling​: a ideia é que o sistema mantenha um diário das 
atividades do disco antes mesmo delas acontecerem. Assim, em caso de falha, o sistema 
pode verificar no diário o que estava para acontecer e concluir a ação. Quando uma 
modificação há de ser feita no disco, o sistema primeiro registra e persiste todas as ações a 
serem feitas no diário e só depois começa a executar as operações de fato. Quando as 
operações são finalizadas com sucesso, a entrada no diário é apagada. Em caso de erro, o 
sistema verifica no diário e reexecuta as operações. Para isso, as operações devem ser 
idempotentes. 
 
3. Implementação do Sistemas de Arquivos do Linux 
Para abstrair o sistema de arquivos das chamadas do sistema, o linux possui um sistema de 
arquivos virtual. A VFS oferece uma interface para operações simples. O ext2 é um dos 
sistemas de arquivos mais populares do Linux. Ele organiza o disco iniciando por um bloco 
com informações sobre a inicialização do sistema. Depois, vem o superbloco, que contém 
informações sobre o sistema de arquivos, quantidade de i-nodes, alguns apontadores para 
blocos livres. A próxima parte são os i-nodes, que, como vimos, descrevem os arquivos. A 
próxima parte são os blocos de arquivos em si. Arquivos não são necessariamente escritos 
em série se eles ocuparem mais de um bloco. 
 
4. Gerenciamento e Otimização de Sistemas de Arquivos 
Gerenciamento do espaço em disco​: blocos tem tamanho fixo e os arquivos não são 
guardados em blocos consecutivos. 
 
 
 
Tamanho do bloco​: blocos muito pequenos evitam desperdício de espaço, mas nem todos 
os arquivos cabem em um só bloco e ler muitos blocos é um custo maior. Blocos grandes 
demais podem gerar fragmentação. 
 
Monitoramento dos blocos livres​: uma opção é usar uma lista encadeada de blocos livres 
ou um mapa de bit. 
 
Backups​: importante saber quais arquivos copiar (nunca fazer cópia de diretórios de 
dispositivos removíveis, por exemplo). Além disso, é interessante uma estrutura que permita 
snapshot do sistema de arquivos pois o backup demora muito a ser feito e esse snapshot 
auxilia na cópia. Cópias incrementais ajudam a manter a velocidade, visto que depois que 
há um backup de tudo, basta atualizar os arquivos que foram modificados. Há também o 
problema de blocos defeituosos, que, obviamente, tornam a cópia dele impossível. 
 
Consistência​:

Continue navegando