17cbb468fSMauro Carvalho Chehab.. SPDX-License-Identifier: GPL-2.0 27cbb468fSMauro Carvalho Chehab 37cbb468fSMauro Carvalho Chehab================================ 47cbb468fSMauro Carvalho ChehabOptimized MPEG Filesystem (OMFS) 57cbb468fSMauro Carvalho Chehab================================ 67cbb468fSMauro Carvalho Chehab 77cbb468fSMauro Carvalho ChehabOverview 87cbb468fSMauro Carvalho Chehab======== 97cbb468fSMauro Carvalho Chehab 107cbb468fSMauro Carvalho ChehabOMFS is a filesystem created by SonicBlue for use in the ReplayTV DVR 117cbb468fSMauro Carvalho Chehaband Rio Karma MP3 player. The filesystem is extent-based, utilizing 127cbb468fSMauro Carvalho Chehabblock sizes from 2k to 8k, with hash-based directories. This 137cbb468fSMauro Carvalho Chehabfilesystem driver may be used to read and write disks from these 147cbb468fSMauro Carvalho Chehabdevices. 157cbb468fSMauro Carvalho Chehab 167cbb468fSMauro Carvalho ChehabNote, it is not recommended that this FS be used in place of a general 177cbb468fSMauro Carvalho Chehabfilesystem for your own streaming media device. Native Linux filesystems 187cbb468fSMauro Carvalho Chehabwill likely perform better. 197cbb468fSMauro Carvalho Chehab 207cbb468fSMauro Carvalho ChehabMore information is available at: 217cbb468fSMauro Carvalho Chehab 227cbb468fSMauro Carvalho Chehab http://linux-karma.sf.net/ 237cbb468fSMauro Carvalho Chehab 247cbb468fSMauro Carvalho ChehabVarious utilities, including mkomfs and omfsck, are included with 257cbb468fSMauro Carvalho Chehabomfsprogs, available at: 267cbb468fSMauro Carvalho Chehab 27*561a75acSAlexander A. Klimov https://bobcopeland.com/karma/ 287cbb468fSMauro Carvalho Chehab 297cbb468fSMauro Carvalho ChehabInstructions are included in its README. 307cbb468fSMauro Carvalho Chehab 317cbb468fSMauro Carvalho ChehabOptions 327cbb468fSMauro Carvalho Chehab======= 337cbb468fSMauro Carvalho Chehab 347cbb468fSMauro Carvalho ChehabOMFS supports the following mount-time options: 357cbb468fSMauro Carvalho Chehab 367cbb468fSMauro Carvalho Chehab ============ ======================================== 377cbb468fSMauro Carvalho Chehab uid=n make all files owned by specified user 387cbb468fSMauro Carvalho Chehab gid=n make all files owned by specified group 397cbb468fSMauro Carvalho Chehab umask=xxx set permission umask to xxx 407cbb468fSMauro Carvalho Chehab fmask=xxx set umask to xxx for files 417cbb468fSMauro Carvalho Chehab dmask=xxx set umask to xxx for directories 427cbb468fSMauro Carvalho Chehab ============ ======================================== 437cbb468fSMauro Carvalho Chehab 447cbb468fSMauro Carvalho ChehabDisk format 457cbb468fSMauro Carvalho Chehab=========== 467cbb468fSMauro Carvalho Chehab 477cbb468fSMauro Carvalho ChehabOMFS discriminates between "sysblocks" and normal data blocks. The sysblock 487cbb468fSMauro Carvalho Chehabgroup consists of super block information, file metadata, directory structures, 497cbb468fSMauro Carvalho Chehaband extents. Each sysblock has a header containing CRCs of the entire 507cbb468fSMauro Carvalho Chehabsysblock, and may be mirrored in successive blocks on the disk. A sysblock may 517cbb468fSMauro Carvalho Chehabhave a smaller size than a data block, but since they are both addressed by the 527cbb468fSMauro Carvalho Chehabsame 64-bit block number, any remaining space in the smaller sysblock is 537cbb468fSMauro Carvalho Chehabunused. 547cbb468fSMauro Carvalho Chehab 557cbb468fSMauro Carvalho ChehabSysblock header information:: 567cbb468fSMauro Carvalho Chehab 577cbb468fSMauro Carvalho Chehab struct omfs_header { 587cbb468fSMauro Carvalho Chehab __be64 h_self; /* FS block where this is located */ 597cbb468fSMauro Carvalho Chehab __be32 h_body_size; /* size of useful data after header */ 607cbb468fSMauro Carvalho Chehab __be16 h_crc; /* crc-ccitt of body_size bytes */ 617cbb468fSMauro Carvalho Chehab char h_fill1[2]; 627cbb468fSMauro Carvalho Chehab u8 h_version; /* version, always 1 */ 637cbb468fSMauro Carvalho Chehab char h_type; /* OMFS_INODE_X */ 647cbb468fSMauro Carvalho Chehab u8 h_magic; /* OMFS_IMAGIC */ 657cbb468fSMauro Carvalho Chehab u8 h_check_xor; /* XOR of header bytes before this */ 667cbb468fSMauro Carvalho Chehab __be32 h_fill2; 677cbb468fSMauro Carvalho Chehab }; 687cbb468fSMauro Carvalho Chehab 697cbb468fSMauro Carvalho ChehabFiles and directories are both represented by omfs_inode:: 707cbb468fSMauro Carvalho Chehab 717cbb468fSMauro Carvalho Chehab struct omfs_inode { 727cbb468fSMauro Carvalho Chehab struct omfs_header i_head; /* header */ 737cbb468fSMauro Carvalho Chehab __be64 i_parent; /* parent containing this inode */ 747cbb468fSMauro Carvalho Chehab __be64 i_sibling; /* next inode in hash bucket */ 757cbb468fSMauro Carvalho Chehab __be64 i_ctime; /* ctime, in milliseconds */ 767cbb468fSMauro Carvalho Chehab char i_fill1[35]; 777cbb468fSMauro Carvalho Chehab char i_type; /* OMFS_[DIR,FILE] */ 787cbb468fSMauro Carvalho Chehab __be32 i_fill2; 797cbb468fSMauro Carvalho Chehab char i_fill3[64]; 807cbb468fSMauro Carvalho Chehab char i_name[OMFS_NAMELEN]; /* filename */ 817cbb468fSMauro Carvalho Chehab __be64 i_size; /* size of file, in bytes */ 827cbb468fSMauro Carvalho Chehab }; 837cbb468fSMauro Carvalho Chehab 847cbb468fSMauro Carvalho ChehabDirectories in OMFS are implemented as a large hash table. Filenames are 857cbb468fSMauro Carvalho Chehabhashed then prepended into the bucket list beginning at OMFS_DIR_START. 867cbb468fSMauro Carvalho ChehabLookup requires hashing the filename, then seeking across i_sibling pointers 877cbb468fSMauro Carvalho Chehabuntil a match is found on i_name. Empty buckets are represented by block 887cbb468fSMauro Carvalho Chehabpointers with all-1s (~0). 897cbb468fSMauro Carvalho Chehab 907cbb468fSMauro Carvalho ChehabA file is an omfs_inode structure followed by an extent table beginning at 917cbb468fSMauro Carvalho ChehabOMFS_EXTENT_START:: 927cbb468fSMauro Carvalho Chehab 937cbb468fSMauro Carvalho Chehab struct omfs_extent_entry { 947cbb468fSMauro Carvalho Chehab __be64 e_cluster; /* start location of a set of blocks */ 957cbb468fSMauro Carvalho Chehab __be64 e_blocks; /* number of blocks after e_cluster */ 967cbb468fSMauro Carvalho Chehab }; 977cbb468fSMauro Carvalho Chehab 987cbb468fSMauro Carvalho Chehab struct omfs_extent { 997cbb468fSMauro Carvalho Chehab __be64 e_next; /* next extent table location */ 1007cbb468fSMauro Carvalho Chehab __be32 e_extent_count; /* total # extents in this table */ 1017cbb468fSMauro Carvalho Chehab __be32 e_fill; 1027cbb468fSMauro Carvalho Chehab struct omfs_extent_entry e_entry; /* start of extent entries */ 1037cbb468fSMauro Carvalho Chehab }; 1047cbb468fSMauro Carvalho Chehab 1057cbb468fSMauro Carvalho ChehabEach extent holds the block offset followed by number of blocks allocated to 1067cbb468fSMauro Carvalho Chehabthe extent. The final extent in each table is a terminator with e_cluster 1077cbb468fSMauro Carvalho Chehabbeing ~0 and e_blocks being ones'-complement of the total number of blocks 1087cbb468fSMauro Carvalho Chehabin the table. 1097cbb468fSMauro Carvalho Chehab 1107cbb468fSMauro Carvalho ChehabIf this table overflows, a continuation inode is written and pointed to by 1117cbb468fSMauro Carvalho Chehabe_next. These have a header but lack the rest of the inode structure. 1127cbb468fSMauro Carvalho Chehab 113