Keep versions. Store shared content once.
A copy-on-write Linux filesystem with inline deduplication, compression, snapshots, and an encrypted vault.
Manage it from a Qt Quick desktop app, or run it from the terminal through FUSE.
Why VerFSNext · Desktop app · Quick start · Terminal guide · Snapshots · Vault · Technical guide
Use your file manager, editor, and command-line tools as usual. VerFSNext mounts as a normal folder while storing its contents as deduplicated, compressed chunks in a separate data directory.
| What you want | What VerFSNext gives you |
|---|---|
| Less repeated data on disk | Inline UltraCDC chunking identifies shared content so duplicate chunks can reuse stored data. Chunk sizes are configurable. |
| Compression as you write | Zstandard compresses chunks before they reach storage, with a configurable compression level. |
| Earlier versions you can browse | Create read-only snapshots and open their files through .snapshots at the mount root. |
| Private files in their own space | The optional .vault namespace uses Argon2id key derivation and XChaCha20-Poly1305 authenticated encryption. It is hidden and inaccessible while locked. |
| A clear view of your storage | The desktop control center shows logical size, storage used, space savings, throughput, and detailed runtime statistics. |
| Your choice of workflow | A setup assistant and tray controls for your desktop; a CLI and systemd service for terminal and server use. |
Space savings depend on your data: repeated content benefits from deduplication, and compressible content benefits from Zstandard. Background garbage collection reclaims eligible unused storage while the filesystem is idle.
Project status: VerFSNext is a personal project used by its author for everyday data. It is not recommended for critical data; use it at your own risk.
The desktop app is included in the default build. Launch verfsnext with no
arguments to open the first-run assistant or return to the system tray.
- Choose whether VerFSNext should run as a background user service or only while the app is open. The user service needs no root privileges.
- Review the recommended settings, or customize them.
- Choose the VerFSNext folder you will use for your files and the separate data folder where VerFSNext stores metadata and packs.
- Finish setup. The filesystem starts, the window closes to the tray, and an applications-menu entry is added. Login startup is optional.
Click the tray icon to open the control center:
| Page | What you can do |
|---|---|
| Overview | Check whether the filesystem is running, inspect space savings and I/O statistics, open the mounted folder, and take a snapshot. |
| Snapshots | Create, browse, and delete snapshots without remembering CLI commands. |
| Vault | Create the encrypted vault, select its key file, unlock it, open it, and lock it again. |
| Folders & Startup | Review folder locations and choose how VerFSNext starts. |
| Settings | Adjust storage and resource settings; the app tells you when a restart is needed. |
The tray menu also opens the folder, takes a snapshot, starts or stops the filesystem, and quits. Closing the control window keeps the app in the tray. After setup, later launches start the filesystem and wait in the tray.
The app manages ~/.config/verfsnext/config.toml, the same configuration the
CLI can discover. A StatusNotifierItem system tray is required; GNOME
needs the AppIndicator extension. Background user-service mode also requires
systemctl --user.
Install Rust and the FUSE userspace tools for your distribution. The desktop
build also needs Qt 6 development packages and lld. On Debian, Ubuntu, or
Pop!_OS, the build and Qt dependencies are:
sudo apt install build-essential clang lld cmake pkg-config libdbus-1-dev \
qt6-base-dev qt6-base-dev-tools qt6-declarative-dev libqt6svg6 \
qml6-module-qtquick qml6-module-qtquick-controls qml6-module-qtquick-layouts \
qml6-module-qtquick-templates qml6-module-qtquick-window qml6-module-qtqml-workerscriptThen build and launch:
git clone https://github.com/jmarceno/VerFSNext.git
cd VerFSNext
cargo build --release
./target/release/verfsnextFollow the setup assistant and start using the mounted folder. Keep the executable at a stable location: desktop and service entries refer to it. The mounted folder is where you work with your files; the data directory contains VerFSNext's internal storage.
Build without the desktop app to omit Qt, D-Bus, and tray dependencies:
cargo build --release --no-default-featuresThen follow the terminal mount guide below.
A bare headless binary mounts the filesystem; a bare GUI-enabled binary opens
the desktop app. verfsnext mount explicitly chooses terminal mounting in
either build.
-
Set your paths in
config.toml:mount_point: existing mount directory (for example/mnt/verfs)data_dir: existing data directory (for example/mnt/work/verfs)- Optional mount behavior:
fuse_direct_io = trueto bypass kernel page cachefuse_fsname,fuse_subtypefor filesystem labeling/identityfuse_allow_other = trueto let other users access the mount (see below)
Who can access the mount. By default (
fuse_allow_other = false) only the user running the daemon can access the mounted filesystem; the kernel rejects everyone else, root included. No root privileges are needed to run or mount in this mode: the daemon uses the systemfusermounthelper, and you only need write access tomount_pointanddata_dir. Withfuse_allow_other = trueother users can access it too, subject to normal file permission bits, which the kernel enforces (default_permissionsis always set). A daemon not running as root then needsuser_allow_otherin/etc/fuse.conf(a one-time root change); without it the mount fails with an error that says so. The filesystem root directory is mode1777(like/tmp): with this option any local user can create entries at the top level, but only an entry's owner can delete or rename it. -
Start the filesystem daemon from the repo root:
./target/release/verfsnext mount
(A bare
./target/release/verfsnextopens the desktop app instead, unless it was built with--no-default-features.) Config resolution order is:./config.toml~/.config/verfsnext/config.toml/etc/verfsnext/config.tomlIf found by search, the CLI shows the selected file and asks for confirmation (auto-accept after 5 seconds).
You can bypass discovery and confirmation with an explicit config file:
./target/release/verfsnext --config /etc/verfsnext/config.toml # or ./target/release/verfsnext -c /etc/verfsnext/config.toml -
Use the mount normally:
ls -la /mnt/verfs cp /etc/hosts /mnt/verfs/hosts.copy
-
Unmount cleanly:
- Press
Ctrl+Cin the daemon terminal (or send it SIGTERM). - The process performs graceful shutdown and final sync before exit.
- Press
-
If a manual unmount is needed:
fusermount -uz /mnt/verfs
Use snapshots through the control CLI:
# Create
./target/release/verfsnext snapshot create snap1
# List
./target/release/verfsnext snapshot list
# Delete
./target/release/verfsnext snapshot delete snap1To force a specific config file for any control command:
./target/release/verfsnext --config /etc/verfsnext/config.toml snapshot listMounted snapshot view:
- Snapshot roots appear under
/.snapshotsand can be accessed like normal directories.
Read live runtime/internal statistics from the mounted daemon through the control socket:
./target/release/verfsnext statsStats namespace behavior:
- Live logical size excludes
/.snapshots. - If vault is locked, live logical size also excludes hidden
/.vaultand reports it separately as hidden vault logical size. - The report includes metadata consistency checks (chunk refcount mismatches, missing chunk records, orphan extents).
/.vault is a reserved encrypted namespace at filesystem root.
- Not created automatically
- Hidden/inaccessible while locked
- Visible and usable only when unlocked
./target/release/verfsnext crypt -c -p "your-password" -path /secure/key/dir- Creates
verfsnext.vault.key(mode0600) in the provided directory. Theverfsnextcommand you run writes it, so it belongs to you even when the daemon runs as another user (e.g. theverfsservice user). An existing key file is never overwritten; if creating the vault fails, the new key file is removed. - Creates
/.vaultmetadata in the filesystem, with/.vault(mode0700) owned by the user who ran the command
If -path is omitted, the key is created in the current working directory.
Losing the key file means losing access to the vault: keep a copy somewhere safe.
./target/release/verfsnext crypt -u -p "your-password" -k /secure/key/dir/verfsnext.vault.keyThe command reads the key file as you and sends its content to the daemon over the control socket; the daemon never opens your key file. After unlock .vault becomes visible and accessible for normal file operations. The vault remains unlocked and usable until a lock command is issued or the daemon is restarted.
./target/release/verfsnext crypt -lAfter lock:
/.vaultdisappears from directory listings- Direct access to
/.vault/*fails until next unlock
To migrate to a new pack size:
./target/release/verfsnext pack-size-migrateNotes:
- This command must run while the daemon is stopped.
- It rewrites all packs and updates chunk metadata pack mappings.
- Old packs are moved to a backup directory under
data_dir; remove that backup only after validation. - Every stored copy of a chunk is migrated, and all copies of one chunk land in the same new pack, which may then exceed the new size target.
Use this when you want to rebuild .DISCARD from scratch (instead of relying on the existing file), for example after large deletions or to catch data left behind by a previous GC run.
# Rebuild .DISCARD only
./target/release/verfsnext gc offline
# Rebuild .DISCARD and immediately run the pack-rewrite GC phase
./target/release/verfsnext gc offline --runNotes:
- This command must run while the daemon is stopped.
gc offline --runthen only runs the second GC phase (pack rewrite), because the discard list was just rebuilt.- Pack rewrite decisions still honor
gc_pack_rewrite_min_reclaim_bytesandgc_pack_rewrite_min_reclaim_percentfromconfig.toml. - Before rebuilding the discard list, the command deletes every chunk record whose refcount is 0 (the work of the online GC scan phase, which it otherwise skips), so
--runreclaims chunks of files deleted since the last online scan as well. This is safe only because the daemon is stopped.
This is the system-wide service (runs as user verfs, needs root to install). For a personal setup without root, use the desktop app's background user service instead.
-
Install everything (build, binary, user, config, mount/data dirs, unit, enable/start). The installer builds the headless binary (
--no-default-features), so the server needs no Qt:./contrib/systemd/verfsnext-service.sh install
The installer also adds the invoking user to group
verfsand prints a highlighted reminder that control commands requireverfsgroup membership (newgrp verfsor re-login required). The control socket (<data_dir>/verfsnext.sock) is mode0660, owned byverfs:verfs; only members of groupverfscan run snapshot, crypt and stats commands against the service. The service starts with--config /etc/verfsnext/config.toml. The service runs as userverfs, so the installer setsfuse_allow_other = truein a newly installed config and addsuser_allow_otherto/etc/fuse.confwhen it is missing. An existing config is left as is, except that a config written before the option existed getsfuse_allow_other = trueadded (byinstalland byupdate-bin), which keeps the previous behavior. If you set it tofalse, only theverfsuser can access the service mount. -
If already installed, update only the executable:
./contrib/systemd/verfsnext-service.sh update-bin
-
Preview actions without changing the system:
./contrib/systemd/verfsnext-service.sh --dry-run install
-
Useful commands:
sudo systemctl status verfsnext sudo journalctl -u verfsnext -f sudo systemctl restart verfsnext sudo systemctl stop verfsnext
-
Uninstall service artifacts (keeps
data_diruntouched):./contrib/systemd/verfsnext-uninstall.sh
If startup fails with FUSE permission errors, verify /dev/fuse access and that the fuse group exists.
VerFSNext is the public release of a project I've been developing for years. It began with my curiosity about storage appliances in 2011, followed by the first Python implementation in 2015. Around 2020, a later version added features including replication; that iteration is archived as VerFS.
After further iterations, VerFSNext focuses on the features that make sense for my daily use.
Over the years, I've tried many metadata databases and FUSE bindings, and
implemented metadata storage from scratch. The internal forks of
async_fusex and surrealkv let me change the filesystem interface and
storage engine together as the project evolves.
- Technical deep dive — storage layout, write and read paths, snapshots, vault, garbage collection, and the desktop architecture.
- Bug-fix history — fixes, their impact, and regression context.
- Resilience validation — workload and fault-injection procedures, scope, and recorded results.
- Configuration example — annotated storage, cache, FUSE, and vault settings.
VerFSNext is released under the Apache License 2.0.
Have an idea or found a bug? Open an issue with your setup, what happened, and the relevant logs. If VerFSNext is useful to you, a star helps other Linux users discover it.