Sistema de fitxers MFS: codi C corregit per a directoris i inodes

Inglés7,29 KB

Sistema de fitxers MFS: codi C corregit

A continuació es presenta el codi en llenguatge C d'un sistema de fitxers simple (MFS), amb les funcions per a la creació, lectura i gestió de directoris, inodes i blocs de dades.

Estructura de directori

struct mfs_dir {
int siguiente;
struct disk_inode d;
};


Obertura de directoris: mfs_opendir

MFS_DIR *mfs_opendir(const char *name) {
int i;
int fd = -1;
struct disk_inode ino;
int inodo = namei(fs, &fs->root, name);
if (inodo == -1) return NULL;
if (inode_read(fs, &ino, inodo) != 1) return NULL;
if (ino.is_dir != 1) return NULL;
struct mfs_dir *directorio = malloc(sizeof(struct mfs_dir));
if (directorio == NULL) return NULL;
for (i = 0; i < NUM_FILES; i++) {
if (fs->file[i].num == -1) {
fd = i;
break;
}
}
if (fd != -1) {
inode_read(fs, &fs->file[fd].ino, inodo);
fs->file[fd].pos = 0;
fs->file[fd].num = inodo;
} else {
return NULL;
}
directorio->siguiente = fd;
return directorio;
}


Lectura de directoris: mfs_readdir

struct dirent *mfs_readdir(MFS_DIR *dir) {
struct entry arg;
struct dirent *d = malloc(sizeof(struct dirent));
arg.inode = dir->siguiente;
return NULL;
}


Tancament de directoris: mfs_closedir

int mfs_closedir(MFS_DIR *dir) {
if (dir->siguiente < 0 || dir->siguiente >= NUM_FILES) return -1;
if (fs->file[dir->siguiente].num == -1) return -1; // cerrar algo no abierto
inode_write(fs, &fs->file[dir->siguiente].ino, fs->file[dir->siguiente].num);
fs->file[dir->siguiente].num = -1;
free(dir);
return 0;
}


Inicialització del superbloc: sb_init

static int sb_init(struct file_system *fs, int num_blocks, int percent_inodes) {
fs->sb.block_size = block_get_block_size(fs->dev);
fs->sb.num_inodes = num_blocks * percent_inodes / 100;
fs->sb.num_bitmap = num_blocks - 1 - fs->sb.num_inodes;
fs->sb.num_bitmap = fs->sb.num_bitmap + fs->sb.block_size - 1;
fs->sb.num_bitmap = fs->sb.num_bitmap / fs->sb.block_size;
fs->sb.num_data_blocks = num_blocks - fs->sb.num_inodes - fs->sb.num_bitmap - 1;
fs->sb.root_inode = 0;
return sb_write(fs->dev, &(fs->sb));
}


Inicialització del mapa de bits: bitmap_init

static int bitmap_init(struct file_system *fs) {
int size = block_get_block_size(fs->dev);
char *block = malloc(size);
int i;
if (block == NULL) return -ENOMEM;
memset(block, '\0', size);
for (i = 0; i < fs->sb.num_bitmap; i++) block_write(fs->dev, block, 1 + i);
bitmap_read(fs);
return 1;
}


Inicialització dels inodes: inodes_init

static int inodes_init(struct file_system *fs) {
struct disk_inode ino;
int i;
ino.size = -1; /* vacío */
ino.is_dir = -1;
for (i = 0; i < NUM_EXTENTS; i++) {
ino.e[i].start = -1;
ino.e[i].size = -1;
}
for (i = 0; i < fs->sb.num_inodes; i++) inode_write(fs, &ino, i);
return 1;
}


Inicialització dels blocs de dades: data_init

static int data_init(struct file_system *fs) {
int size = block_get_block_size(fs->dev);
char *block = malloc(size);
int i;
if (block == NULL) return -ENOMEM;
memset(block, '@', size);
for (i = 0; i < fs->sb.num_data_blocks; i++) data_write(fs, block, i);
return 1;
}


