Introduction
SquashFS is a compressed, read-only filesystem for Linux, written by Phillip Lougher and in the kernel since 2.6.29. An image holds a whole directory tree, with permissions, owners, times, symbolic links, device nodes and extended attributes, compressed block by block, and the kernel mounts it directly: reading a file decompresses only the blocks that file needs. It is the filesystem of live CDs and installers, of Snap packages and AppImages, of the firmware of routers and many embedded devices, and of container images.
Version 4.0, current since 2009, is described here: mksquashfs builds
one from a directory, unsquashfs lists and extracts one. Images are normally little-endian
(they start hsqs); the format also has a big-endian form that starts sqsh.
Older versions have different structures and are separate formats on this site:
3, 2 and
1.
How it works
The superblock at the start gives the block size, the compressor (gzip, lzma, lzo, xz, lz4 or zstd) and the file offset of each table. File contents are cut into blocks of the block size, each compressed on its own and stored one after another (see file data); the short tail of a file shares a fragment block with the tails of others. After the data come the tables, all made of metadata blocks of at most 8 KiB: one inode for every file, directory, link and device, the directory listings that name them, and the lookup tables for fragments, NFS export and user and group ids, then the extended attributes.
To open a file by path, a reader takes the root inode from the superblock, reads that directory’s listing from the directory table, finds the next name, follows its reference to an inode, and so on to the file’s inode, which holds the size, the start of its data and the sizes of its blocks.
0Superblock magichsqs, counts, compressor, flags, the table offsets9696Compressor options when flag 0x400 is set10 or so…Data blocks and fragment blocks, each compressed alonevaries…Inode table, directory tablevaries…Fragment, export and id tables, xattr tablevariesbytes usedZero padding to a multiple of 4096varies
In the explorer
Drop a .squashfs, .sqsh or .sfs file on this site. The structure tree
covers every byte of the file: the superblock with a node for every field, the compressor options, the
data region (a node for each file with a node for each of its blocks, and for each fragment block), the
inode and directory tables as metadata blocks (the header and data of each), the fragment, export, id and
xattr tables with their pointer arrays, and the padding and anything appended after the filesystem. Tables
of everything are on the page:
- Files: every path of the tree, with its type, mode, owner, size, time, symbolic link target or device numbers and the fields of its inode. Regular files open as files of their own, decompressed on demand; a file of 64 MiB or more is read in windows, block by block, so a file of many gigabytes opens without reading the image whole. A file in a known format (a tar, a picture, a program) opens in that format’s viewer.
- Directory entries, Inodes and Directory indexes: every header and entry of the directory table (offset, inode delta, type, name), every inode in table order with all its fields, and every index entry, each checked against the listing it indexes.
- Fragments, Export table, Ids and Extended attributes: every entry, with the export table checked against the inodes and every attribute’s prefix, name and value, in line or out of line.
- Metadata blocks and Data blocks: every metadata block of every table (stored or compressed, sizes), and every data block of every file, the sparse blocks and the tails in fragments, each data block decoded to check it.
- Problems: a full pass over the image that lists everything wrong with it: bad offsets, a directory that contains itself, an inode that cannot be read, a block that does not decompress, an index entry that points nowhere. The listing, the tables and the file blocks are paged from checkpoints, so large images open at once and a damaged one is reported and shown as far as it reads, never hung on.
Both byte orders are read, and all six compressors: gzip, lzma, lzo, xz (with its branch filters), lz4 and zstd, with the decoders written for this site.
Not described
Checked against unsquashfs 4.7.5 on images made by mksquashfs 4.7.5 with every compressor,
block sizes from 4 KiB to 1 MiB and every -no… option (superblock, every listed path with type, mode,
owner, size and time, and every file’s bytes); big-endian images were made by converting those, because the tools
no longer read or write them.
Known, not yet covered
- Viewer: an image that sits inside another file (a Snap package, an AppImage, a firmware image) is read only from its first byte: the viewer does not search for it or take an offset. An image whose compressor is a vendor’s variant (the sasquatch LZMA forms, the LZO and LZMA variants of router firmware) is not recognised.
- Viewer: the data region draws one node for each file and fragment block, built when the node is opened; an image with millions of files makes that list long.
Unknown
- Reference and Viewer: no real big-endian version 4 image was available: the form is checked only against images converted from little-endian ones.
Variants
- SquashFS 4.0 filesystem – the current format: six compressors, extended attributes, an NFS export table, little- or big-endian
- SquashFS 3 filesystem – gzip only, bit-field inodes, fragments, sparse blocks, a lookup table for NFS (3.1)
- SquashFS 2 filesystem – fragments, no inode numbers or link counts
- SquashFS 1 filesystem – the first version: no fragments, 16-bit block sizes
Links
Software
- Squashfs-tools –
mksquashfsbuilds an image andunsquashfslists and extracts one (Linux, macOS) - squashfuse – mounts an image in user space (Linux, macOS)
- squashfs-tools-ng – a newer toolset that can pack, unpack and convert images (Linux, Windows)
- The Linux kernel – mounts an image directly, with gzip, lz4, lzo, xz and zstd (Linux)
Developers
- libsquashfs – library that reads and writes images (C)
- backhand – library and tools that read and write images (Rust)
- squashfs – library that reads images (Go)
- PySquashfsImage – library that reads images (Python)
Reference
- SquashFS binary format – Dr. David Alan Gilbert’s description of the on-disk format, in a maintained form
- SquashFS in the Linux kernel documentation – the filesystem, its compressors and options
- squashfs_fs.h in squashfs-tools – the structures as the tools define them