Reiser4 é um sistema de arquivos, uma versão específica do ReiserFS, sendo em 2007 a última versão disponível do poderoso Reiser.

Origem Em 2001 criado por Hans Reiser o sistema de arquivos Reiser4 teve sua primeira aparição e inicialmente mantido pela empresa (Namesys) para gerenciar os trabalhos do projeto.Esse sistema de arquivo está disponível como padrão em muitas das distribuições Linux. O Reiser4 foi o primeiro sistema de arquivos com suporte a “journaling”( um recurso que ajuda a manter a integridade dos dados em caso de erros no sistema causados por desligamento incorreto ou determinadas falhas de hardware) incluído no núcleo Linux 2.4+. São seus patrocinadores as empresas Novell e Linspire, embora a Novell tenha anunciado em Outubro de 2006 que o sistema de arquivos selecionado por omissão no Suse Linux passou a ser o ext3.

Semântica Básica Ficheiros

Um ficheiro é algo que tenta parecer com uma sequência de bytes.

É possível ler e escrever os bytes, determinar quantos e a partir de onde se podem ler. Também pode-se eliminar bytes no fim do ficheiro. A eliminação no início e meio do ficheiro não é permitida pela semântica do Unix. As interacções com os ficheiros são feitas através de plugins de ficheiros, interfaces que as delimitam. Para cada ficheiro existe uma pluginid. Cada forma de interagir com uma plugin é chamada de método, portanto cada plugin é composta por tais métodos. Cada método é composto de funções de bibliotecas (library). Para implementar um ficheiro Unix regular, com a sua Metadata [ver em tipos de items 2.3.1], é usado um file plugin (unix_file) para o corpo do ficheiro, um directory plugin (unix_file_dir) para encontrar file plugins para cada Metadata e uma especial file plugin para cada Metadata.

Nome e Objeto

Um nome é um meio de seleção de um objeto. Um Objeto é algo que atua como se fosse uma simples entidade, dependente do contexto. Namespace é o mapeamento de nomes a objetos, como, por exemplo, sistemas de ficheiros, bases de dados, motores de busca ou nomes de variáveis nas shells. Quanto mais poder tiverem os namespaces, mais poder expressivo terá o Sistema Operativo.

Reiser4 procura criar uma storage layer (camada de armazenagem) eficiente para qualquer, e eventualmente unificado, namespace, e uma semantic layer (camada semântica) com algumas vantagens sobre state of the art. A Namesys prevê mais expressão semântica na storage layer. A busca por objectos é feita por camadas. A camada semântica pega os nomes e converte-os em chaves (Keys) através de objectids. A camada de armazenagem (que contém o código para correr a árvore) pega as chaves e procura os bytes que guardam as partes do objecto. Cada elemento da árvore tem uma chave única, apesar de as chaves duplicadas serem permitidas. O seu uso significa que todos os duplicados devem ser examinados e verificado se realmente contêm o que é procurado. Por isto, são raros nos sistemas que procuram alta performance. Permitindo duplicados, as chaves podem ser mais compactas. Reiser4 trata apenas nomes hierárquicos (Hierarchical names). Os não-hierárquicos estão planeados para o SSN ReiserFS. (Semi-Structured Naming Reiserfs).

Diretórios

Nomes hierárquicos são implementados em Reiser4 pelo uso de diretorios. O 1º componente é o nome da diretorio. Os componentes são separados por "/". Os seguintes componentes são interpretados e usados para seguir para a sub-directorio seguinte até devolver um conjunto de chaves. Em Reiser4, este conjunto contém exactamente um membro, mas em SSN Reiserfs isso poderá mudar. Reiser4 necessita de interagir com a interface do Unix para os sistemas de ficheiros, daí a necessidade de existir uma chave que o VFS (sistema de ficheiros virtual) compreenda. As directorias podem devolver uma lista de nomes, que não precisa de ser a lista de nomes que consegue resolver. É possível ocultar nomes em Reiser4 e as diretorios podem resolver mais nomes do que podem listar, especialmente se forem pseudo files (não existentes na camada de armazenagem).

