mmap 尝试在 C 中写入结构时返回 MAP_FAILED

问题描述 投票:0回答:1

我正在尝试开发 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 file mmap fuse inode
1个回答
0
投票

您正在寻求将 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
。这是无限递归的。我猜你的意思是它是一个指针。

© www.soinside.com 2019 - 2024. All rights reserved.