mirror of
https://github.com/torvalds/linux
synced 2026-07-22 10:10:47 +09:00
fs/cramfs/README still carries a "Future Development" section written
around the Linux 2.3.39 era discussing design decisions that have long
since been settled:
- Block size is 4096 and matches PAGE_SIZE on the reader.
- Endianness is host-endian; mkcramfs -B / -L handles cross-builds.
- Block-pointer extensions (CRAMFS_FLAG_EXT_BLOCK_POINTERS) ended up
being the answer to layout flexibility rather than inode growth.
Drop the stale forward-looking section -- the factual format
description above remains accurate and is kept as-is.
While here, replace the dead sourceforge URL in the "Tools" section
with the current location of the user-space tools on github.
Signed-off-by: Nicolas Pitre <nico@fluxnic.net>
Signed-off-by: Jonathan Corbet <corbet@lwn.net>
Message-ID: <20260422211039.270552-2-nico@fluxnic.net>
108 lines
4.2 KiB
Plaintext
108 lines
4.2 KiB
Plaintext
Notes on Filesystem Layout
|
|
--------------------------
|
|
|
|
These notes describe what mkcramfs generates. Kernel requirements are
|
|
a bit looser, e.g. it doesn't care if the <file_data> items are
|
|
swapped around (though it does care that directory entries (inodes) in
|
|
a given directory are contiguous, as this is used by readdir).
|
|
|
|
All data is currently in host-endian format; neither mkcramfs nor the
|
|
kernel ever do swabbing. (See section `Block Size' below.)
|
|
|
|
<filesystem>:
|
|
<superblock>
|
|
<directory_structure>
|
|
<data>
|
|
|
|
<superblock>: struct cramfs_super (see cramfs_fs.h).
|
|
|
|
<directory_structure>:
|
|
For each file:
|
|
struct cramfs_inode (see cramfs_fs.h).
|
|
Filename. Not generally null-terminated, but it is
|
|
null-padded to a multiple of 4 bytes.
|
|
|
|
The order of inode traversal is described as "width-first" (not to be
|
|
confused with breadth-first); i.e. like depth-first but listing all of
|
|
a directory's entries before recursing down its subdirectories: the
|
|
same order as `ls -AUR' (but without the /^\..*:$/ directory header
|
|
lines); put another way, the same order as `find -type d -exec
|
|
ls -AU1 {} \;'.
|
|
|
|
Beginning in 2.4.7, directory entries are sorted. This optimization
|
|
allows cramfs_lookup to return more quickly when a filename does not
|
|
exist, speeds up user-space directory sorts, etc.
|
|
|
|
<data>:
|
|
One <file_data> for each file that's either a symlink or a
|
|
regular file of non-zero st_size.
|
|
|
|
<file_data>:
|
|
nblocks * <block_pointer>
|
|
(where nblocks = (st_size - 1) / blksize + 1)
|
|
nblocks * <block>
|
|
padding to multiple of 4 bytes
|
|
|
|
The i'th <block_pointer> for a file stores the byte offset of the
|
|
*end* of the i'th <block> (i.e. one past the last byte, which is the
|
|
same as the start of the (i+1)'th <block> if there is one). The first
|
|
<block> immediately follows the last <block_pointer> for the file.
|
|
<block_pointer>s are each 32 bits long.
|
|
|
|
When the CRAMFS_FLAG_EXT_BLOCK_POINTERS capability bit is set, each
|
|
<block_pointer>'s top bits may contain special flags as follows:
|
|
|
|
CRAMFS_BLK_FLAG_UNCOMPRESSED (bit 31):
|
|
The block data is not compressed and should be copied verbatim.
|
|
|
|
CRAMFS_BLK_FLAG_DIRECT_PTR (bit 30):
|
|
The <block_pointer> stores the actual block start offset and not
|
|
its end, shifted right by 2 bits. The block must therefore be
|
|
aligned to a 4-byte boundary. The block size is either blksize
|
|
if CRAMFS_BLK_FLAG_UNCOMPRESSED is also specified, otherwise
|
|
the compressed data length is included in the first 2 bytes of
|
|
the block data. This is used to allow discontiguous data layout
|
|
and specific data block alignments e.g. for XIP applications.
|
|
|
|
|
|
The order of <file_data>'s is a depth-first descent of the directory
|
|
tree, i.e. the same order as `find -size +0 \( -type f -o -type l \)
|
|
-print'.
|
|
|
|
|
|
<block>: The i'th <block> is the output of zlib's compress function
|
|
applied to the i'th blksize-sized chunk of the input data if the
|
|
corresponding CRAMFS_BLK_FLAG_UNCOMPRESSED <block_ptr> bit is not set,
|
|
otherwise it is the input data directly.
|
|
(For the last <block> of the file, the input may of course be smaller.)
|
|
Each <block> may be a different size. (See <block_pointer> above.)
|
|
|
|
<block>s are merely byte-aligned, not generally u32-aligned.
|
|
|
|
When CRAMFS_BLK_FLAG_DIRECT_PTR is specified then the corresponding
|
|
<block> may be located anywhere and not necessarily contiguous with
|
|
the previous/next blocks. In that case it is minimally u32-aligned.
|
|
If CRAMFS_BLK_FLAG_UNCOMPRESSED is also specified then the size is always
|
|
blksize except for the last block which is limited by the file length.
|
|
If CRAMFS_BLK_FLAG_DIRECT_PTR is set and CRAMFS_BLK_FLAG_UNCOMPRESSED
|
|
is not set then the first 2 bytes of the block contains the size of the
|
|
remaining block data as this cannot be determined from the placement of
|
|
logically adjacent blocks.
|
|
|
|
|
|
Holes
|
|
-----
|
|
|
|
This kernel supports cramfs holes (i.e. [efficient representation of]
|
|
blocks in uncompressed data consisting entirely of NUL bytes), but by
|
|
default mkcramfs doesn't test for & create holes, since cramfs in
|
|
kernels up to at least 2.3.39 didn't support holes. Run mkcramfs
|
|
with -z if you want it to create files that can have holes in them.
|
|
|
|
|
|
Tools
|
|
-----
|
|
|
|
The cramfs user-space tools, including mkcramfs and cramfsck, are
|
|
located at <https://github.com/npitre/cramfs-tools>.
|