Ordenação das Diretorios

Em Unix, nem a ordem com que os ficheiros são criados nem a ordem lexicográfica se impõem à ordem de listagem. Após os sistemas de ficheiros os retornarem, são as aplicações que os ordenam. Em Reiser4, a plugin ordena os nomes dos ficheiros com menos de 15 letras lexicograficamente, e para os com mais, ordena pelas primeiras 8 letras e depois pelo hash do nome completo. Hans Reiser planeia implementar a ordenação pedida pelo utilizador nas próximas versões.

Diretórios também são Ficheiros

Em Reiser4, (mas não em Reiser3) um objeto tanto pode ser um ficheiro como uma directorio. Se for acedido como ficheiro, devolve uma sequência de bytes; se for acedido como directorio ("/"), devolve o resultado normal (listagem de nomes, ficheiros contidos etc.).

Entradas escondidas

Um ficheiro pode existir e não ser visível através da forma usual.

/* First directory item has k_offset component 1. We store "." and ".." in one item, always, we never split "." and ".." into differing items. This makes, among other things, the code for removing directories simpler. */

struct reiserfs_de_head { __le32 deh_offset; /* third component of the directory entry key */ __le32 deh_dir_id; /* objectid of the parent directory of the object, that is referenced by directory entry */ __le32 deh_objectid; /* objectid of the object, that is referenced by directory entry */ __le16 deh_location; /* offset of name in the whole item */ __le16 deh_state; /* whether 1) entry contains stat data (for future), and 2) whether entry is hidden (unlinked) */ } __attribute__ ((__packed__));

Características

O ReiserFS tem como referência o esquema B+Trees para organizar e localizar os itens que compõem, todo o sistema de arquivos, isto é, os dados em si e as informações associadas (data de criação, permissões de acesso, proprietário, etc). Todos esses itens são classificados em diretórios, blocos de dados diretos e indiretos (direct items / indirect items) e inodes (stat data items). ReiserFS usa árvores balanceadas para tornar o processo de busca de arquivos, informações sobre segurança e outros metadados mais eficientes. Para arquivos muito pequenos, seus dados podem ser armazenados próximos aos metadados, então, ambos podem ser recuperados com um pequeno movimento do mecanismo da "cabeça" de leitura do disco. Essa propriedade vai contribuir para um melhor desempenho caso uma aplicação necessite abrir muitos arquivos pequenos rapidamente. No caso de um desligamento incorreto do sistema, o ReiserFS é capaz de recuperar a consistência do sistema de arquivos em pouco tempo e a possibilidade de perda de pastas ou partições é reduzida.No entanto, os arquivos que eventualmente estiverem sendo gravados no exato momento em que acabou a energia elétrica ficarão com seus dados corrompidos, haverá acesso aos arquivos normalmente, mas o conteúdo estará truncado ou incompleto.

Árvores: Conceitos básicos Árvores, nós e Items Árvores

Um modo de organizar informação é a inserir em árvores. Reiser4 usa uma árvore finita com raiz (root), acíclica, com menos um apontadores (1-p) nós, e com exactamente um caminho desde a raiz até qualquer nó.

Grafos e Árvores

Esta árvore contém o mínimo de apontadores, suficientes para conectar todos os nós. Reiser usa grafos e árvores, sendo as árvores usadas para quando o sistema de ficheiros escolhe a organização na camada de armazenagem e os grafos para a organização escolhida pelo utilizador na camada semântica (mais complexa).

Chaves