Creació del directori arrel: dir_create

static int dir_create(struct file_system *fs) {
struct disk_inode ino;
int i;
char block[fs->sb.block_size];
struct entry *dir = (struct entry *)block;
// obtenemos un inodo libre
int inode = get_free_inode(fs);
// inicializamos a -1 todos los campos inode de las entradas que quepan en un bloque
for (i = 0; i < fs->sb.block_size / sizeof(struct entry); i++) dir[i].inode = -1;
// leemos el inodo que hemos encontrado libre
inode_read(fs, &ino, inode);
ino.is_dir = 1; // indicamos que es un directorio
for (i = 0; i < ino.e[0].size; i++) {
file_write(fs, &ino, block, i);
}
// indicamos los dos directorios estándar de cualquier directorio
strcpy(dir[0].name, ².);
dir[0].inode = inode;
strcpy(dir[1].name, ²..);
dir[1].inode = inode;
file_write(fs, &ino, block, 0);
inode_write(fs, &ino, inode);
return inode;
}


Formateig del sistema de fitxers: mfs_mkfs

int mfs_mkfs(char *name, int num_blocks, int size_block, int percent_inodes) {
// reservamos espacio para el sistema de ficheros
fs = malloc(sizeof(struct file_system));
if (fs == NULL) return -ENOMEM;
// rellenamos con '\0' la estructura fs para que los campos en memoria queden inicializados y no haya basura
memset(fs, '\0', sizeof(struct file_system));
fs->dev = block_create(name, num_blocks, size_block);
if (fs->dev == NULL) return -1;
if (sb_init(fs, num_blocks, percent_inodes) <= 0) return -1;
if (bitmap_init(fs) <= 0) return -1;
if (inodes_init(fs) <= 0) return -1;
if (data_init(fs) <= 0) return -1;
// CREAMOS el directorio raíz y guardamos el número de inodo (el 0) en el atributo correspondiente
fs->sb.root_inode = dir_create(fs);
if (fs->sb.root_inode < 0) return -1;
sb_write(fs->dev, &(fs->sb));
return 0;
}


Obtenció d'atributs: mfs_stat

int mfs_stat(const char *path, struct stat *buf) {
int inode;
struct disk_inode ino;
inode = namei(fs, &fs->root, path);
if (inode == -1) return -1;
inode_read(fs, &ino, inode);
// guardamos en la estructura stat los datos que tenemos del inodo
buf->st_ino = inode;
buf->st_blocks = ino.e[0].size;
buf->st_size = ino.size;
if (ino.is_dir == 1) buf->st_mode = S_IFDIR;
else buf->st_mode = S_IFREG;
return 0;
}


Creació de directoris: mfs_mkdir

int mfs_mkdir(const char *pathname, mode_t mode) {
int i, j;
int inode;
char padres[strlen(pathname)];
strcpy(padres, damePadresPath(pathname)); // guardo path del padre
char fichName[strlen(pathname)];
strcpy(fichName, dameFicheroPath(pathname)); // guardo nombre fichero
inode = namei(fs, &fs->root, padres); // busco cuál es el nº de inodo padre
if (inode == -1) return -1;
struct disk_inode ino_padre;
inode_read(fs, &ino_padre, inode); // traigo a memoria el inodo del directorio padre
int nuevo_inodo = dir_create(fs);
if (nuevo_inodo == -1) return -1;
char block[fs->sb.block_size];
struct entry *dir = (struct entry *)block;
for (i = 0; i < ino_padre.e[0].size; i++) {
file_read(fs, &ino_padre, block, i);
for (j = 0; i < fs->sb.block_size / sizeof(struct entry); j++) {
if (dir[j].inode == -1) {
dir[j].inode = nuevo_inodo;
strncpy(dir[j].name, fichName, ENTRY_SIZE);
file_write(fs, &ino_padre, block, i);
break;
}
}
}
return 1;
}

Descargar

PDF Word HTML