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
27561a75acSAlexander 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