A hybrid filesystem framework that blends BTRFS and DwarFS into a unified namespace, combining BTRFS's mutable Copy-on-Write semantics with DwarFS's extreme compression ratios (10–16×).
Two technologies, two strengths:
| BTRFS | DwarFS | |
|---|---|---|
| Mode | Read/write | Read-only |
| Storage | Block device | Single image file |
| Snapshots | Native CoW subvolumes | N/A |
| Compression | Transparent, per-block | 10–16× via similarity hashing |
| Use case | Live, active data | Archival, read-mostly data |
This framework bridges them with two partition types and a blend layer:
Stores BTRFS subvolumes and snapshots as compressed .dwarfs image files. A BTRFS subvolume is exported via btrfs send | btrfs receive | mkdwarfs into a single self-contained image. Ideal for archiving versioned data at maximum compression.
Stores .dwarfs image files on a live BTRFS filesystem. The images gain BTRFS's CoW semantics (no partial-write corruption), per-file checksumming, and snapshot capability — so you can take point-in-time snapshots of entire image collections.
Merges a BTRFS upper layer and one or more DwarFS lower layers into a single coherent namespace. Reads fall through from BTRFS to DwarFS; writes always land on BTRFS with automatic copy-up.
┌──────────────────────────────────────────────┐
│ Blend Namespace │
│ /mnt/blend/ │
│ │
│ READ: BTRFS upper → DwarFS lower fallback │
│ WRITE: always to BTRFS upper (copy-up) │
└──────────┬───────────────────────┬───────────┘
│ │
┌────────▼────────┐ ┌──────────▼──────────┐
│ BTRFS Upper │ │ DwarFS Lower(s) │
│ (writable) │ │ (compressed) │
└─────────────────┘ └─────────────────────┘
Promote — extract a DwarFS-backed path into a writable BTRFS subvolume.
Demote — compress a BTRFS subvolume into a DwarFS image, optionally deleting the subvolume to reclaim space.
btrfs-dwarfs-framework/
├── include/
│ ├── btrfs_dwarfs/types.h # Shared type definitions
│ └── uapi/bdfs_ioctl.h # Kernel↔userspace ioctl interface (18 ioctls)
│
├── kernel/
│ └── btrfs_dwarfs/
│ ├── bdfs_main.c # Module init, /dev/bdfs_ctl, partition registry
│ ├── bdfs_blend.c # bdfs_blend VFS type, unified namespace
│ ├── bdfs_btrfs_part.c # BTRFS-backed partition backend
│ ├── bdfs_dwarfs_part.c # DwarFS-backed partition backend
│ ├── bdfs_internal.h # Internal kernel declarations
│ ├── Kbuild # Kernel build rules
│ └── Kconfig # Kernel config options
│
├── userspace/
│ ├── daemon/
│ │ ├── bdfs_daemon.c # Lifecycle, worker pool, main loop
│ │ ├── bdfs_exec.c # mkdwarfs/dwarfs/btrfs tool wrappers
│ │ ├── bdfs_jobs.c # Job handlers (export/import/mount/snapshot)
│ │ ├── bdfs_netlink.c # Netlink event listener
│ │ └── bdfs_socket.c # Unix socket server for CLI
│ ├── cli/
│ │ ├── bdfs_main.c # Entry point, global options, dispatch
│ │ ├── bdfs_partition.c # partition add/remove/list/show
│ │ ├── bdfs_export_import.c # export, import
│ │ ├── bdfs_mount.c # mount, umount, blend mount/umount
│ │ ├── bdfs_snapshot_promote_demote.c # snapshot, promote, demote
│ │ └── bdfs_status.c # status
│ └── CMakeLists.txt
│
├── tests/
│ ├── integration/ # Loopback-device test suites (requires root)
│ │ ├── lib.sh # Shared helpers, loopback setup, assertions
│ │ ├── test_dwarfs_partition.sh
│ │ ├── test_btrfs_partition.sh
│ │ ├── test_blend_layer.sh
│ │ ├── test_snapshot_lifecycle.sh
│ │ └── run_all.sh
│ └── unit/ # Unit tests (no root required)
│ ├── test_uuid.c
│ ├── test_compression.c
│ └── test_job_alloc.c
│
├── configs/
│ ├── bdfs.conf # Framework configuration
│ └── bdfs_daemon.service # systemd service unit
│
├── doc/
│ ├── architecture.md # Detailed architecture and data flow diagrams
│ ├── bdfs.1 # CLI man page
│ └── bdfs_daemon.8 # Daemon man page
│
└── Makefile # Top-level build (kernel + userspace)
| Tool | Purpose |
|---|---|
| Linux kernel headers ≥ 5.15 | Kernel module build |
btrfs-progs |
btrfs send/receive/snapshot/subvolume |
mkdwarfs |
DwarFS image creation |
dwarfs (FUSE3) |
DwarFS image mounting |
dwarfsextract |
DwarFS image extraction |
dwarfsck |
DwarFS image verification |
| CMake ≥ 3.16 | Userspace build |
| pthreads | Daemon worker pool |
Install DwarFS tools from mhx/dwarfs releases (pre-built static binaries available for most architectures).
# Kernel module + userspace (daemon + CLI)
make all
# Kernel module only
make kernel KDIR=/lib/modules/$(uname -r)/build
# Userspace only
make userspace
# Install (requires root for kernel module)
sudo make install
# Load the kernel module
sudo insmod kernel/btrfs_dwarfs/btrfs_dwarfs.kocmake -S userspace -B build \
-DBUILD_DAEMON=ON \
-DBUILD_CLI=ON \
-DBUILD_TESTS=OFF \
-DENABLE_ASAN=OFF \
-DCMAKE_INSTALL_PREFIX=/usr/local
cmake --build build --parallelsudo systemctl start bdfs_daemon
# or in the foreground for debugging:
sudo bdfs_daemon -f -v# DwarFS-backed: stores BTRFS snapshots as compressed images
bdfs partition add \
--type dwarfs-backed \
--device /dev/sdb1 \
--label archive \
--mount /mnt/archive
# BTRFS-backed: stores DwarFS image files with CoW + checksums
bdfs partition add \
--type btrfs-backed \
--device /dev/sdc1 \
--label images \
--mount /mnt/images# Find the subvolume ID
btrfs subvolume list /mnt/data
# Export it (creates a read-only snapshot, runs mkdwarfs, cleans up)
bdfs export \
--partition <dwarfs-backed-uuid> \
--subvol-id 256 \
--btrfs-mount /mnt/data \
--name myapp_v1 \
--compression zstd \
--verifybdfs mount \
--partition <dwarfs-backed-uuid> \
--image-id 1 \
--mountpoint /mnt/myapp_v1 \
--cache-mb 512bdfs import \
--partition <btrfs-backed-uuid> \
--image-id 1 \
--btrfs-mount /mnt/data \
--subvol-name myapp_restored# Point-in-time CoW snapshot of the subvolume holding the image file
bdfs snapshot \
--partition <btrfs-backed-uuid> \
--image-id 1 \
--name images_snap_20250101 \
--readonlybdfs blend mount \
--btrfs-uuid <uuid> \
--dwarfs-uuid <uuid> \
--mountpoint /mnt/blend \
--writeback# Promote: make a DwarFS-backed path writable (extract to BTRFS subvolume)
bdfs promote \
--blend-path /mnt/blend/myapp \
--subvol-name myapp_live
# Demote: compress a BTRFS subvolume to DwarFS and reclaim space
bdfs demote \
--blend-path /mnt/blend/myapp_live \
--image-name myapp_archived \
--compression zstd \
--delete-subvolbdfs status
bdfs status --partition <uuid>
bdfs status --jsonTests run against loopback devices — no real block devices needed. Prerequisites are checked per-suite; missing tools cause a graceful skip rather than a failure.
sudo make test
# or directly:
sudo bash tests/integration/run_all.shSuites:
test_dwarfs_partition.sh— export pipeline, compression ratio, FUSE mount, integrity, read-only enforcementtest_btrfs_partition.sh— image storage, CoW semantics, snapshot independence, import pipeline, scrubtest_blend_layer.sh— read routing, copy-up on write, promote/demote, round-trip integritytest_snapshot_lifecycle.sh— incremental snapshot chains, independent image mounts, size progression
make check
# runs: test_uuid, test_compression, test_job_allocSee doc/architecture.md for component diagrams and full data flow for the export and import pipelines.
Man pages:
man doc/bdfs.1
man doc/bdfs_daemon.8- Blend layer whiteouts not implemented. The
bdfs_blendVFS type handles reads, writes, copy-up, promote, and demote. Whiteout entries (deletion of lower-layer files from the upper layer) are not yet implemented — deleting a file that exists only in a DwarFS lower layer will return EPERM.
GPL-2.0-or-later. See individual file headers.
- kdave/btrfs-devel — BTRFS kernel development tree
- mhx/dwarfs — DwarFS compressed filesystem