Every SquashFS 4.0 image starts with a 96-byte superblock. It gives the size of the
blocks, how they are compressed, how many inodes, fragments and ids there are, and the file
offset of every table. All numbers are stored in one byte order for the whole image:
little-endian when the first four bytes are hsqs, big-endian when they are
sqsh. Offsets below are bytes from the start of the image.
Fields
| Offset | Size | Type | Name | Description |
|---|---|---|---|---|
0 | 4 | text | Magic | hsqs (0x73717368 read little-endian) for a little-endian image, sqsh for a big-endian one. |
4 | 4 | uint32 | Inode count | The number of inodes in the inode table, and the number of entries of the export table. |
8 | 4 | uint32 | Modification time | Seconds since 1970-01-01 (UTC): when the image was made or last appended to. |
12 | 4 | uint32 | Block size | The size of a data block and of a fragment block, before compression. A power of two from 4096 to 1,048,576; mksquashfs defaults to 131,072. |
16 | 4 | uint32 | Fragment count | The number of entries of the fragment table; 0 when there are none. |
20 | 2 | uint16 | Compression id | 1 gzip, 2 lzma, 3 lzo, 4 xz, 5 lz4, 6 zstd. See compression. |
22 | 2 | uint16 | Block log | The base-2 logarithm of the block size (17 for 131,072). Must agree with the block size. |
24 | 2 | uint16 | Flags | Bit flags, below. |
26 | 2 | uint16 | Id count | The number of entries of the id table: the distinct user and group ids used. |
28 | 2 | uint16 | Version major | 4. |
30 | 2 | uint16 | Version minor | 0. |
32 | 8 | uint64 | Root inode | A reference to the root directory’s inode: the offset of its metadata block from the start of the inode table, times 65,536, plus the offset inside the decompressed block. |
40 | 8 | uint64 | Bytes used | The size of the filesystem, up to the end of the last table. mksquashfs then pads the file with zeros to a multiple of 4096 bytes. |
48 | 8 | uint64 | Id table start | File offset of the id table’s pointer array (tables). |
56 | 8 | uint64 | Xattr table start | File offset of the extended attribute table’s header, or 0xFFFFFFFFFFFFFFFF when there are none (xattrs). |
64 | 8 | uint64 | Inode table start | File offset of the first metadata block of the inode table. The file data ends here. |
72 | 8 | uint64 | Directory table start | File offset of the first metadata block of the directory table. |
80 | 8 | uint64 | Fragment table start | File offset of the fragment table’s pointer array, or 0xFFFFFFFFFFFFFFFF when there are none (tables). |
88 | 8 | uint64 | Export table start | File offset of the export table’s pointer array, or 0xFFFFFFFFFFFFFFFF when the image is not exportable (tables). |
Flags
The flags are informational: the tables themselves say whether each metadata block is compressed (bit 15 of its header) and each data block (bit 24 of its size word), and a reader goes by those. They tell a reader what the writer was asked for.
| Mask | Name | Meaning |
|---|---|---|
0x0001 | UNCOMPRESSED_INODES | The inode table is stored uncompressed (mksquashfs -noI, which also leaves the id table uncompressed). |
0x0002 | UNCOMPRESSED_DATA | Data blocks are stored uncompressed (-noD). |
0x0004 | CHECK | Unused in version 4 (it marked check data in version 3). |
0x0008 | UNCOMPRESSED_FRAGMENTS | Fragment blocks are stored uncompressed (-noF). |
0x0010 | NO_FRAGMENTS | No fragments are used (-no-fragments): the tail of a file is a short block of its own. |
0x0020 | ALWAYS_FRAGMENTS | Tail ends are always packed into fragments (-tailends, -always-use-fragments). |
0x0040 | DUPLICATES | Files with identical contents share their data (the default; -no-duplicates clears it). |
0x0080 | EXPORTABLE | The image has an export table, so it can be exported over NFS (-no-exports clears it). |
0x0100 | UNCOMPRESSED_XATTRS | The extended attribute blocks are stored uncompressed (-noX). |
0x0200 | NO_XATTRS | The image has no extended attributes (-no-xattrs). |
0x0400 | COMPRESSOR_OPTIONS | A compressor options block follows the superblock. |
0x0800 | UNCOMPRESSED_IDS | The id table is stored uncompressed. |
The four bits 0xF000 are not defined.
Where everything is
0Superblock 96 bytes9696Compressor options one metadata block, only with flag 0x4002 + size…Data blocks and fragment blocks the contents of the filesvariesinode table startInode table metadata blocksvariesdirectory table startDirectory table metadata blocksvaries…Fragment, export and id tables metadata blocks, then a pointer array eachvaries…Xattr table key/value blocks, id blocks, a header and pointersvariesbytes usedPadding zeros to a multiple of 4096, then anything elsevaries
Everything after bytes used is not part of the filesystem. mksquashfs pads the image with zeros to a multiple of 4096 bytes so that it can sit on a block device; a file image can also sit inside another file (a Snap package is one; an AppImage is a program followed by an image). This viewer reads an image that starts at the first byte of the file.