← Slim64FS
Slim64FS — Full
Specifications and Limits
Format version: 0x00090002
License: MIT
Author: Albert Yang / 64-4 Systems
1. Storage Layout
| Block size |
4,096 bytes |
Fixed; no alternative sizes |
| Block header |
8 bytes |
Magic + CRC32C per block |
| Block usable data |
4,088 bytes |
4,096 − 8 |
| Superblock location |
Block 0 |
Always |
| Bitmap location |
Block 1 |
Primary allocation bitmap |
| Inode table location |
Block 2 |
Starts at block 2 |
| Commit block A |
Block N |
Dual-slot commit |
| Commit block B |
Block N+1 |
Shadow commit slot |
| Transaction block |
Block N+2 |
W7 recovery anchor |
| Shadow bitmap |
Blocks N+3 … |
CRC-verified shadow |
| Shadow inode table |
Follows shadow bitmap |
CRC-verified shadow |
| Data region start |
After all metadata |
Variable; depends on volume size |
2. Volume Limits
| Maximum volume size |
8 EiB (2⁶³ − 1 bytes) |
Bounded by off_t on 64-bit Linux |
| Maximum block count |
2,251,799,813,685,247 (≈ 2.25 × 10¹⁵) |
total_blocks field: uint64_t |
| Minimum volume size |
~288 KiB |
Enough for all metadata + 1 data block |
| Inode density |
1 inode per 64 KiB of volume |
Set at format time; not tunable |
| Maximum inode count |
140,737,488,355,327 (≈ 140 trillion) |
For maximum 8 EiB volume |
| Minimum inode count |
4,096 |
Enforced floor regardless of volume size |
| Volume geometry |
Fixed at mkfs time |
Cannot be resized after format |
Inode density formula:
inode_count = volume_bytes / 65,536
3. File Limits
| Maximum file size (format field) |
18,446,744,073,709,551,615 bytes (16 EiB) |
inode.size: uint64_t |
| Maximum file size (contiguous) |
Volume size − metadata |
1 extent covering all data blocks |
| Maximum file size (258 single-block extents) |
1,054,704 bytes (~1 MiB) |
Pathological fragmentation worst case |
| Maximum extents per file |
258 |
3 inline + 255 overflow |
| Block allocation unit |
4,096 bytes |
One block at a time or as contiguous runs |
| Sparse files |
Not supported |
All blocks allocated on write |
| File data per block |
4,088 bytes |
8-byte header reserved for format use |
| Hard links to regular files |
Not supported |
Returns EOPNOTSUPP |
| Symbolic links |
Supported |
Target stored as file data |
Extent model: Slim64FS tracks contiguous block runs
(extents). A file written sequentially uses 1 extent regardless of size.
Fragmentation accumulates extents; at 258 extents the file cannot be
extended further. Camera and video workloads (large sequential writes to
fresh media) almost never exceed single-digit extents.
4. Directory Limits
| Maximum directory depth |
16 |
Writer-enforced: mkdir at depth 17 fails
ENAMETOOLONG (S64_DIR_DEPTH_MAX, root children
= depth 1). Readers tolerate deeper trees on foreign images. See note
below. |
| Maximum entries per directory |
Bounded by inode count |
No per-directory hard limit |
| Directory entry overhead |
12 bytes + filename length + 1 (NUL) |
ino(8) + reclen(2) + namelen(1) + type(1) + name |
| Minimum directory entry |
14 bytes |
1-character filename |
| Maximum directory entry |
268 bytes |
255-character filename |
| Directory size on disk |
Multiple 4,096-byte blocks |
Tracked by extent map like regular files |
| Empty directory minimum size |
1 block (4,096 bytes) |
Always allocates at least one block |
Depth-cap semantics (writer MUST / reader
SHOULD-tolerate). Slim64FS never creates a directory
deeper than 16 (mkdir → ENAMETOOLONG), so
embedded implementations may size fixed 16-slot traversal stacks for
slim64fs-written media. Readers (mount, fsck, salvage) tolerate deeper
trees found on foreign or hostile images — traversal is iterative and
cycle-guarded, never depth-limited — so a nonconforming card stays
recoverable. The number 16 is also the physical ceiling implied by the
kernel's PATH_MAX (~4,096 bytes) at maximum name length: 16
× (255 + 1) ≈ 4 KB. One known writer-side edge is enshrined, not
enforced: rename can move an existing subtree under a deep
parent such that descendants exceed 16 (see
known-limitations.html).
5. Naming
| Maximum filename length |
255 bytes |
S64_NAME_MAX; raw bytes, not characters |
| Filename encoding |
Any byte sequence except / and NUL |
UTF-8 recommended, not enforced; //NUL rejected by
on-disk dirent validation (V14.1) |
| Case sensitivity |
Case-sensitive |
Byte-exact comparison |
| NUL character in names |
Not permitted |
C string convention |
| Path separator |
/ |
Standard POSIX |
| Reserved names |
. and .. |
Synthesized; not stored on disk |
| Maximum symlink target length |
4,095 bytes |
Limited by POSIX PATH_MAX; not slim64fs itself |
| Inode number |
uint64_t |
1 … inode_count |
0 is invalid/unallocated |
| File size |
uint64_t |
0 … 2⁶⁴ − 1 bytes |
|
| UID |
uint32_t |
0 … 4,294,967,295 |
Standard POSIX UID |
| GID |
uint32_t |
0 … 4,294,967,295 |
Standard POSIX GID |
| Permissions |
uint16_t |
Standard POSIX mode bits |
rwxrwxrwx + type bits |
| Hard link count |
uint16_t |
0 … 65,535 |
Directories track subdirectory count |
| Access time (atime) |
uint64_t seconds |
0 … 2⁶⁴ − 1 |
1-second precision; year ~584 billion max |
| Modification time (mtime) |
uint64_t seconds |
0 … 2⁶⁴ − 1 |
1-second precision |
| Change time (ctime) |
uint64_t seconds |
0 … 2⁶⁴ − 1 |
1-second precision |
| Block number |
uint64_t |
0 … total_blocks − 1 |
|
| Inode size on disk |
128 bytes |
Fixed |
S64_INODE_SIZE |
| Inodes per block |
32 |
Fixed |
4,096 / 128 |
Timestamp note: atime, mtime, ctime are stored as
seconds since the Unix epoch. Sub-second precision is not recorded.
atime is not updated on read (equivalent to noatime mount
behavior).
7. Integrity Model
| Checksum algorithm |
CRC32C (hardware-accelerated on modern CPUs and ARM) |
| Checksum coverage |
Bitmap, inode table, shadow bitmap, shadow inode table, commit
block, superblock |
| Checksum granularity |
Entire structure (not per-block streaming) |
| Dual-slot commit |
Yes — commit blocks A and B; generation counter selects winner |
| Shadow structures |
Yes — shadow bitmap + shadow inode table, CRC-verified on mount |
| Journal |
None — anticipatory sequencing provides equivalent safety at zero
overhead |
| Recovery |
Mount reads both commit slots, selects highest valid generation;
shadow structures verify clean checkpoint |
8. What Slim64FS Does Not
Support
| Hard links (regular files) |
EOPNOTSUPP |
Simplicity; namespace DAG becomes a graph; deferred |
| Compression |
Not implemented |
Target media (JPEG, MP4) is already compressed |
| Encryption |
Not implemented |
Out of scope; CRC is integrity, not confidentiality |
| Extended attributes (xattr) |
Not implemented |
Deferred |
| ACLs |
Not implemented |
Deferred |
| Journaling |
By design |
FTL handles atomic writes; journal adds write amplification |
| Quotas |
Not implemented |
Deferred |
| Sub-second timestamps |
Not recorded |
1-second precision matches camera metadata requirements |
| atime updates on read |
Not implemented |
Equivalent to noatime; preserves flash endurance |
| Volume resize |
Not supported |
Geometry fixed at format time |
| Sparse file holes |
Not supported |
All regions fully allocated |
| Directory hard link count > inode_count |
Impossible |
Bounded by volume |
S64_SUPER_MAGIC |
0x534C363446533100 |
Superblock magic "SL64FS\0" |
S64_COMMIT_MAGIC |
0x533634434D543100 |
Commit block magic "S64CMT\0" |
S64_SUPER_VERSION |
0x00090002 |
Current format version (V9.2) |
S64_BLOCK_SIZE |
4096 |
Bytes per block |
S64_BLOCK_HDR_SIZE |
8 |
Block header bytes |
S64_INODE_SIZE |
128 |
On-disk inode bytes |
S64_NAME_MAX |
255 |
Max filename bytes |
S64_EXT_INLINE_MAX |
3 |
Inline extents in inode reserved region |
S64_EXT_OVERFLOW_MAX |
255 |
Additional extents in overflow block |
S64_EXT_TOTAL_MAX |
258 |
Total extents per file |
| USB flash drive |
Samsung FIT |
119.5 GB |
✅ PASS (V9.2) |
| SD card |
UHS-I |
119.1 GB |
✅ PASS (V12.0) |
| Portable SSD |
WD Black SN850X (USB NVMe) |
4 TB |
✅ PASS (V12.2) |
| CFexpress Type B |
— |
— |
⚠️ Not tested (no hardware) |
11. Partition Identity
Slim64FS publishes both a modern GPT identity and a legacy MBR
hint:
| GPT partition type GUID |
64646464-6464-4464-8464-82F63B786464 |
Canonical partition identity |
| MBR partition type byte |
0x64 |
Legacy compatibility hint |
Identity precedence
Partition IDs are partition-table metadata. Filesystem truth is
validated by Slim64FS superblock magic/version
(S64_SUPER_MAGIC, S64_SUPER_VERSION).
If partition-table ID and superblock disagree:
- superblock validation decides mount/probe behavior,
- partition ID is treated as advisory labeling only.
Operational guidance
- Prefer GPT GUID for new media.
- Use MBR
0x64 only when legacy MBR partitioning is
required.
- Always verify with both partition tools
(
lsblk/blkid) and Slim64FS tools
(slim64fs-info, slim64fs-check).