我正在尝试开发 FUSE 文件系统驱动程序来创建挂载点。为了使其持久化,我想将索引节点保存到二进制文件中。这是我的 inode 结构:
struct s_fuseInode {
int id; /* Identificador del inodo */
char name[MAX_NAME]; /* Nombre del archivo */
char path[MAX_PATH]; /* Ruta del archivo */
int size; /* Tamaño del archivo */
int block_count; /* Número de bloques ocupados por el archivo */
int block[MAX_BLOCKS]; /* Bloques ocupados por el archivo */
struct s_fuseInode parent; / Inodo padre */
int parent_id; /* Identificador del inodo padre */
struct s_fuseInode *children; / Inodos hijos */
int children_count; /* Número de inodos hijos */
int is_dir; /* Indica si el inodo es un directorio */
char data; / Datos del archivo */
time_t creation_time; /* Fecha de creación del archivo */
time_t modification_time; /* Fecha de modificación del archivo */
time_t access_time; /* Fecha de acceso al archivo */
int links; /* Número de enlaces al archivo */
mode_t mode; /* Permisos del archivo */
uid_t uid; /* Identificador de usuario */
gid_t gid; /* Identificador de grupo */
};
这就是将inode保存到文件中的函数
static int save_inode(struct s_fuseInode *inode)
{
int fd = open("virtual_disk.bin", O_RDWR, S_IRUSR | S_IWUSR); // Abrimos el archivo de disco virtual
if (fd == -1) // Si no se ha podido abrir
{
fprintf(stderr, "save_inode: Error al abrir el archivo de disco virtual\n");
return (1);
}
off_t offset = lseek(fd, 0, SEEK_END); // Nos situamos al final del archivo
fprintf(stderr, "offset %ld\n", offset);
if (offset == -1) // Si no se ha podido situar
{
fprintf(stderr, "save_inode: Error al situarse al final del archivo\n");
return (1);
}
ftruncate(fd, offset + sizeof(struct s_fuseInode)); // Truncamos el archivo
fprintf(stderr, "size %ld\n", offset + sizeof(struct s_fuseInode));
struct s_fuseInode *map = mmap(0, sizeof(struct s_fuseInode), PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset); // Mapeamos el archivo
if (map == MAP_FAILED) // Si no se ha podido mapear
{
close(fd);
fprintf(stderr, "save_inode: Error al mapear el archivo\n");
return (1);
}
memcpy(map, inode, sizeof(struct s_fuseInode)); // Copiamos el inodo en el archivo
if (munmap(map, sizeof(struct s_fuseInode)) == -1) // Si no se ha podido desmapear
{
close(fd);
fprintf(stderr, "save_inode: Error al desmapear el archivo\n");
return (1);
}
close(fd); // Cerramos el archivo
return (0);
}
它返回
MAP_FAILED
的错误。 inode 结构是 256 位,PAGE_SIZE
是 4096。我以为问题是页面对齐,但我不知道如何解决问题,第一次使用 mmap。
我尝试包含一个
char padding[3840]
来达到 4096 大小并且它可以工作,但问题是文件的每个 inode 占用 4KB 的大小,我希望它得到优化。
您正在寻求将 C 结构序列化为磁盘文件。使用
mmap
来实现它是相当复杂的。为了优化这一点,您必须为每个页面提供一个标题,指向下一个可用的插槽。当然,一旦您添加了另一个索引节点,就会进行更新。就像文件系统中的超级块一样。
以追加模式打开文件(与seek-to-end相同)并直接写入结构会更简单。
没有错误检查:
int fd = open("virtual_disk.bin", O_RDWR | O_APPEND, S_IRUSR | S_IWUSR);
write(fd, inode, sizeof(inode));
close(fd);
顺便说一句:
您的结构体将其自身作为成员:
struct s_fuseInode parent
。这是无限递归的。我猜你的意思是它是一个指针。