This page follows squashfs_fs.h of squashfs-tools 3.4 (its _2 structures) for SquashFS 2.0 and 2.1. The numbers of an image are all
little-endian or all big-endian, as the magic says. Some structures pack several small fields into one group of bits, a bit-field; each is
described by its bit position and width. In a little-endian image, bit 0 is the lowest bit of the first byte and a field takes the next bits upward; in a big-endian image, bit 0 is the
highest bit of the first byte and a field takes the next bits downward.
Superblock
119 bytes at the start; the structure is shared with versions 1 and 3. Version 2 uses the 32-bit fields; the 64-bit ones from offset 63 are not used.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
0 | 4 | text | Magic | hsqs little-endian, sqsh big-endian. |
4 | 4 | uint32 | Inode count | The number of inodes. |
8 | 4 | uint32 | Bytes used | The size of the filesystem: the end of the gid table. The file may be padded with zeros after it. |
12 | 4 | uint32 | Uid table start | File offset of the uid table. |
16 | 4 | uint32 | Gid table start | File offset of the gid table; 0 when there are no gids. |
20 | 4 | uint32 | Inode table start | File offset of the first metadata block of the inode table. The file data ends here. |
24 | 4 | uint32 | Directory table start | File offset of the first metadata block of the directory table. |
28 | 2 | uint16 | Version major | 2. |
30 | 2 | uint16 | Version minor | 0 or 1. |
32 | 2 | uint16 | Block size (16-bit) | Used by version 1; not used here. |
34 | 2 | uint16 | Block log | The base-2 logarithm of the block size. |
36 | 1 | uint8 | Flags | Bit flags, below. |
37 | 1 | uint8 | Uid count | The number of entries of the uid table. |
38 | 1 | uint8 | Gid count | The number of entries of the gid table. |
39 | 4 | uint32 | Modification time | Seconds since 1970-01-01 (UTC); also the time of every inode that has none of its own. |
43 | 8 | uint64 | Root inode | A reference to the root directory’s inode. |
51 | 4 | uint32 | Block size | The size of a data block and a fragment block before compression: a power of two. |
55 | 4 | uint32 | Fragment count | The number of fragment blocks. |
59 | 4 | uint32 | Fragment table start | File offset of the fragment table’s index, or 0xFFFFFFFF when there are no fragments. |
63 | 56 | – | Not used | The 64-bit fields of version 3 (bytes used, table starts, lookup table): not used in version 2. |
Flags
| Mask | Name | Meaning |
|---|---|---|
0x01 | UNCOMPRESSED_INODES | The inode and directory tables are stored uncompressed. |
0x02 | UNCOMPRESSED_DATA | Data blocks are stored uncompressed. |
0x04 | CHECK | Check data is present. |
0x08 | UNCOMPRESSED_FRAGMENTS | Fragment blocks are stored uncompressed. |
0x10 | NO_FRAGMENTS | Fragments are not used. |
0x20 | ALWAYS_FRAGMENTS | Fragments are always generated. |
0x40 | DUPLICATES | Files with identical contents are stored once. |
0x80 | EXPORTABLE | Not used in version 2. |
Metadata blocks
The inode table, the directory table and the fragment table are runs of metadata blocks, read as one stream. A block is a 2-byte header (bit 15 set:
stored uncompressed; bits 0 to 14: the size of the data, 1 to 8192) and the data, a zlib stream that decompresses to at most 8192 bytes. A
reference to a position in a table is block × 65536 + offset: the file offset of a metadata block counted from the start of the
table, and a position in that block after decompression. An inode or listing may continue into the next block.
Inodes
The inode table is a stream of inodes with no gaps. Every inode starts with the same 4-byte header; the fields of its type follow. There are no inode numbers and no link counts. Types: 1 directory, 2 file, 3 symbolic link, 4 block device, 5 character device, 6 FIFO, 7 socket, 8 extended directory.
| Bit | Bits | Name | Description |
|---|---|---|---|
0 | 4 | Type | 1 to 8. |
4 | 12 | Mode | The permission bits, including setuid, setgid and sticky. |
16 | 8 | Uid index | An index into the uid table. |
24 | 8 | Gid index | An index into the gid table; 255 means the group is the same as the user. |
After the header (bit positions counted from the start of the inode, so the first field after the header is at bit 32). Only files and directories have a time; the others have the superblock’s modification time.
| Type | Bit | Bits | Name | Description |
|---|---|---|---|---|
| 1 directory | 32 | 19 | File size | The size of the listing in bytes (no 3 is added in version 2). |
51 | 13 | Offset | Where the listing starts in its metadata block of the directory table. | |
64 | 32 | Modification time | Seconds since 1970-01-01 (UTC). | |
96 | 24 | Start block | The offset of that metadata block from the start of the directory table. | |
| 8 extended directory | 32 | 27 | File size | The size of the listing in bytes. |
59 | 13 | Offset | As above. | |
72 | 32 | Modification time | As above. | |
104 | 24 | Start block | As above. | |
128 | 16 | Index count | The number of index entries that follow the inode. | |
144 | … | Index | Index count entries, see directories. | |
| 2 file | 32 | 32 | Modification time | Seconds since 1970-01-01 (UTC). |
64 | 32 | Start block | The file offset of the first data block. | |
96 | 32 | Fragment | The fragment holding the file’s tail, or 0xFFFFFFFF. | |
128 | 32 | Offset | Where the tail starts in the decompressed fragment. | |
160 | 32 | File size | The size of the file in bytes. | |
192 | 32 × n | Block list | One size word per data block: with a fragment, the file size divided by the block size rounded down; without, rounded up. | |
| 3 symbolic link | 32 | 16 | Target size | The length of the target in bytes. |
48 | 8 × size | Target | The path, with no terminator. | |
| 4, 5 device | 32 | 16 | Device number | Major in the high 8 bits, minor in the low 8 bits. |
| 6, 7 FIFO, socket | – | – | – | Nothing but the header. |
There is no inode number in the image. The kernel makes one from the position: the metadata block’s offset times 256, plus the offset in the block divided by 4, plus 1; the explorer shows that.
Directories
A directory inode names its listing by a block and an offset in the directory table, and gives its length. A listing is a run of headers, each followed by up to 256 entries; “.” and “..” are not stored and no 3 is added to the size. In version 2.1 the entries are sorted by name; in 2.0 they are not.
| Structure | Offset | Size | Name | Description |
|---|---|---|---|---|
| Header (4 bytes) | bits 0 to 7 | 8 bits | Count | The number of entries that follow, minus one. |
bits 8 to 31 | 24 bits | Start block | The metadata block of the inode table that holds the inodes of all these entries. | |
| Entry (3 bytes, then the name) | bits 0 to 12 | 13 bits | Offset | Where the entry’s inode starts in that decompressed block. |
bits 13 to 15 | 3 bits | Type | The basic type of the inode, 1 to 7. | |
bits 16 to 23 | 8 bits | Name size | The length of the name minus one. | |
3 | size + 1 | Name | The name, with no terminator. | |
| Index entry of an extended directory (8 bytes, then the name) | bits 0 to 26 | 27 bits | Index | The byte position of a header in the listing. |
bits 27 to 55 | 29 bits | Start block | The metadata block of the directory table that holds that header. | |
bits 56 to 63 | 8 bits | Name size | The length of the name minus one; the name is the first entry of that header. |
File data
A file’s blocks lie one after another from its start block. Each block has a 32-bit size word in the inode: bits 0 to 23 are the stored size and bit 24 is set when the block is stored uncompressed. A block decompresses (a zlib stream) to the block size, except a last block. Version 2 has no sparse blocks. The tail of a file that is not a whole number of blocks is in a fragment: the inode gives the fragment and the offset of the tail in the decompressed fragment block.
Fragment table
One 8-byte entry for each fragment block, 1024 to a metadata block, then an index: an array of 32-bit file offsets of those metadata blocks. The superblock gives the offset of the index.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
0 | 4 | uint32 | Start | The file offset of the fragment block. |
4 | 4 | uint32 | Size | As a data block’s size word: bit 24 set when stored uncompressed. |
Uid and gid tables
Two plain arrays of 32-bit ids at the end of the filesystem (not in metadata blocks): the uid table, then the gid table. An inode’s uid and gid indexes select an entry; a gid index of 255 means the group is the same as the user.