文件系統是linux內核的重要組成部分,涉及到vfs、塊IO層的調度機制,塊設備驅動以及具體文件系統所采用的數據結構。所使用linux內核版本是2.6.34.1。
以fs/omfs為例,主要學習vfs的實現,omfs的硬盤布局,它所采用的數據結構為何能夠優化MPEG文件系統。Omfs文件系統的具體文件讀寫又是如何實現的。
OMFS:Optimized MPEG Filesystem
OMFS是由SonicBlue公司創建的用於ReplayTV DVR和MP3 player的文件系統。該文件系統是基於extent的(現代很多文件系統都采用extent替代block來管理磁盤。Extent就是一些連續的block,可以有效減少元數據開銷。),可用的block大小在2k到8k之間,目錄結構是基於hash的。
該文件系統在特定的流媒體設備中性能很好,但對於一般的應用,linux主流的文件系統應該性能更優。Omfs是如何針對MPEG做性能優化,這點還在探索中。
相關閱讀:
Linux文件系統omfs的目錄創建和刪除 http://www.linuxidc.com/Linux/2012-02/54025.htm
Linux文件系統omfs的目錄創建和刪除 http://www.linuxidc.com/Linux/2012-02/54025.htm
Linux文件系統omfs的普通文件創建和刪除 http://www.linuxidc.com/Linux/2012-02/54026.htm
硬盤布局格式:
Omfs區分sysblocks和一般的數據blocks。Sysblock group由superblock信息、文件的metadata元數據、目錄結構和extents構成。每一個sysblock都有一個包含CRC校驗的頭,而且可以在硬盤上備份。Sysblock大小比一個數據block小,但是它們都用64位的塊號尋址。
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中的目錄是一個大的hash表。文件名經過hash計算,然後放到以OMFS_DIR_START開始的桶中。查找的時候需要hash文件名,然後通過i_sibling指針查找到匹配的i_name。
文件以omfs_inode結構體開頭,後面跟著在OMFS_EXTENT_START開始的extent table。
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 */
};