cromfs - Copyright (C) 1992,2006 Bisqwit (http://iki.fi/bisqwit/)
License: GPL
Homepage: http://bisqwit.iki.fi/source/cromfs.html

cromfs filesystem structure / format description.

VERSION 02

--------------------------------
Note: Inode 1 is assumed to be the root directory by the kernel.

Note: All integers are encoded in little-endian byte order.

OVERALL STRUCTURE

OBJECT: SUPERBLOCK
	0000	u64	CROMFS SIGNATURE "CROMFS02"
	0008	u64	Location of BLKDATA within the filesystem
	0010	u64	Location of FBLKTAB within the filesystem (must be last)
	0018	u64	Location of the Inotab inode within the filesystem
	0020	u64	Location of the Root directory within the filesystem
	0028	u32	FSIZE Maximum size of uncompressed FBLOCK (default: 2M)
	002C	u32	BSIZE Size of uncompressed blocks (default: 64k)
	0030	u64	Bytes of file data on disk (only there for statvfs)
	0...	INODE	Root directory
	0...	INODE	Inotab (only the "list of blocks" is used)
	0...	BLKDATA	LZMA-compressed array of BLOCK entries.
	0...	FBLOCK[] FBLKTAB = compressed storage

In CROMFS02, root directory and inotab are stored compressed.
In CROMFS01, they are stored uncompressed.
This is the only difference between those versions.

Note:
- Inotab must be placed immediately after the root directory.
- BLKDATA must be placed immediately after inotab.
- FBLKTAB must be placed immediately after BLKDATA.
- There must be no content after FBLKTAB.
  If you require padding, put it before the root directory.

---------------------------

STRUCT: FBLOCK
	0000	u32	length of compressed data
	0004	char[]	LZMA-compressed data, length indicated in above field
	0009	u64	length of uncompressed data (this field is part of the LZMA stream)
	(Note: Since cromfs version 1.0.5, FBLOCKs are variable-length.
	 Previously they were all of FSIZE size.)
	(Note: Since cromfs version 1.1.0, FSIZE indicates the maximum size of
	 uncompressed FBLOCKs. Previously it indicated the maximum size of compressed
	 FBLOCKs.)

STRUCT: BLKDATA (LZMA-compressed)
	0000	BLOCK[]  BLKTAB = all blocks of the filesystem (indexed by block number)
	(Note: To handle BLKDATA effeciently, it must be decompressed entirely
	into the RAM when the block lists are needed. This typically might consume
	several megabytes of RAM. However, cromfs-driver deallocates the
	data periodically when the filesystem has been idle for some time.)

STRUCT: BLOCK
	0000	u32	FBLOCK number (0=first FBLOCK, 1=second FBLOCK, etc)
	0004	u32	starting offset within the _uncompressed data_ for this data
	(Note: different BLOCKs may utilize the same data from same FBLOCK.
	 They regions which they use may overlap partially or completely.
	 They do not need to be aligned.)
	(This record refers to at most BSIZE bytes of data, but may actually
	 refer to less data if this is the last block of the file.)

STRUCT: INODE
	0000	u32	mode
	0004	u32	mtime
	0008	u32	rdev, if a device, hardlink count otherwise
	000C	u16	uid
	000E	u16	gid
	0010	u64	size in bytes
	0018	u32[]	(data locators;indexes to BLKTAB, 0=first BLOCK,1=second BLOCK,...)
	(Note: Location of uid&gid and rdev have been changed in version 1.1.2)

STRUCT: ENTRY
	0000	u64	inode number
	0008	char[]	file name, nul-terminated

ALL FILES ARE COMPRESSED (the content is spread across different FBLOCKs)

FILE CONTENT WHEN: INOTAB
	0000	INODE[] all inodes of the filesystem (note: INODE is variable-length).
	                the beginning of each inode is at offset ((inodenumber-2) * 4)
	                inodenumber 1 is the root directory (not stored in INOTAB),
	                and inodenumber 0 is error.

FILE CONTENT WHEN: DIRECTORY
	0000	u32	number of files in directory
	0004	u32[]	index into each file entry (from directory entry beginning)
	0004	ENTRY[]	each file entry (variable length)
	(Note: The files in a directory are sorted in an asciibetical order.
	This enables fast implementation of lookup() using a binary search.)

FILE CONTENT WHEN: SYMLINK
	0000	char[]	link text, not nul-terminated

FILE CONTENT WHEN: REGULAR FILES
	0000	content	file content

For other types of files, file has no content (size=0, blocktab=empty)

--------------------------------
