The directory table is a stream of metadata blocks holding the listing of every directory, one after another. A directory’s inode says where its listing starts (a block and an offset) and how long it is. A listing is a run of headers, each followed by up to 256 entries; the entries are sorted by name, and the names are not null-terminated. The “.” and “..” entries are not stored. All numbers are in the image’s byte order.
Directory header
12 bytes. An entry gives its inode as an offset from the header, so one header covers a run of entries whose inodes are in the same metadata block of the inode table and whose numbers are within 16 bits of the first.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
0 | 4 | uint32 | Count | The number of entries that follow, minus one: 0 to 255. |
4 | 4 | uint32 | Start | The offset of the metadata block of the inode table that holds all the entries’ inodes, counted from the start of that table. |
8 | 4 | uint32 | Inode number | The inode number of the first entry; the other entries’ numbers are this plus their delta. |
Directory entry
8 bytes, then the name.
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
0 | 2 | uint16 | Offset | Where the entry’s inode starts in that decompressed block of the inode table (0 to 8191). With the header’s start this is the inode’s reference. |
2 | 2 | int16 | Inode delta | A signed number added to the header’s inode number to get the entry’s inode number. |
4 | 2 | uint16 | Type | The basic type of the inode, 1 to 7 (inodes). |
6 | 2 | uint16 | Name size | The length of the name in bytes, minus one: 0 to 255. |
8 | size + 1 | bytes | Name | The file name: any bytes except / and zero, not . or ... SquashFS does not say how names are encoded; Linux writes UTF-8. |
The size of a listing, as the directory inode gives it, is the sum of every header (12) and every entry (8 plus the name) plus 3. A reader works through the listing until it has taken that many bytes minus 3. Entries that share an inode are hard links.
Directory index
A listing of many entries would be slow to search, so an extended directory inode carries an index: the position of some of its headers, with the first name of each, so that a lookup can go straight to the right header. mksquashfs writes an entry for each header that starts in another metadata block of the directory table than the one before it. An index entry is 12 bytes and a name:
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
0 | 4 | uint32 | Index | Where the header lies in the listing: a byte position counted from the start of the listing (0 is the first header). |
4 | 4 | uint32 | Start block | The offset of the metadata block of the directory table that holds that header, counted from the start of the directory table. |
8 | 4 | uint32 | Name size | The length of the name minus one. |
12 | size + 1 | bytes | Name | The name of the first entry of that header. A lookup for a name that sorts before the next index entry’s name starts at this header. |