xref: /linux/fs/cramfs/README (revision 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2)
1*1da177e4SLinus TorvaldsNotes on Filesystem Layout
2*1da177e4SLinus Torvalds--------------------------
3*1da177e4SLinus Torvalds
4*1da177e4SLinus TorvaldsThese notes describe what mkcramfs generates.  Kernel requirements are
5*1da177e4SLinus Torvaldsa bit looser, e.g. it doesn't care if the <file_data> items are
6*1da177e4SLinus Torvaldsswapped around (though it does care that directory entries (inodes) in
7*1da177e4SLinus Torvaldsa given directory are contiguous, as this is used by readdir).
8*1da177e4SLinus Torvalds
9*1da177e4SLinus TorvaldsAll data is currently in host-endian format; neither mkcramfs nor the
10*1da177e4SLinus Torvaldskernel ever do swabbing.  (See section `Block Size' below.)
11*1da177e4SLinus Torvalds
12*1da177e4SLinus Torvalds<filesystem>:
13*1da177e4SLinus Torvalds	<superblock>
14*1da177e4SLinus Torvalds	<directory_structure>
15*1da177e4SLinus Torvalds	<data>
16*1da177e4SLinus Torvalds
17*1da177e4SLinus Torvalds<superblock>: struct cramfs_super (see cramfs_fs.h).
18*1da177e4SLinus Torvalds
19*1da177e4SLinus Torvalds<directory_structure>:
20*1da177e4SLinus Torvalds	For each file:
21*1da177e4SLinus Torvalds		struct cramfs_inode (see cramfs_fs.h).
22*1da177e4SLinus Torvalds		Filename.  Not generally null-terminated, but it is
23*1da177e4SLinus Torvalds		 null-padded to a multiple of 4 bytes.
24*1da177e4SLinus Torvalds
25*1da177e4SLinus TorvaldsThe order of inode traversal is described as "width-first" (not to be
26*1da177e4SLinus Torvaldsconfused with breadth-first); i.e. like depth-first but listing all of
27*1da177e4SLinus Torvaldsa directory's entries before recursing down its subdirectories: the
28*1da177e4SLinus Torvaldssame order as `ls -AUR' (but without the /^\..*:$/ directory header
29*1da177e4SLinus Torvaldslines); put another way, the same order as `find -type d -exec
30*1da177e4SLinus Torvaldsls -AU1 {} \;'.
31*1da177e4SLinus Torvalds
32*1da177e4SLinus TorvaldsBeginning in 2.4.7, directory entries are sorted.  This optimization
33*1da177e4SLinus Torvaldsallows cramfs_lookup to return more quickly when a filename does not
34*1da177e4SLinus Torvaldsexist, speeds up user-space directory sorts, etc.
35*1da177e4SLinus Torvalds
36*1da177e4SLinus Torvalds<data>:
37*1da177e4SLinus Torvalds	One <file_data> for each file that's either a symlink or a
38*1da177e4SLinus Torvalds	 regular file of non-zero st_size.
39*1da177e4SLinus Torvalds
40*1da177e4SLinus Torvalds<file_data>:
41*1da177e4SLinus Torvalds	nblocks * <block_pointer>
42*1da177e4SLinus Torvalds	 (where nblocks = (st_size - 1) / blksize + 1)
43*1da177e4SLinus Torvalds	nblocks * <block>
44*1da177e4SLinus Torvalds	padding to multiple of 4 bytes
45*1da177e4SLinus Torvalds
46*1da177e4SLinus TorvaldsThe i'th <block_pointer> for a file stores the byte offset of the
47*1da177e4SLinus Torvalds*end* of the i'th <block> (i.e. one past the last byte, which is the
48*1da177e4SLinus Torvaldssame as the start of the (i+1)'th <block> if there is one).  The first
49*1da177e4SLinus Torvalds<block> immediately follows the last <block_pointer> for the file.
50*1da177e4SLinus Torvalds<block_pointer>s are each 32 bits long.
51*1da177e4SLinus Torvalds
52*1da177e4SLinus TorvaldsThe order of <file_data>'s is a depth-first descent of the directory
53*1da177e4SLinus Torvaldstree, i.e. the same order as `find -size +0 \( -type f -o -type l \)
54*1da177e4SLinus Torvalds-print'.
55*1da177e4SLinus Torvalds
56*1da177e4SLinus Torvalds
57*1da177e4SLinus Torvalds<block>: The i'th <block> is the output of zlib's compress function
58*1da177e4SLinus Torvaldsapplied to the i'th blksize-sized chunk of the input data.
59*1da177e4SLinus Torvalds(For the last <block> of the file, the input may of course be smaller.)
60*1da177e4SLinus TorvaldsEach <block> may be a different size.  (See <block_pointer> above.)
61*1da177e4SLinus Torvalds<block>s are merely byte-aligned, not generally u32-aligned.
62*1da177e4SLinus Torvalds
63*1da177e4SLinus Torvalds
64*1da177e4SLinus TorvaldsHoles
65*1da177e4SLinus Torvalds-----
66*1da177e4SLinus Torvalds
67*1da177e4SLinus TorvaldsThis kernel supports cramfs holes (i.e. [efficient representation of]
68*1da177e4SLinus Torvaldsblocks in uncompressed data consisting entirely of NUL bytes), but by
69*1da177e4SLinus Torvaldsdefault mkcramfs doesn't test for & create holes, since cramfs in
70*1da177e4SLinus Torvaldskernels up to at least 2.3.39 didn't support holes.  Run mkcramfs
71*1da177e4SLinus Torvaldswith -z if you want it to create files that can have holes in them.
72*1da177e4SLinus Torvalds
73*1da177e4SLinus Torvalds
74*1da177e4SLinus TorvaldsTools
75*1da177e4SLinus Torvalds-----
76*1da177e4SLinus Torvalds
77*1da177e4SLinus TorvaldsThe cramfs user-space tools, including mkcramfs and cramfsck, are
78*1da177e4SLinus Torvaldslocated at <http://sourceforge.net/projects/cramfs/>.
79*1da177e4SLinus Torvalds
80*1da177e4SLinus Torvalds
81*1da177e4SLinus TorvaldsFuture Development
82*1da177e4SLinus Torvalds==================
83*1da177e4SLinus Torvalds
84*1da177e4SLinus TorvaldsBlock Size
85*1da177e4SLinus Torvalds----------
86*1da177e4SLinus Torvalds
87*1da177e4SLinus Torvalds(Block size in cramfs refers to the size of input data that is
88*1da177e4SLinus Torvaldscompressed at a time.  It's intended to be somewhere around
89*1da177e4SLinus TorvaldsPAGE_CACHE_SIZE for cramfs_readpage's convenience.)
90*1da177e4SLinus Torvalds
91*1da177e4SLinus TorvaldsThe superblock ought to indicate the block size that the fs was
92*1da177e4SLinus Torvaldswritten for, since comments in <linux/pagemap.h> indicate that
93*1da177e4SLinus TorvaldsPAGE_CACHE_SIZE may grow in future (if I interpret the comment
94*1da177e4SLinus Torvaldscorrectly).
95*1da177e4SLinus Torvalds
96*1da177e4SLinus TorvaldsCurrently, mkcramfs #define's PAGE_CACHE_SIZE as 4096 and uses that
97*1da177e4SLinus Torvaldsfor blksize, whereas Linux-2.3.39 uses its PAGE_CACHE_SIZE, which in
98*1da177e4SLinus Torvaldsturn is defined as PAGE_SIZE (which can be as large as 32KB on arm).
99*1da177e4SLinus TorvaldsThis discrepancy is a bug, though it's not clear which should be
100*1da177e4SLinus Torvaldschanged.
101*1da177e4SLinus Torvalds
102*1da177e4SLinus TorvaldsOne option is to change mkcramfs to take its PAGE_CACHE_SIZE from
103*1da177e4SLinus Torvalds<asm/page.h>.  Personally I don't like this option, but it does
104*1da177e4SLinus Torvaldsrequire the least amount of change: just change `#define
105*1da177e4SLinus TorvaldsPAGE_CACHE_SIZE (4096)' to `#include <asm/page.h>'.  The disadvantage
106*1da177e4SLinus Torvaldsis that the generated cramfs cannot always be shared between different
107*1da177e4SLinus Torvaldskernels, not even necessarily kernels of the same architecture if
108*1da177e4SLinus TorvaldsPAGE_CACHE_SIZE is subject to change between kernel versions
109*1da177e4SLinus Torvalds(currently possible with arm and ia64).
110*1da177e4SLinus Torvalds
111*1da177e4SLinus TorvaldsThe remaining options try to make cramfs more sharable.
112*1da177e4SLinus Torvalds
113*1da177e4SLinus TorvaldsOne part of that is addressing endianness.  The two options here are
114*1da177e4SLinus Torvalds`always use little-endian' (like ext2fs) or `writer chooses
115*1da177e4SLinus Torvaldsendianness; kernel adapts at runtime'.  Little-endian wins because of
116*1da177e4SLinus Torvaldscode simplicity and little CPU overhead even on big-endian machines.
117*1da177e4SLinus Torvalds
118*1da177e4SLinus TorvaldsThe cost of swabbing is changing the code to use the le32_to_cpu
119*1da177e4SLinus Torvaldsetc. macros as used by ext2fs.  We don't need to swab the compressed
120*1da177e4SLinus Torvaldsdata, only the superblock, inodes and block pointers.
121*1da177e4SLinus Torvalds
122*1da177e4SLinus Torvalds
123*1da177e4SLinus TorvaldsThe other part of making cramfs more sharable is choosing a block
124*1da177e4SLinus Torvaldssize.  The options are:
125*1da177e4SLinus Torvalds
126*1da177e4SLinus Torvalds  1. Always 4096 bytes.
127*1da177e4SLinus Torvalds
128*1da177e4SLinus Torvalds  2. Writer chooses blocksize; kernel adapts but rejects blocksize >
129*1da177e4SLinus Torvalds     PAGE_CACHE_SIZE.
130*1da177e4SLinus Torvalds
131*1da177e4SLinus Torvalds  3. Writer chooses blocksize; kernel adapts even to blocksize >
132*1da177e4SLinus Torvalds     PAGE_CACHE_SIZE.
133*1da177e4SLinus Torvalds
134*1da177e4SLinus TorvaldsIt's easy enough to change the kernel to use a smaller value than
135*1da177e4SLinus TorvaldsPAGE_CACHE_SIZE: just make cramfs_readpage read multiple blocks.
136*1da177e4SLinus Torvalds
137*1da177e4SLinus TorvaldsThe cost of option 1 is that kernels with a larger PAGE_CACHE_SIZE
138*1da177e4SLinus Torvaldsvalue don't get as good compression as they can.
139*1da177e4SLinus Torvalds
140*1da177e4SLinus TorvaldsThe cost of option 2 relative to option 1 is that the code uses
141*1da177e4SLinus Torvaldsvariables instead of #define'd constants.  The gain is that people
142*1da177e4SLinus Torvaldswith kernels having larger PAGE_CACHE_SIZE can make use of that if
143*1da177e4SLinus Torvaldsthey don't mind their cramfs being inaccessible to kernels with
144*1da177e4SLinus Torvaldssmaller PAGE_CACHE_SIZE values.
145*1da177e4SLinus Torvalds
146*1da177e4SLinus TorvaldsOption 3 is easy to implement if we don't mind being CPU-inefficient:
147*1da177e4SLinus Torvaldse.g. get readpage to decompress to a buffer of size MAX_BLKSIZE (which
148*1da177e4SLinus Torvaldsmust be no larger than 32KB) and discard what it doesn't need.
149*1da177e4SLinus TorvaldsGetting readpage to read into all the covered pages is harder.
150*1da177e4SLinus Torvalds
151*1da177e4SLinus TorvaldsThe main advantage of option 3 over 1, 2, is better compression.  The
152*1da177e4SLinus Torvaldscost is greater complexity.  Probably not worth it, but I hope someone
153*1da177e4SLinus Torvaldswill disagree.  (If it is implemented, then I'll re-use that code in
154*1da177e4SLinus Torvaldse2compr.)
155*1da177e4SLinus Torvalds
156*1da177e4SLinus Torvalds
157*1da177e4SLinus TorvaldsAnother cost of 2 and 3 over 1 is making mkcramfs use a different
158*1da177e4SLinus Torvaldsblock size, but that just means adding and parsing a -b option.
159*1da177e4SLinus Torvalds
160*1da177e4SLinus Torvalds
161*1da177e4SLinus TorvaldsInode Size
162*1da177e4SLinus Torvalds----------
163*1da177e4SLinus Torvalds
164*1da177e4SLinus TorvaldsGiven that cramfs will probably be used for CDs etc. as well as just
165*1da177e4SLinus Torvaldssilicon ROMs, it might make sense to expand the inode a little from
166*1da177e4SLinus Torvaldsits current 12 bytes.  Inodes other than the root inode are followed
167*1da177e4SLinus Torvaldsby filename, so the expansion doesn't even have to be a multiple of 4
168*1da177e4SLinus Torvaldsbytes.
169