Skip to content

Axis-OC/axfs-fuse

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AXFS v2 — AxisOS Filesystem Driver

A cross-platform FUSE driver and reusable C library for mounting AXFS v2 filesystem images as native drives. Designed for AxisOS disk images from OpenComputers, but works with any AXFS v2 volume.

Transparently handles GZIP-compressed OpenComputers drive images, Amiga-style RDB partition tables with multiple AXFS partitions, and bare superblocks.

Z:\> dir
 Volume in drive Z is AXFS [AxisOS]

 Directory of Z:\

2025-06-14  12:30    <DIR>          bin
2025-06-14  12:30    <DIR>          etc
2025-06-14  12:30    <DIR>          lib
2025-06-14  12:30    <DIR>          var
               0 File(s)              0 bytes
               4 Dir(s)       1,331,200 bytes free

Features

  • Multi-partition auto-mount — scans RDB tables, assigns drive letters (Windows) or /tmp mount points (Linux) automatically
  • Read/write — full create, delete, rename, truncate support
  • GZIP transparency — detects .gz OC drive images, decompresses on load, recompresses on save
  • LRU inode cache — O(1) cached reads for recently accessed inodes (64 entries)
  • Path resolution cache — HashMap-backed path→inode cache, cleared on directory mutations
  • Extent-based allocation — coalesces consecutive blocks into extents, supports indirect blocks
  • Inline small files — files ≤52 bytes stored directly in the inode (zero data blocks)
  • Thread-safe — per-volume mutex, safe for concurrent FUSE access

Architecture

┌──────────────────────────────────────────────────────────┐
│                    axfs_fuse.c                           │
│              FUSE callbacks + mount logic                │
│         (WinFsp on Windows, libfuse on Linux)            │
├──────────────────────────────────────────────────────────┤
│                    axfs_lib.h / .c                       │
│           Filesystem library (transport-agnostic)        │
│    Superblock · Inodes · Dirs · Bitmaps · Path resolve   │
│         LRU inode cache · Path HashMap cache             │
├──────────────────────────────────────────────────────────┤
│                   ctemplates.h v2                        │
│           Compile-time generics for C                    │
│   Vec · HashMap · LRU · Bitset · SmallVec · Optional     │
│      Result · FixedString · Pair · CT_AUTOFREE           │
└──────────────────────────────────────────────────────────┘
File Purpose
ctemplates.h Type-safe generic containers via C preprocessor
axfs_lib.h Public API — types, constants, function declarations
axfs_lib.c Filesystem implementation — all logic lives here
axfs_fuse.c FUSE driver — mounts volumes, bridges OS ↔ library

Building

Windows (MSVC + WinFsp)

Prerequisites:

  • Visual Studio 2019+ with C11 support
  • WinFsp installed (default path assumed below)
cl /std:c11 /Zc:preprocessor /O2 axfs_fuse.c ^
    /I"C:\Program Files (x86)\WinFsp\inc\fuse" ^
    /link /LIBPATH:"C:\Program Files (x86)\WinFsp\lib" winfsp-x64.lib

Or use the included build script:

build_all.bat

Linux (GCC + libfuse)

Prerequisites:

  • GCC or Clang with C99+ support
  • libfuse 2.x development headers (apt install libfuse-dev)
gcc -std=c99 -O2 -o axfs_mount axfs_fuse.c \
    $(pkg-config fuse --cflags --libs) -lpthread

Usage

Auto-mount all partitions

axfs_mount drive.bin

Scans the image for an RDB partition table, discovers all AXFS v2 partitions, and mounts each one:

  • Windows: assigns free drive letters (Z:, Y:, ...)
  • Linux: creates mount points under /tmp/axfs_0_AxisOS/, etc.

Mount first partition to a specific location

# Windows
axfs_mount drive.bin Z:

# Linux
axfs_mount drive.bin /mnt/axfs

Mount a specific partition by sector offset

axfs_mount drive.bin 42 Z:

Unmount

Press Ctrl+C in the terminal, or:

# Linux
fusermount -u /mnt/axfs

# Windows — Ctrl+C or eject from Explorer

Changes are saved to the image file on unmount. GZIP images are recompressed automatically.


Disk Image Format

AXFS v2 is a simple extent-based filesystem designed for small virtual disks (64KB–4MB typical in OpenComputers).

Sector 0:     Primary superblock     ("AXF2" magic, version 2)
Sector 1:     Mirror superblock      (recovery copy)
Sector 2:     Inode bitmap           (1 bit per inode)
Sectors 3+:   Block bitmap           (1 bit per data block)
              Inode table            (80 bytes per inode)
              Data blocks            (extent-addressed)

Key parameters

Parameter Value
Magic AXF2 (4 bytes)
Inode size 80 bytes
Directory entry size 32 bytes
Max filename length 27 bytes
Max inline file size 52 bytes
Max direct extents 13 per inode
Indirect block support Yes (1 level)
Byte order Big-endian (Amiga heritage)

Inode types

Value Type
0 Free
1 File
2 Directory
3 Symlink

Cache System

The library includes two caches that mirror the Lua v3 implementation's CLOCK cache and path cache:

