MINIX Projeto 5 Sistema de arquivos MINIX File















- Slides: 15
MINIX – Projeto 5 Sistema de arquivos
MINIX – File System Enunciado: “Como ocorre a system call read? (item 5. 6. 10 do livro do minix 3). Crie a system call leia (uma cópia de read) que ao fazer a leitura, imprime os blocos do disco que foram lidos. Faça um programa em C que use "leia" e imprima quais blocos foram lidos. Informe se o bloco está sendo lido do cache ou do disco. ”
MINIX – File System Objetivos: Este projeto tem como principais objetivos mostrar como o File System do Minix funciona, em especial no tratamento da system call “read”. Com isso, conseguimos acompanhar um pouco da lógica do Minix na hora de transferir blocos para o cache na leitura de um arquivo”
MINIX – File System call read: Localizada em /usr/src/lib/posix/_read. c Protótipo: PUBLIC ssize_t read(fd, buffer, nbytes); Parâmetros: fd – file descriptor: para se achar a entrada filp e o inode, necessários para a abertura do arquivo buffer – especifica o buffer do usuário nbytes – especifica a quantidade de bytes a serem lidos
MINIX – Projeto 5 Funcionamento da system call read: Construção de mensagem a partir dos parâmetros Mensagem emitida ao File System, que utiliza seu índice para chamar o procedimento que executa a leitura Faz-se a extração do file descriptor, para se fazer a leitura do arquivo Quebra-se o pedido para que cada parte do mesmo caiba em um bloco
MINIX – Projeto 5 Funcionamento da system call read: (continuação) Para cada bloco desta separação, verifica-se se está em cache Se não, o file system toma um buffer não em uso, não recentemente usado, reescrevendo-o, se já utilizado, com a leitura do arquivo. Com os blocos no cache, os dados são copiados ao buffer especificado na system call Com a cópia, o file system emite resposta com o número de bytes copiados Por fim, a system call retorna o código da resposta à função do processo que a chamou
MINIX – Projeto 5 Criação da system call “leia” Feita com base na system call read. Alterações nos seguintes arquivos: /usr/src/servers/fs/table. c /usr/src/servers/fs/proto. h /usr/src/servers/fs/leia. c (cópia de read. c) /usr/src/servers/fs/Makefile /usr/src/include/minix/callnr. h /usr/src/lib/posix/_leia. c (cópia de _read. c) /usr/src/lib/syscall/leia. s (cópia de read. s) /usr/src/lib/posix/Makefile. in /usr/src/include/unistd. h /usr/include/unistd. h
MINIX – Projeto 5 table. c: Modificar "no_sys, /* 69 = unused */" para "do_leia, /* 69 = leia */" proto. h: /* leia. c */ _PROTOTYPE( int do_leia, (void)); _PROTOTYPE( struct buf *leiaahead, (struct inode *rip, block_t baseblock, off_t position, unsigned bytes_ahead)); _PROTOTYPE( void leia_ahead, (void)); _PROTOTYPE( block_t leia_map, (struct inode *rip, off_t position)); _PROTOTYPE( int leia_write, (int rw_flag)); _PROTOTYPE( zone_t leia_indir, (struct buf *bp, int index));
MINIX – Projeto 5 leia. c: */ linha 31: PUBLIC int do_leia() linha 33: return(leia_write(READING)); linha 39: PUBLIC int leia_write(rw_flag) linha 281: b = leia_map(rip, position); linha 296: bp = leiaahead(rip, b, position, left); linha 338: PUBLIC block_t leia_map(rip, position) linha 381: z = leia_indir(bp, index); /* z= zone for single*/ linha 391: z = leia_indir(bp, ex); /* get block pointed to */ linha 401: PUBLIC zone_t leia_indir(bp, index) linha 433: PUBLIC void leia_ahead() linha 444: if ( (b = leia_map(rip, rdahedpos)) == NO_BLOCK) return; /* at EOF linha 445: bp = leiaahead(rip, b, rdahedpos, block_size); linha 452: PUBLIC struct buf *leiaahead(rip, baseblock, position, bytes_ahead) Imprimir o valor de "block" (linhas 484 -487 e ) utilizando "printf("Lendo bloco #%ld do cachen", block); " ou "printf("Lendo bloco #%ld do discon", block); ", observando que quando bp->b_dev for diferente de NO_DEV, o bloco já estará no cache
MINIX – Projeto 5 No arquivo /usr/src/servers/fs/Makefile em "OBJ = ", adicionar uma entrada para o arquivo "leia. o" Compilar em /usr/src/servers, com make image make install Alterar /usr/src/include/minix/callnr. h e /usr/include/minix/callnr. h: Adicionar linha “#define LEIA 69”
MINIX – Projeto 5 _leia. c: Remover linha "#define read _read“ Modificar: de "PUBLIC ssize_t read" para "PUBLIC ssize_t leia" de "return(_syscall(FS, READ, &m))“ para "return(_syscall(FS, LEIA, &m))" leia. s: Modificar: de ". extern __read" de ". define _read" de "_read: " de "jmp __read" para ". extern __leia" para ". define _leia" para "_leia: " para "jmp __leia"
MINIX – Projeto 5 Adicionar _leia. c no arquivo /usr/src/lib/posix/Makefile. in Executar “make Makefile” neste diretório Alterar /usr/src/include/unistd. h e /usr/include/unistd. h: Adicionar “_PROTOTYPE(ssize_t leia, (int _fd, void *_buf, size_t _n)); ” Compilar bibliotecas: Em /usr/src/, make libraries Compilar imagem de boot: Em /usr/src/tools, make hdboot, make install (gerada em /boot/image) Entrar comandos em modo monitor (após shutdown) image=/boot/image/<nome da imagem> boot
MINIX – Projeto 5 Criação de executável que use a system call: #include <stdio. h> #include <unistd. h> void main(int argc, char *argv[]) { FILE * arq; char * nome_arq, * buf; int nb; printf("Digite o nome do arquivo: "); scanf("%s", &nome_arq); while (arq==NULL) { printf("Arquivo invalido. Digite novamente o nome: "); scanf("%s", &nome_arq); }
MINIX – Projeto 5 printf("Digite o numero de bytes a serem lidos: "); scanf("%d", &nb); arq = fopen(nome_arq, "r"); leia(arq->_fd, buf, nb); printf("Leu: %sn", buf); fclose(arq); return 0; } Por fim, entrar com os comandos: cc <arquivo. c> -o <nome do executável>. /<nome do executável>
MINIX – Projeto 5