A cada elemento na árvore é atribuída uma chave. O uso de chaves adiciona flexibilidade a como são ordenados os elementos, e se estas forem pequenas, um meio compacto de especificar o suficiente para encontrar o elemento, mas também limita que informação pode ser usada para encontrar elementos. Este limites são úteis, pois a camada de armazenagem escolhe as chaves apenas para organizar o armazenamento de modo a melhorar o desempenho, e a camada semântica, nomes que tenham significado para o utilizador. Esta abordagem ajuda a adição de melhoramentos em nível de armazenamento, sem comprometer com efeitos colaterais a camada semântica.

/* Key of an item determines its location in the S+tree, and is composed of 4 components */ struct reiserfs_key { __le32 k_dir_id; /* packing locality: by default parent directory object id */ __le32 k_objectid; /* object identifier */ union { struct offset_v1 k_offset_v1; struct offset_v2 k_offset_v2; } __attribute__ ((__packed__)) u; } __attribute__ ((__packed__));

struct in_core_key { __u32 k_dir_id; /* packing locality: by default parent directory object id */ __u32 k_objectid; /* object identifier */ __u64 k_offset; __u8 k_type;

struct cpu_key { struct in_core_key on_disk_key; int version; int key_length; /* 3 in all cases but direct2indirect and indirect2direct conversion */

A escolha da subárvore

A raiz contém apontadores para as suas subárvores. Para cada apontador a uma subárvore, existe uma chave esquerda delimitadora correspondente. Os apontadores para as subárvores e as subárvores estão ordenadas por esta chave. Esta é igual à menor chave dos elementos da subárvore. Também existe uma chave direita delimitadora que é superior à maior chave na sua subárvore e é a chave esquerda delimitadora na próxima subárvore deste nó. Se não existirem chaves duplicadas, cada subárvore apenas contém elementos cuja chave é igual à chave esquerda delimitadora e menor que a sua chave direita delimitadora, e procurando dentro do nó por apontadores, é encontrado o que se procura. Caso existam chaves duplicadas, como já foi dito, todos os duplicados devem ser examinados um a um e estão ordenados pela ordem de criação.

Nós Folhas, Pecíolos e Ramos (Leaves, Twigs, and Branches)

Folhas são os nós que não têm filhos. Os nós internos são os que têm filhos.

Um nó que contém itens é chamado nó formatado (formatted node).

Se um objecto é grande, não está comprimido e não precisa suportar inserções eficientes, então pode ser guardado mais eficientemente nos nós sem qualquer uso de itens. É feito por norma para objectos maiores que 16k. Objectos comprimidos são especiais porque necessitam mudar o uso de espaço quando é escrito para os seus interiores, pois a compressão pode não ser igualmente eficiente para os novos dados.

Nós não formatados {Unformatted leaves (unfleaves)} são folhas que contêm apenas dados e nenhum tipo de informação de formato. Apenas as folhas podem conter dados não formatados. Apontadores são guardados em itens, assim como todos os nós internos são necessariamente nós formatados. Apontadores para unfleaves são diferentes na sua estrutura dos apontadores para nós formatados. Apontadores estendidos (Extent pointers) apontam para unfleaves. Uma extensão (extent) é um número grande de blocos consecutivos. Cada extensão é descrita como um triplo, consistindo em: file offset, início do bloco, tamanho, onde file offset é o offset do 1º bloco da extensão desde o início do ficheiro, e tamanho é o número de blocos na extensão. As extensões são alocadas e seguidas como uma única entidade, i.e., um único apontador liga um grupo de blocos. Para grandes ficheiros, alocação por extensão é muito mais eficiente que alocação por bloco. Apontadores para nós (Node Pointers) são apontadores para nós formatados. Ainda não existe uma versão comprimida destes apontadores. Para os apontadores estendidos não é categórico guardar as chaves delimitadoras para cada nó apontado, mas é preciso para os Node Pointers. Pecíolos (Twigs) são os pais das folhas. Os extent Pointers existem apenas nos pecíolos. Esta é uma decisão muito controversa. Ramos (Branches) são nós internos que não são pecíolos.