LRU Inode Cache

  • Capacity: 64 entries (configurable via AXFS_INODE_CACHE_SIZE)
  • Eviction: least-recently-used
  • Hit path: O(1) hash lookup → copy cached inode → return
  • Miss path: disk read → parse → insert into cache → return
  • Invalidation: axfs_write_inode deletes the entry for the written inode

Path Resolution Cache

  • Type: open-addressing HashMap (from ctemplates.h)
  • Key: fixed-length path string (up to 128 chars)
  • Value: inode number
  • Hit path: O(1) hash probe → return cached inode number
  • Invalidation: entire cache cleared on any dir_add or dir_remove

Monitoring

axfs_cache_stats_t stats = axfs_cache_stats(vol);
printf("Inode cache: %zu/%zu entries, %zu hits, %zu misses\n",
       stats.inode_entries, stats.inode_capacity,
       stats.inode_hits, stats.inode_misses);
printf("Path cache:  %zu entries, %zu hits, %zu misses\n",
       stats.path_entries, stats.path_hits, stats.path_misses);

ctemplates.h

A standalone header providing type-safe generic containers for C via preprocessor macro expansion. No dependencies beyond the C standard library.

Available Containers

Macro Generates
DEFINE_VEC(T) Growable dynamic array (Vec_T)
DEFINE_HASHMAP(K, V, h, eq) Open-addressing hash table
DEFINE_LRU(K, V, h, eq) Fixed-capacity LRU eviction cache
DEFINE_OPTIONAL(T) Nullable value wrapper
DEFINE_RESULT(T) Rust-style Result<T, int>
DEFINE_PAIR(A, B) Typed key-value pair
DEFINE_BITSET(Name, N) Compile-time fixed-size bit array
DEFINE_SMALLVEC(T, N) Stack-first small-buffer-optimized vector
DEFINE_FIXED_STRING(Name, N) Value-semantic fixed-capacity string

Quick Example

#include "ctemplates.h"

DEFINE_VEC(int)
DEFINE_HASHMAP(int, double, ct_hash_int, ct_eq_int)

int main(void) {
    Vec_int v = Vec_int_new();
    Vec_int_push(&v, 10);
    Vec_int_push(&v, 20);
    Vec_int_push(&v, 30);
    printf("len = %zu, back = %d\n", v.len, Vec_int_back(&v));
    Vec_int_free(&v);

    HashMap_int_double m = HashMap_int_double_new();
    HashMap_int_double_put(&m, 42, 3.14);
    double *val = HashMap_int_double_get(&m, 42);
    if (val) printf("42 -> %f\n", *val);
    HashMap_int_double_free(&m);
}

RAII Cleanup (GCC/Clang)

void process(void) {
    CT_AUTOFREE uint8_t *buf = malloc(4096);
    CT_AUTO_VEC(int) Vec_int v = Vec_int_new();
    Vec_int_push(&v, 1);

    if (error_condition)
        return;  // buf freed, v freed — automatically

    // ... more work ...
}  // buf freed, v freed — automatically

RDB Partition Table

AXFS images can contain an Amiga Rigid Disk Block partition table at sector 0. The driver scans this to discover multiple AXFS partitions within a single disk image.

Sector 0:        RDSK header (Rigid Disk Block)
Sectors 1-16:    PART entries (linked list, one per partition)
Sector N+:       Partition data (each contains its own AXFS superblock)

The driver recognizes AXFS partitions by their filesystem type ID: 0x41584632 ("AXF2" in ASCII).

If no RDB is found, the driver falls back to detecting a bare AXFS superblock at sector 0 or 1.


Relation to AxisOS

This driver is the host-side tooling for AxisOS, a security-focused operating system for OpenComputers (Minecraft mod). The Lua-side implementation (axfs_core.lua) runs inside the game and provides the same filesystem with additional features:

Feature C Library Lua v3
Inode cache LRU (64 entries) LRU-ish (48 entries)
Path cache HashMap Table-based
Dir cache Hash table per directory
Sector cache CLOCK algorithm (48 entries)
Block checksums CRC32 per block
Copy-on-Write Optional, crash-safe
Batch I/O Multi-sector reads

The C library focuses on correctness and FUSE integration. The Lua implementation adds caching layers appropriate for the constrained OpenComputers runtime (limited memory, coroutine-based I/O).


Troubleshooting

Windows: "Access denied" when deleting or copying files

The FUSE mount options must include uid=-1,gid=-1,umask=0 to bypass WinFsp's permission checking. This is already configured in the provided axfs_fuse.c. If you see permission errors, verify that mount_one() passes these options.

Windows: drive letter doesn't appear

  • Check that WinFsp is installed
  • Run the driver from an elevated (Administrator) terminal
  • Check stderr output for mount errors

Linux: "Transport endpoint is not connected"

The FUSE process crashed or was killed without unmounting:

fusermount -u /mnt/axfs

Image not saving changes

Changes are saved when the last mounted partition is unmounted (Ctrl+C or fusermount -u). If the process is killed with SIGKILL, changes are lost. Use SIGINT (Ctrl+C) or SIGTERM for clean shutdown.


License

i dont give a fuck

About

Simple AXFS v2 C FUSE driver for OpenComputers Axis OS. Handles Amiga RDB, but current can't see Ultravisor partition.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors