# linux-apfs-rw mounts an Apple filesystem on Linux, read-only by default

> linux-apfs-rw is an out-of-tree kernel module that mounts APFS volumes on Linux, with write support that the README explicitly calls experimental and risky enough that mounts default to read-only. It is the result of reverse engineering, works on kernels since 4.12, and has no encryption support at all.

**linux-apfs/linux-apfs-rw** — APFS module for linux, with experimental write support

- Repository: https://github.com/linux-apfs/linux-apfs-rw
- Stars: 807 · Forks: 54
- Language: C
- License: GPL-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/linux-apfs-linux-apfs-rw

## The module is a reverse engineering result, and it says so

APFS is the copy-on-write filesystem used on all Apple devices, and linux-apfs-rw brings a degree of experimental support for it to Linux. The README is unusually direct about the provenance: the module is the result of reverse engineering and testing has been limited. The work was first based on reverse engineering done by others, and later on the official specification, which is described as very incomplete.

The references are named. The base reverse engineering is the paper Decoding the APFS file system by Hansen and Toolan, and the apfs-fuse project by sgan81. The specification reference is Apple's own APFS Reference document.

The code borrows from elsewhere too. Some parts imitate the ext2 module, and to a lesser degree xfs, udf, gfs2 and hfsplus. That is a useful signal about the shape of the implementation, since a filesystem driver modelled on ext2 inherits ext2's ideas about superblocks, inodes and directory handling.

Original authorship is Ernesto A. Fernández, with contributions from Gabriel Krisman Bertazi, Arnaud Ferraris and Stan Skowronek. The attribution details are in the historical git tree at the older eafer/linux-apfs repository. The licence is GPL-2.0, and the last push was on 2026-10-16 with release v0.3.22 dated 2026-10-13.

## Writes are behind a mount option and a compile flag, and default to off

Write support is the headline feature and also the main risk. The README states that if you make use of the write support there is a real risk of data corruption, so mounts are read-only by default.

There are two ways to change that. At mount time, the `readwrite` option enables the experimental write support, with the warning that this may corrupt your container, especially if your kernel does not use 4 KiB pages. At build time, the Makefile documents a way to make mounts writable by default:

```bash
make APFS_CONFIG=-DCONFIG_APFS_RW_ALWAYS
```

The Makefile comment itself says this is risky and not generally recommended.

The page size warning is worth taking seriously. APFS containers from Apple hardware typically use larger pages than a stock Linux kernel, and a mismatch there is exactly the kind of thing that produces silent corruption rather than a clean error.

Two other write-related limits are stated plainly. Writes to fusion drives will likely never be supported, though the author says he might reconsider if people actually need it. And encryption is not implemented even in read-only mode, which means an encrypted APFS container is simply out of reach for this module.

## Building it out of tree, with distro packages as the easier route

The README suggests a shortcut before anything else. The driver has been packaged for several distributions, so it may be more convenient to install from there instead of building it yourself, though the distro packages are often outdated, so the version is worth checking.

To build from source you need the Linux kernel headers first, and the README lists the commands per distribution family. On Debian and Ubuntu:

```bash
apt-get install linux-headers-$(uname -r)
```

On Arch and Manjaro:

```bash
pacman -Sy linux-headers
```

On RHEL, Rocky, CentOS and Fedora:

```bash
yum install kernel-headers kernel-devel
```

Then you change into the linux-apfs-rw directory and build:

```bash
make
```

The result is the apfs.ko file, which has to be inserted into the kernel before use:

```bash
insmod apfs.ko
```

If that fails with an unknown symbol in module error, the README has a specific remedy:

```bash
modprobe libcrc32c
```

and then you try the insmod command again.

The Makefile itself shows the structure. It is a standard out-of-tree module build with KERNELRELEASE defaulting to the running kernel and KERNEL_DIR pointing at /lib/modules/$(KERNELRELEASE)/build, and the module sources are assembled from the C files in the tree, including the LZFSE decoder objects under lzfse/. There is also a dkms.conf in the repository root, which is the route to a package that rebuilds against a new kernel.

## Mount options decide which volume and which snapshot you see

The mount command follows the usual filesystem shape, with the device and the mount point:

```bash
mount [-o options] device dir
```

The options list is short and each one maps to a specific APFS concept. `vol=n` selects the volume number, defaulting to volume 0. `snap=label` mounts a named volume snapshot, and only in read-only mode. `tier2=path` gives the path to the tier 2 device, which applies to fusion drives only. `uid=n, gid=n` overrides the on-disk inode ownership data. `cknodes` verifies the checksum on all metadata nodes, and the README warns that this has a severe performance cost so it is not recommended. `readwrite` turns on the experimental write support.

