优化的 MPEG 文件系统 (OMFS)

概述

OMFS 是 SonicBlue 创建的文件系统,用于 ReplayTV DVR 和 Rio Karma MP3 播放器。该文件系统基于区段,使用 2k 到 8k 的块大小,并具有基于哈希的目录。此文件系统驱动程序可用于读取和写入这些设备上的磁盘。

请注意,不建议将此文件系统用于您自己的流媒体媒体设备的通用文件系统。原生 Linux 文件系统可能会表现更好。

更多信息请访问

各种实用程序,包括 mkomfs 和 omfsck,都包含在 omfsprogs 中,可在此处获得

说明包含在其 README 中。

选项

OMFS 支持以下挂载时选项

uid=n

使所有文件都归指定用户所有

gid=n

使所有文件都归指定组所有

umask=xxx

将权限 umask 设置为 xxx

fmask=xxx

为文件将 umask 设置为 xxx

dmask=xxx

为目录将 umask 设置为 xxx

磁盘格式

OMFS 区分“sysblock”和普通数据块。 sysblock 组包含超级块信息、文件元数据、目录结构和区段。每个 sysblock 都有一个包含整个 sysblock 的 CRC 的标头,并且可以在磁盘上的连续块中镜像。 sysblock 的大小可能小于数据块,但由于它们都由相同的 64 位块号寻址,因此较小的 sysblock 中任何剩余空间都未使用。

Sysblock 标头信息

struct omfs_header {
        __be64 h_self;                  /* FS block where this is located */
        __be32 h_body_size;             /* size of useful data after header */
        __be16 h_crc;                   /* crc-ccitt of body_size bytes */
        char h_fill1[2];
        u8 h_version;                   /* version, always 1 */
        char h_type;                    /* OMFS_INODE_X */
        u8 h_magic;                     /* OMFS_IMAGIC */
        u8 h_check_xor;                 /* XOR of header bytes before this */
        __be32 h_fill2;
};

文件和目录都由 omfs_inode 表示

struct omfs_inode {
        struct omfs_header i_head;      /* header */
        __be64 i_parent;                /* parent containing this inode */
        __be64 i_sibling;               /* next inode in hash bucket */
        __be64 i_ctime;                 /* ctime, in milliseconds */
        char i_fill1[35];
        char i_type;                    /* OMFS_[DIR,FILE] */
        __be32 i_fill2;
        char i_fill3[64];
        char i_name[OMFS_NAMELEN];      /* filename */
        __be64 i_size;                  /* size of file, in bytes */
};

OMFS 中的目录实现为大型哈希表。文件名经过哈希处理,然后预先添加到从 OMFS_DIR_START 开始的桶列表中。查找需要对文件名进行哈希处理,然后跨 i_sibling 指针进行搜索,直到找到 i_name 上的匹配项。空桶由全 1 (~0) 的块指针表示。

文件是一个 omfs_inode 结构,后跟一个从 OMFS_EXTENT_START 开始的区段表

struct omfs_extent_entry {
        __be64 e_cluster;               /* start location of a set of blocks */
        __be64 e_blocks;                /* number of blocks after e_cluster */
};

struct omfs_extent {
        __be64 e_next;                  /* next extent table location */
        __be32 e_extent_count;          /* total # extents in this table */
        __be32 e_fill;
        struct omfs_extent_entry e_entry;       /* start of extent entries */
};

每个区段都包含块偏移量,后跟分配给该区段的块数。每个表中的最后一个区段是一个终止符,其中 e_cluster 为 ~0,e_blocks 为表中块总数的补码。

如果此表溢出,则会写入一个延续 inode 并由 e_next 指向。这些有标头,但缺少 inode 结构的其余部分。