Back to home page

OSCL-LXR

 
 

    


0001 .. SPDX-License-Identifier: GPL-2.0
0002 
0003 ================================
0004 Optimized MPEG Filesystem (OMFS)
0005 ================================
0006 
0007 Overview
0008 ========
0009 
0010 OMFS is a filesystem created by SonicBlue for use in the ReplayTV DVR
0011 and Rio Karma MP3 player.  The filesystem is extent-based, utilizing
0012 block sizes from 2k to 8k, with hash-based directories.  This
0013 filesystem driver may be used to read and write disks from these
0014 devices.
0015 
0016 Note, it is not recommended that this FS be used in place of a general
0017 filesystem for your own streaming media device.  Native Linux filesystems
0018 will likely perform better.
0019 
0020 More information is available at:
0021 
0022     http://linux-karma.sf.net/
0023 
0024 Various utilities, including mkomfs and omfsck, are included with
0025 omfsprogs, available at:
0026 
0027     https://bobcopeland.com/karma/
0028 
0029 Instructions are included in its README.
0030 
0031 Options
0032 =======
0033 
0034 OMFS supports the following mount-time options:
0035 
0036     ============   ========================================
0037     uid=n          make all files owned by specified user
0038     gid=n          make all files owned by specified group
0039     umask=xxx      set permission umask to xxx
0040     fmask=xxx      set umask to xxx for files
0041     dmask=xxx      set umask to xxx for directories
0042     ============   ========================================
0043 
0044 Disk format
0045 ===========
0046 
0047 OMFS discriminates between "sysblocks" and normal data blocks.  The sysblock
0048 group consists of super block information, file metadata, directory structures,
0049 and extents.  Each sysblock has a header containing CRCs of the entire
0050 sysblock, and may be mirrored in successive blocks on the disk.  A sysblock may
0051 have a smaller size than a data block, but since they are both addressed by the
0052 same 64-bit block number, any remaining space in the smaller sysblock is
0053 unused.
0054 
0055 Sysblock header information::
0056 
0057     struct omfs_header {
0058             __be64 h_self;                  /* FS block where this is located */
0059             __be32 h_body_size;             /* size of useful data after header */
0060             __be16 h_crc;                   /* crc-ccitt of body_size bytes */
0061             char h_fill1[2];
0062             u8 h_version;                   /* version, always 1 */
0063             char h_type;                    /* OMFS_INODE_X */
0064             u8 h_magic;                     /* OMFS_IMAGIC */
0065             u8 h_check_xor;                 /* XOR of header bytes before this */
0066             __be32 h_fill2;
0067     };
0068 
0069 Files and directories are both represented by omfs_inode::
0070 
0071     struct omfs_inode {
0072             struct omfs_header i_head;      /* header */
0073             __be64 i_parent;                /* parent containing this inode */
0074             __be64 i_sibling;               /* next inode in hash bucket */
0075             __be64 i_ctime;                 /* ctime, in milliseconds */
0076             char i_fill1[35];
0077             char i_type;                    /* OMFS_[DIR,FILE] */
0078             __be32 i_fill2;
0079             char i_fill3[64];
0080             char i_name[OMFS_NAMELEN];      /* filename */
0081             __be64 i_size;                  /* size of file, in bytes */
0082     };
0083 
0084 Directories in OMFS are implemented as a large hash table.  Filenames are
0085 hashed then prepended into the bucket list beginning at OMFS_DIR_START.
0086 Lookup requires hashing the filename, then seeking across i_sibling pointers
0087 until a match is found on i_name.  Empty buckets are represented by block
0088 pointers with all-1s (~0).
0089 
0090 A file is an omfs_inode structure followed by an extent table beginning at
0091 OMFS_EXTENT_START::
0092 
0093     struct omfs_extent_entry {
0094             __be64 e_cluster;               /* start location of a set of blocks */
0095             __be64 e_blocks;                /* number of blocks after e_cluster */
0096     };
0097 
0098     struct omfs_extent {
0099             __be64 e_next;                  /* next extent table location */
0100             __be32 e_extent_count;          /* total # extents in this table */
0101             __be32 e_fill;
0102             struct omfs_extent_entry e_entry;       /* start of extent entries */
0103     };
0104 
0105 Each extent holds the block offset followed by number of blocks allocated to
0106 the extent.  The final extent in each table is a terminator with e_cluster
0107 being ~0 and e_blocks being ones'-complement of the total number of blocks
0108 in the table.
0109 
0110 If this table overflows, a continuation inode is written and pointed to by
0111 e_next.  These have a header but lack the rest of the inode structure.
0112