1Optimized MPEG Filesystem (OMFS) 2 3Overview 4======== 5 6OMFS is a filesystem created by SonicBlue for use in the ReplayTV DVR 7and Rio Karma MP3 player. The filesystem is extent-based, utilizing 8block sizes from 2k to 8k, with hash-based directories. This 9filesystem driver may be used to read and write disks from these 10devices. 11 12Note, it is not recommended that this FS be used in place of a general 13filesystem for your own streaming media device. Native Linux filesystems 14will likely perform better. 15 16More information is available at: 17 18 http://linux-karma.sf.net/ 19 20Various utilities, including mkomfs and omfsck, are included with 21omfsprogs, available at: 22 23 http://bobcopeland.com/karma/ 24 25Instructions are included in its README. 26 27Options 28======= 29 30OMFS supports the following mount-time options: 31 32 uid=n - make all files owned by specified user 33 gid=n - make all files owned by specified group 34 umask=xxx - set permission umask to xxx 35 fmask=xxx - set umask to xxx for files 36 dmask=xxx - set umask to xxx for directories 37 38Disk format 39=========== 40 41OMFS discriminates between "sysblocks" and normal data blocks. The sysblock 42group consists of super block information, file metadata, directory structures, 43and extents. Each sysblock has a header containing CRCs of the entire 44sysblock, and may be mirrored in successive blocks on the disk. A sysblock may 45have a smaller size than a data block, but since they are both addressed by the 46same 64-bit block number, any remaining space in the smaller sysblock is 47unused. 48 49Sysblock header information: 50 51struct omfs_header { 52 __be64 h_self; /* FS block where this is located */ 53 __be32 h_body_size; /* size of useful data after header */ 54 __be16 h_crc; /* crc-ccitt of body_size bytes */ 55 char h_fill1[2]; 56 u8 h_version; /* version, always 1 */ 57 char h_type; /* OMFS_INODE_X */ 58 u8 h_magic; /* OMFS_IMAGIC */ 59 u8 h_check_xor; /* XOR of header bytes before this */ 60 __be32 h_fill2; 61}; 62 63Files and directories are both represented by omfs_inode: 64 65struct omfs_inode { 66 struct omfs_header i_head; /* header */ 67 __be64 i_parent; /* parent containing this inode */ 68 __be64 i_sibling; /* next inode in hash bucket */ 69 __be64 i_ctime; /* ctime, in milliseconds */ 70 char i_fill1[35]; 71 char i_type; /* OMFS_[DIR,FILE] */ 72 __be32 i_fill2; 73 char i_fill3[64]; 74 char i_name[OMFS_NAMELEN]; /* filename */ 75 __be64 i_size; /* size of file, in bytes */ 76}; 77 78Directories in OMFS are implemented as a large hash table. Filenames are 79hashed then prepended into the bucket list beginning at OMFS_DIR_START. 80Lookup requires hashing the filename, then seeking across i_sibling pointers 81until a match is found on i_name. Empty buckets are represented by block 82pointers with all-1s (~0). 83 84A file is an omfs_inode structure followed by an extent table beginning at 85OMFS_EXTENT_START: 86 87struct omfs_extent_entry { 88 __be64 e_cluster; /* start location of a set of blocks */ 89 __be64 e_blocks; /* number of blocks after e_cluster */ 90}; 91 92struct omfs_extent { 93 __be64 e_next; /* next extent table location */ 94 __be32 e_extent_count; /* total # extents in this table */ 95 __be32 e_fill; 96 struct omfs_extent_entry e_entry; /* start of extent entries */ 97}; 98 99Each extent holds the block offset followed by number of blocks allocated to 100the extent. The final extent in each table is a terminator with e_cluster 101being ~0 and e_blocks being ones'-complement of the total number of blocks 102in the table. 103 104If this table overflows, a continuation inode is written and pointed to by 105e_next. These have a header but lack the rest of the inode structure. 106 107