Files
claude-os/src/vfs.h
AI 0c5aa72fd3 Add VFS subsystem and initrd filesystem driver (AI)
VFS subsystem (vfs.c/h):
- Mount table with up to 16 mount points, longest-prefix path matching.
- File descriptor table (256 entries, fds 0-2 reserved for std streams).
- Path resolution walks mount table then delegates to filesystem's
  finddir() for each path component.
- Operations: open, close, read, write, seek, readdir, stat.
- Each filesystem driver provides a vfs_fs_ops_t with callbacks.

Initrd filesystem driver (initrd_fs.c/h):
- Read-only VFS driver backed by the CPIO ramdisk.
- Mounted at '/initrd' during boot.
- Zero-copy reads: file data points directly into the CPIO archive
  memory, no allocation or copying needed.
- Supports readdir (flat iteration) and finddir (name lookup).

Bug fix: resolve_path was overwriting file-specific fs_data (set by
finddir, e.g. pointer to CPIO file data) with the mount's fs_data
(NULL). Fixed to preserve fs_data from finddir.

Verified in QEMU: kernel reads /initrd/README via VFS and prints its
contents. Ring 3 user process continues to work.
2026-02-23 12:23:32 +00:00

198 lines
5.2 KiB
C

/**
* @file vfs.h
* @brief Virtual Filesystem (VFS) subsystem.
*
* Provides a unified interface for file and directory operations across
* different filesystem implementations. Filesystem drivers register
* themselves and can be mounted at specific paths.
*/
#ifndef VFS_H
#define VFS_H
#include <stdint.h>
#include <stddef.h>
/** Maximum number of open files across all processes. */
#define VFS_MAX_OPEN_FILES 256
/** Maximum number of mounted filesystems. */
#define VFS_MAX_MOUNTS 16
/** Maximum path length. */
#define VFS_MAX_PATH 256
/** Maximum filename length. */
#define VFS_MAX_NAME 128
/** File types. */
#define VFS_FILE 0x01
#define VFS_DIRECTORY 0x02
#define VFS_CHARDEV 0x03
#define VFS_BLOCKDEV 0x04
#define VFS_SYMLINK 0x06
/** Seek origins. */
#define VFS_SEEK_SET 0
#define VFS_SEEK_CUR 1
#define VFS_SEEK_END 2
/** Forward declarations. */
struct vfs_node;
struct vfs_dirent;
struct vfs_fs_ops;
/**
* Directory entry, returned by readdir.
*/
typedef struct vfs_dirent {
char name[VFS_MAX_NAME]; /**< Entry name. */
uint32_t inode; /**< Inode number (fs-specific). */
uint8_t type; /**< VFS_FILE, VFS_DIRECTORY, etc. */
} vfs_dirent_t;
/**
* VFS node representing a file or directory.
*/
typedef struct vfs_node {
char name[VFS_MAX_NAME]; /**< Node name. */
uint8_t type; /**< VFS_FILE, VFS_DIRECTORY, etc. */
uint32_t size; /**< File size in bytes. */
uint32_t inode; /**< Inode number (fs-specific). */
uint32_t mode; /**< Permissions/mode. */
/** Filesystem-specific operations. */
struct vfs_fs_ops *ops;
/** Opaque pointer for the filesystem driver. */
void *fs_data;
/** Mount index (which mount this node belongs to). */
int mount_idx;
} vfs_node_t;
/**
* Filesystem operations provided by each filesystem driver.
*/
typedef struct vfs_fs_ops {
/** Open a file. Returns 0 on success. */
int (*open)(vfs_node_t *node, uint32_t flags);
/** Close a file. */
void (*close)(vfs_node_t *node);
/** Read up to `size` bytes at `offset`. Returns bytes read, or -1. */
int32_t (*read)(vfs_node_t *node, uint32_t offset, uint32_t size, void *buf);
/** Write up to `size` bytes at `offset`. Returns bytes written, or -1. */
int32_t (*write)(vfs_node_t *node, uint32_t offset, uint32_t size, const void *buf);
/** Read directory entry at index `idx`. Returns 0 on success, -1 at end. */
int (*readdir)(vfs_node_t *dir, uint32_t idx, vfs_dirent_t *out);
/** Look up a child by name within a directory. Returns 0 on success. */
int (*finddir)(vfs_node_t *dir, const char *name, vfs_node_t *out);
} vfs_fs_ops_t;
/**
* Mount point entry.
*/
typedef struct vfs_mount {
char path[VFS_MAX_PATH]; /**< Mount path (e.g., "/initrd"). */
vfs_fs_ops_t *ops; /**< Filesystem operations. */
void *fs_data; /**< Filesystem-specific data. */
int active; /**< 1 if mounted, 0 if free. */
} vfs_mount_t;
/**
* Open file descriptor.
*/
typedef struct vfs_fd {
vfs_node_t node; /**< The file node. */
uint32_t offset; /**< Current read/write offset. */
uint32_t flags; /**< Open flags. */
int active; /**< 1 if in use, 0 if free. */
} vfs_fd_t;
/**
* Initialize the VFS subsystem.
*/
void init_vfs(void);
/**
* Mount a filesystem at the given path.
*
* @param path Mount point path (e.g., "/initrd").
* @param ops Filesystem operations.
* @param fs_data Filesystem-specific data pointer.
* @return 0 on success, -1 on failure.
*/
int vfs_mount(const char *path, vfs_fs_ops_t *ops, void *fs_data);
/**
* Open a file by path.
*
* @param path Absolute path to the file.
* @param flags Open flags (currently unused).
* @return File descriptor (>= 0), or -1 on failure.
*/
int vfs_open(const char *path, uint32_t flags);
/**
* Close an open file descriptor.
*
* @param fd File descriptor.
*/
void vfs_close(int fd);
/**
* Read from an open file.
*
* @param fd File descriptor.
* @param buf Buffer to read into.
* @param size Maximum bytes to read.
* @return Bytes read, or -1 on error.
*/
int32_t vfs_read(int fd, void *buf, uint32_t size);
/**
* Write to an open file.
*
* @param fd File descriptor.
* @param buf Buffer to write from.
* @param size Bytes to write.
* @return Bytes written, or -1 on error.
*/
int32_t vfs_write(int fd, const void *buf, uint32_t size);
/**
* Seek within an open file.
*
* @param fd File descriptor.
* @param offset Offset to seek to.
* @param whence VFS_SEEK_SET, VFS_SEEK_CUR, or VFS_SEEK_END.
* @return New offset, or -1 on error.
*/
int32_t vfs_seek(int fd, int32_t offset, int whence);
/**
* Read a directory entry.
*
* @param path Path to the directory.
* @param idx Entry index (0-based).
* @param out Output directory entry.
* @return 0 on success, -1 at end or on error.
*/
int vfs_readdir(const char *path, uint32_t idx, vfs_dirent_t *out);
/**
* Stat a file (get its node info).
*
* @param path Path to the file.
* @param out Output node.
* @return 0 on success, -1 on failure.
*/
int vfs_stat(const char *path, vfs_node_t *out);
#endif /* VFS_H */