The example in the documentation combines two of them, mounting volume 2 with metadata checking:

```bash
mount -o cknodes,vol=2 device dir
```

Unmounting uses the ordinary command:

```bash
umount dir
```

For debugging, the README asks you to run this first whenever something goes wrong:

```bash
dmesg | grep -i apfs
```

The suggestion is to file a GitHub issue at the eafer/linux-apfs-rw repository if that output does not help, or to send an email.

## Kernel coverage is broad, but the testing focus is narrow

The compatibility statement has two halves, and the difference between them matters. The module is intended to work with all kernel versions since 4.12, but testing is focused on 5.18 and above.

So the honest read is that a large version range is claimed as supported, and a much smaller range is actually exercised. For a filesystem driver, that gap is worth respecting. The tree itself shows how much surface there is, with separate C files for the btree, compress, directory, extents, file, inode, key, namei, node, object, snapshot, spaceman, super, symlink, transaction, unicode, xattr and xfield handling, plus the LZFSE compression decoder and a bitmap helper.

The compression directory is worth noting, since it explains the lzfse objects in the Makefile. APFS containers from Apple hardware use LZFSE compression for some metadata and file data, and without a decoder the volume would not mount cleanly.

The kernel version range also interacts with the write support, because the 4 KiB page warning only matters if your kernel actually uses 4 KiB pages. A kernel configured for larger base pages changes the risk profile of the readwrite option.

There is also a companion project for testing write support. A set of userland tools is under development, and the README gives its git tree location at the eafer/apfsprogs repository. That is the practical way to exercise the write path, rather than pointing a valuable filesystem at it and hoping.

## The practical use is reading Apple volumes for recovery and inspection

Given that encryption is absent, fusion drive writes are unlikely to be supported, and corruption is a documented outcome of writing, the realistic deployment is read-only access to an unencrypted APFS container.

That still covers real work. Reading an APFS volume from Linux is what you need when a Mac disk has failed, when you are migrating data off Apple hardware, when you are analysing media in a forensic workflow, or when you want to inspect a container image without booting macOS. The `snap=label` option extends this to reading a specific snapshot rather than the live volume, which is valuable precisely because a snapshot is immutable.

The metadata structures are documented in enough detail to make the module interesting to read, with apfs.h, apfs_raw.h and separate object, node, spaceman and xfield handling, and the README notes that the work was later based on the official specification, so it is also a reference implementation of how the on-disk structures fit together.

The project's own caveat remains the right frame for any of this. Testing has been limited, mounts are read-only by default, and issues are welcome at the issue tracker. That combination makes linux-apfs-rw a tool for careful, copy-first workflows rather than a filesystem to mount and start writing to.

## Conclusion

Adopt linux-apfs-rw if you need read access to an APFS container on Linux for forensics, recovery or migration work, and you can accept that the filesystem is undocumented, the module is out-of-tree, and encryption is unsupported. Skip it if the volume is encrypted, if it lives on a fusion drive and you intend to write, or if you need a filesystem you can trust with writes on a production machine. Verify first that your kernel is 5.18 or above, the version range where testing is focused, and that the mount stays read-only until you have a copy of the data, because the README states there is a real risk of data corruption.

## FAQ

### How do I mount an APFS volume on Linux with linux-apfs-rw?

Build the module with `make` to produce apfs.ko, insert it with `insmod apfs.ko`, and mount with `mount [-o options] device dir`. Use `vol=n` to pick a volume number and `snap=label` to mount a snapshot, which works only in read-only mode.

### Is write support safe to use on linux-apfs-rw?

The README calls it experimental and states there is a real risk of data corruption, which is why mounts are read-only by default. The `readwrite` mount option may corrupt the container, especially if your kernel does not use 4 KiB pages, and the Makefile offers a build flag for writable-by-default mounts that it calls risky and not generally recommended.

### Can linux-apfs-rw read encrypted APFS containers?

No. The README states that encryption is not yet implemented even in read-only mode. It also says writes to fusion drives will likely never be supported.

### Which kernel versions does linux-apfs-rw support?

It is intended to work with all kernel versions since 4.12, but the README says testing is focused on 5.18 and above.

## Sources

- [Issues](https://github.com/linux-apfs/linux-apfs-rw/issues)
- [License: GPL-2.0](https://github.com/linux-apfs/linux-apfs-rw/blob/master/LICENSE)
- [linux-apfs/linux-apfs-rw on GitHub](https://github.com/linux-apfs/linux-apfs-rw)
- [README](https://github.com/linux-apfs/linux-apfs-rw/blob/master/README.md)
- [Releases](https://github.com/linux-apfs/linux-apfs-rw/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/linux-apfs-linux-apfs-rw
