Skip to content

A simple, layered, asynchronous filesystem library.

License

Notifications You must be signed in to change notification settings

blajzer/laminaFS

Repository files navigation

LaminaFS

Description

LaminaFS is a simple, portable C/C++ filesystem abstraction layer designed to have a modern, asynchronous API while offering good performance and extensibility.

As its name might suggest, LaminaFS is designed as a virtual overlay filesystem. It allows for the mapping of physical device paths to virtual paths, where the virtual path mounts can overlap. A filepath is resolved from a virtual path to a physical path by matching in reverse mount order (newest mounts first) and against mount capabilities (read/write/delete/etc…​).

LaminaFS was originally designed for use in games, but is generic enough for other use cases. An example usage (from games) where LaminaFS really shines is in additive patching: the base data directory or archive is mounted first, and each patch contains only the files that have changed in that patch, mounted in order of release date. Due to the physical path resolution order, the most recent files will always be accessed first. This additionally enables user modding via always mounting a user data directory tree last.

License

LaminaFS is licensed under the MIT License. See the file LICENSE for more information.

Requirements

  • A C++ compiler supporting the C++17 standard

Building

It’s not necessary to build this library separately; the source can be directly integrated into other software just by copying and pasting the contents of the src/ directory and adding to the source tree.

Building this library and tests, requires a copy of dib. After acquiring dib, the command to build is just dib. This will build both the library and the test suite. I may also provide a simple Makefile in the future.

Doxygen is required to build the documentation. Just run it in the root directory to build the docs.

Usage

LaminaFS can be used through one of two include files:

#include <laminaFS.h> // C++ interface
#include <laminaFS_c.h> // C interface

The basic setup procedure is to create a context (either a FileContext, or lfs_context_t) and mount at least one device. The Directory device is at index 0 by default.

FileContext ctx(laminaFS::DefaultAllocator);

// resultCode will return LFS_OK on success
ErrorCode resultCode;
Mount mount = ctx.createMount(0, "/", "path/to/my/mount/on/disk", resultCode);

// The returned mount handle can be used to remove the mount later
ctx.releaseMount(mount);

Once a context and mount have been established successfully, file operations can be performed. All file operations will return a work item pointer (WorkItem or lfs_work_item_t). These are opaque handles to work items and there are static functions for getting information out of them. Before use, a work item must be checked for completion and waited on until it is finished. It is an error to attempt to read any information out of the work item before the completion status has been checked.

If a work item allocates memory, the associated buffer must be freed by the user by calling WorkItemFreeBuffer(). This function is null-safe, so it can be called regardless of the result of the operation.

Ultimately, a work item must be returned to the context through releaseWorkItem().

WorkItem *work = ctx.readFile("/some/file.txt", false);
WaitForWorkItem(work);

if (WorkItemGetResult(work) == LFS_OK) {
	uint64_t bytesRead = WorkItemGetBytes(work);
	void *buffer = WorkItemGetBuffer(work);

	// ... do something with the buffer here ...
}

WorkItemFreeBuffer(work);
ctx.releaseWorkItem(work);

About

A simple, layered, asynchronous filesystem library.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published