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

系统块标头信息

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 有一个标头,但缺少 inode 结构的其余部分。