> ## Documentation Index
> Fetch the complete documentation index at: https://kernel.mvhcloud.com/llms.txt
> Use this file to discover all available pages before exploring further.

# RAMFS Filesystem API — Low-Level FS Functions in MVH Kernel

> Reference for the MVH Kernel RAMFS API: fs_init, fs_chdir, fs_pwd, fs_list, fs_mkdir, fs_touch, fs_write, fs_read, fs_remove. Prefer vfs_* for general use.

The RAMFS (RAM filesystem) implements the low-level filesystem layer inside MVH Kernel. It stores all files and directories in kernel-managed heap memory and exposes a flat, path-based interface directly tied to the RAMFS driver. For most purposes you should use the `vfs_*` functions instead, which wrap the same RAMFS operations behind the Virtual Filesystem mount abstraction. The `fs_*` API documented here is intended for driver authors and kernel subsystems that need direct access below the VFS mount layer.

<Note>
  Prefer the `vfs_*` API for general use. The VFS handles mount-point resolution and remains correct if additional filesystem backends are introduced. Only call `fs_*` functions directly when you specifically need to bypass the VFS mount layer.
</Note>

## Constants

All constants are defined in `mvh/fs.h`.

| Constant      | Value | Description                                                                  |
| ------------- | ----- | ---------------------------------------------------------------------------- |
| `FS_NAME_MAX` | `24`  | Maximum length of a single filename component, including the null terminator |
| `FS_DATA_MAX` | `256` | Maximum size of a file's content in bytes                                    |
| `FS_PATH_MAX` | `128` | Maximum length of an absolute or relative path string                        |
| `FS_LIST_MAX` | `64`  | Maximum number of entries that can be returned by a single directory listing |

## The `fs_entry_t` Struct

Directory listing functions populate arrays of `fs_entry_t`. Each element describes one file or subdirectory found inside the listed path.

```c theme={null}
typedef struct {
    char     name[FS_NAME_MAX]; /* null-terminated filename */
    uint8_t  is_directory;      /* 1 if entry is a directory, 0 if file */
    uint16_t size;              /* content size in bytes (0 for directories) */
} fs_entry_t;
```

<ResponseField name="name" type="char[24]">
  Null-terminated filename. At most `FS_NAME_MAX - 1` (23) usable characters.
</ResponseField>

<ResponseField name="is_directory" type="uint8_t">
  Set to `1` when the entry is a directory, `0` when it is a regular file.
</ResponseField>

<ResponseField name="size" type="uint16_t">
  Content size in bytes. Always `0` for directories. Never exceeds `FS_DATA_MAX` (256) for files.
</ResponseField>

***

## Functions

### `fs_init`

Initialize the RAMFS driver and prepare the root directory. You must call this before any other `fs_*` function. When using the VFS API, `vfs_init` calls `fs_init` internally — do not call it a second time.

```c theme={null}
void fs_init(void);
```

The current working directory is set to `/` after initialization.

***

### `fs_chdir`

Change the RAMFS current working directory to the given path.

```c theme={null}
int fs_chdir(const char *path);
```

<ParamField path="path" type="const char *" required>
  Absolute or relative path of the directory to change into. Must not exceed `FS_PATH_MAX` (128) bytes including the null terminator.
</ParamField>

<ResponseField name="return" type="int">
  `0` on success, or a negative value if the path does not exist or is not a directory.
</ResponseField>

***

### `fs_pwd`

Write the absolute path of the RAMFS current working directory into a caller-supplied buffer.

```c theme={null}
int fs_pwd(char *output, uint32_t capacity);
```

<ParamField path="output" type="char *" required>
  Buffer to receive the null-terminated path string. Must be at least `capacity` bytes.
</ParamField>

<ParamField path="capacity" type="uint32_t" required>
  Size of `output` in bytes. A value of `FS_PATH_MAX` (128) is always sufficient.
</ParamField>

<ResponseField name="return" type="int">
  `0` on success, or a negative value if `output` is `NULL` or `capacity` is too small to hold the current path.
</ResponseField>

***

### `fs_list`

List the contents of a directory into a caller-supplied array of `fs_entry_t` structs.

```c theme={null}
int fs_list(const char *path, fs_entry_t *entries, uint32_t capacity);
```

<ParamField path="path" type="const char *" required>
  Absolute or relative path of the directory to list.
</ParamField>

<ParamField path="entries" type="fs_entry_t *" required>
  Array of `fs_entry_t` to receive directory entries. Allocate at least `FS_LIST_MAX` (64) elements to capture every entry in any directory.
</ParamField>

<ParamField path="capacity" type="uint32_t" required>
  Number of elements available in `entries`. Results are truncated to this limit when a directory holds more entries than `capacity`.
</ParamField>

