1. Nível de Hardware
As operações de arquivo no nível de hardware incluem:
fdisk: particionar discos rígidos, drives USB ou cartões SD.mkfs: formatar partições de disco para preparar o sistema.fsck: verificar e reparar o sistema de arquivos.- Desfragmentação: comprimir arquivos dentro do sistema de arquivos.
2. Funções de Sistema de Arquivos no Kernel do Sistema Operacional
Cada kernel do sistema operacional fornece suporte para operações básicas de arquivo através de funções integradas.
3. Chamadas de Sistema
Programas em modo de usuário utilizam chamadas de sistema para acessar funções do kernel.
4. Funções de Biblioteca I/O
Bibliotecas de I/O oferecem uma camada de abstração sobre as chamadas de sistema.
5. Comandos do Usuário
Usuários podem executar operações de arquivo usando comandos do Unix/Linux sem necessidade de programação. Exemplos incluem:
mkdir, rmdir, cd, pwd, ls, link, unlink, rm, cat, cp, mv, chmod, etc.
Cada comando de usuário é tipicamente um programa executável que invoca funções de biblioteca I/O, que por sua vez emitem chamadas de sistema para chamar as funções do kernel correspondentes.
Operações de I/O de Arquivo
Quando um programa em modo de usuário executa uma operação de I/O:
- Uma chamada como
fopen("arquivo", "r")abre um fluxo de arquivo para leitura ou escrita. - A função
fopen()cria uma estruturaFILEno espaço do usuário (heap), contendo um descritor de arquivofd, um bufferfbuf[BLKSIZE]e variáveis de controle. - A função
fread(ubuf, size, nitem, fp)lênitemelementos desizebytes paraubuf. Primeiro, copia dados dofbufda estruturaFILEparaubuf; se os dados forem suficientes, retorna. Caso contrário, procede para a etapa de leitura do kernel. - Uma chamada de sistema
read(fd, fbuf, BLKSIZE)é emitida para carregar um bloco de dados do arquivo do kernel para ofbuf, e os dados são então copiados paraubufaté serem suficientes ou o arquivo terminar. - Para
fwrite(ubuf, size, nitem, fp): os dados são copiados deubufparafbuf. Se ofbuftiver espaço, os dados são armazenados e a função retorna. Se ofbufestiver cheio, uma chamada de sistemawrite(fd, fbuf, BLKSIZE)é usada para gravar o bloco de dados no kernel, e então os novos dados são escritos nofbuf.
Assim, fread() e fwrite() emitem chamadas de sistema read ou write somente quando necessário, transferindo dados em tamanhos de bloco para eficiência. Outras funções de biblioteca I/O, como fgetc/fputc, fgets/fputs, fscanf/fprintf, também operam no fbuf da estrutura FILE no espaço do usuário.
Funções de Sistema de Arquivos no Kernel
Para uma chamada de sistema read(fd, fbuf[], BLKSIZE) em um arquivo não especial:
- O
fdé um descritor de arquivo aberto, um índice no arrayfdo processo em execução, apontando para uma tabela aberta de arquivos (OpenTable). - A OpenTable contém o modo de abertura do arquivo, um ponteiro para o inode do arquivo na memória e o deslocamento atual de leitura/escrita.
- A partir do deslocamento na OpenTable, o número lógico do bloco
lbké calculado. O arrayINODE.i_block[]converte o número lógico do bloco no número físico do blocoblk. - O Minode contém o inode do arquivo na memória, com
INODE.i_block[]apontando para blocos físicos no disco.
Para aumentar a eficiência de I/O de disco, o kernel do sistema operacional normalmente usa um conjunto de buffers de I/O como cache para reduzir o número de operações físicas de I/O. Por exemplo:
- Para
read(fd, buf, BLKSIZE), determina-se o número(dev, blk)necessário e consulta-se a cache de buffers de I/O. - Para
write(fd, fbuf, BLKSIZE), determina-se o número(dev, blk)necessário e consulta-se a cache de buffers de I/O.
I/O de Dispositivo
A operação física de I/O nos buffers passa pelos drivers de dispositivo, que são compostos pela parte superior start_io() e pelo manipulador de interrupção de disco inferior.
Operações de Arquivo de Baixo Nível
- Particionamento de discos.
- Formatação de partições.
- Montagem de partições.
Chamadas de Sistema Simples
Exemplos de chamadas de sistema para operações comuns incluem:
access: verifica permissões de arquivo.chdir: altera o diretório de trabalho.chmod: altera as permissões de um arquivo.chown: altera o proprietário de um arquivo.chroot: altera o diretório raiz lógico.getcwd: obtém o caminho absoluto do diretório de trabalho atual.mkdir: cria um diretório.rmdir: remove um diretório vazio.link: cria um hardlink para um arquivo.unlink: reduz a contagem de links de um arquivo; se chegar a zero, o arquivo é removido.symlink: cria um link simbólico para um arquivo.rename: renomeia um arquivo.utime: altera os tempos de acesso e modificação de um arquivo.
Algumas chamadas de sistema requerem privilégios de superusuário:
mount: anexa um sistema de arquivos a um ponto de montagem.umount: desanexa um sistema de arquivos montado.mknod: cria um arquivo especial.
Chamadas de Sistema Comuns para I/O
stat: obtém informações de estado de um arquivo.open: abre um arquivo para leitura, escrita ou anexação.close: fecha um descritor de arquivo aberto.read: lê de um descritor de arquivo aberto.write: escreve em um descritor de arquivo aberto.lseek: reposiciona o deslocamento de leitura/escrita de um descritor de arquivo.dup: duplica um descritor de arquivo para o menor número disponível.dup2: duplica um descritor de arquivo para um número específico, fechando o destino se necesssário.link: cria um hardlink de um novo caminho para um caminho antigo.unlink: remove um link de arquivo; se a contagem de links chegar a zero, o arquivo é deletado.symlink: cria um link simbólico.readlink: lê o conteúdo de um arquivo de link simbólico.umask: define a máscara de criação de arquivo; permissões do arquivo são(mask & ~umask).
Chamada de Sistema read
A chamada de sistema read lê dados de um arquivo identificado por um descritor de arquivo, armazenando-os em um buffer pré-definido. Ela retorna o número de bytes realmente lidos.
Protótipo no Linux:
size_t read(int fildes, void *buf, size_t nbytes);
Parâmetros:
fildes: descritor de arquivo, identificando o arquivo a ser lido. Se for 0, lê da entrada padrão (similar ascanf()).*buf: buffer para armazenar os dados lidos.nbytes: número de bytes a serem lidos.
Valor de retorno: size_t retorna o número de caracteres lidos com sucesso, que pode ser menor que o solicitado.
Chamada de Sistema write
A chamada de sistema write grava dados de um buffer em um arquivo, onde "arquivo" pode ser entendido em sentido amplo, como disco, impressora, etc.
Protótipo no Linux:
size_t write(int fildes, const void *buf, size_t nbytes);
Parâmetros:
fildes: descritor de arquivo, identificando o destino da escrita. Por exemplo, se for 1, escreve na saída padrão (exibição na tela); se for 2, escreve na saída de erro.*buf: ponteiro para a string de dados a serem gravados.nbytes: número de bytes a serem escritos.
Valor de retorno: size_t retorna o número de bytes gravados com sucesso. Note que write pode reportar ter escrito menos bytes do que solicitado; isso não é necessariamente um erro. Em programas, deve-se verificar erros e chamar write novamente para os dados restantes, se necessário.