<ResponseField name="return" type="int">
  Non-negative entry count on success, or a negative value if the path does not exist or is not a directory.
</ResponseField>

<Note>
  A single directory holds at most `FS_LIST_MAX` (64) entries. Allocating `FS_LIST_MAX` elements for the `entries` array guarantees no entries are lost.
</Note>

***

### `fs_mkdir`

Create a new directory at the specified path.

```c theme={null}
int fs_mkdir(const char *path);
```

<ParamField path="path" type="const char *" required>
  Absolute or relative path of the directory to create. The parent directory must already exist. The final path component must not exceed `FS_NAME_MAX - 1` (23) characters.
</ParamField>

<ResponseField name="return" type="int">
  `0` on success, or a negative value if the parent does not exist, the name is too long, or an entry with that name already exists.
</ResponseField>

***

### `fs_touch`

Create a new empty file at the specified path.

```c theme={null}
int fs_touch(const char *path);
```

<ParamField path="path" type="const char *" required>
  Absolute or relative path of the file to create. The parent directory must already exist. The final path component must not exceed `FS_NAME_MAX - 1` (23) characters.
</ParamField>

<ResponseField name="return" type="int">
  `0` on success, or a negative value if the parent does not exist, the name is too long, or an entry with that name already exists.
</ResponseField>

***

### `fs_write`

Write or append text to an existing RAMFS file.

```c theme={null}
int fs_write(const char *path, const char *text, uint8_t append);
```

<ParamField path="path" type="const char *" required>
  Absolute or relative path of the target file. The file must already exist; call `fs_touch` first if needed.
</ParamField>

<ParamField path="text" type="const char *" required>
  Null-terminated string to write. The resulting file content must not exceed `FS_DATA_MAX` (256) bytes.
</ParamField>

<ParamField path="append" type="uint8_t" required>
  Pass `0` to overwrite the file's existing content with `text`. Pass `1` to append `text` after the current content.
</ParamField>

<ResponseField name="return" type="int">
  `0` on success, or a negative value if the path does not exist, the target is a directory, or the write would push the file beyond `FS_DATA_MAX` (256) bytes.
</ResponseField>

***

### `fs_read`

Read the content of a RAMFS file, returning a pointer into the kernel's internal buffer and the current byte count.

```c theme={null}
int fs_read(const char *path, const char **data, uint16_t *size);
```

<ParamField path="path" type="const char *" required>
  Absolute or relative path of the file to read.
</ParamField>

<ParamField path="data" type="const char **" required>
  On success, `*data` is set to a pointer into the kernel's internal file buffer. Do not free this pointer or write through it.
</ParamField>

<ParamField path="size" type="uint16_t *" required>
  On success, `*size` is set to the current content length in bytes. The value does not include a null terminator and never exceeds `FS_DATA_MAX` (256).
</ParamField>

<ResponseField name="return" type="int">
  `0` on success, or a negative value if the path does not exist or is a directory.
</ResponseField>

***

### `fs_remove`

Remove a file or an empty directory from RAMFS.

```c theme={null}
int fs_remove(const char *path);
```

<ParamField path="path" type="const char *" required>
  Absolute or relative path of the entry to remove. Directories must be empty before they can be removed.
</ParamField>

<ResponseField name="return" type="int">
  `0` on success, or a negative value if the path does not exist, the directory is not empty, or the path resolves to the root.
</ResponseField>

***

## File Size and Directory Capacity Limits

Each RAMFS file can hold at most **`FS_DATA_MAX` = 256 bytes** of content. Any `fs_write` call that would push a file past this limit fails with a negative return value.

Each RAMFS directory can contain at most **`FS_LIST_MAX` = 64 entries** (files and subdirectories combined). Attempting to create a new entry in a full directory fails with a negative return value.

***

## Example

```c theme={null}
#include "mvh/fs.h"
#include <stdint.h>

void example_ramfs(void) {
    /* Initialize RAMFS directly (skips VFS mount layer) */
    fs_init();

    /* Create a directory and a file */
    fs_mkdir("/data");
    fs_touch("/data/config.txt");

    /* Write initial content (overwrite mode) */
    fs_write("/data/config.txt", "timeout=30\n", 0);

    /* Append a second key */
    fs_write("/data/config.txt", "retries=3\n", 1);

    /* Read the content back */
    const char *data = 0;
    uint16_t size    = 0;

    if (fs_read("/data/config.txt", &data, &size) == 0) {
        /* data -> "timeout=30\nretries=3\n", size == 21 */
        (void)data;
        (void)size;
    }

    /* List /data */
    fs_entry_t entries[FS_LIST_MAX];
    int count = fs_list("/data", entries, FS_LIST_MAX);

    for (int i = 0; i < count; i++) {
        (void)entries[i]; /* entries[i].name, .is_directory, .size */
    }
}
```
