miniOS
x86_64 hobby kernel with SMP, VFS, and POSIX process model
Loading...
Searching...
No Matches
vfs.h
Go to the documentation of this file.
1// MIT License
2//
3// Copyright (c) 2026 Christian Spoo
4//
5// Permission is hereby granted, free of charge, to any person obtaining a copy
6// of this software and associated documentation files (the "Software"), to deal
7// in the Software without restriction, including without limitation the rights
8// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9// copies of the Software, and to permit persons to whom the Software is
10// furnished to do so, subject to the following conditions:
11//
12// The above copyright notice and this permission notice shall be included in all
13// copies or substantial portions of the Software.
14//
15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21// SOFTWARE.
22
23#ifndef _MINIOS_FS_VFS_H_
24#define _MINIOS_FS_VFS_H_
25
26#include <miniOS/types.h>
27
28#include <miniOS/fs/ext2.h>
29#include <miniOS/fs/pipe.h>
30
31#define VFS_MAX_FDS 64 /* max open files per task */
32#define VFS_PATH_MAX 256 /* max path length */
33#define VFS_FD_STDIN 0
34#define VFS_FD_STDOUT 1
35#define VFS_FD_STDERR 2
36#define VFS_FIRST_OPEN_FD 3
37
38/* File type flags stored in vfs_file */
39#define VFS_FILE_TYPE_REG 1
40#define VFS_FILE_TYPE_DIR 2
41#define VFS_FILE_TYPE_PIPE 3 /* anonymous pipe backed by ring buffer */
42#define VFS_FILE_TYPE_SYMLINK 4 /* symbolic link; used by lstat to detect symlink targets */
43#define VFS_FILE_TYPE_CHAR 5 /* character device node */
44#define VFS_FILE_TYPE_BLK 6 /* block device node */
45#define VFS_FILE_TYPE_SOCKET 7 /* BSD-style socket backed by lwIP PCB */
46#define VFS_FILE_TYPE_UNIX_SOCKET 8 /* AF_UNIX socket backed by unix_sock_t */
47
48#define VFS_DEVICE_NONE 0
49#define VFS_DEVICE_TTY 1
50#define VFS_DEVICE_NULL 2
51
52typedef struct vfs_inode_info {
56 uint32_t dev; /* encoded (major<<8)|minor for CHR/BLK nodes; 0 otherwise */
58 uint16_t mode; /* lower 9 bits: rwxrwxrwx permission bits; 0 = unknown */
60
61/* Filesystem statistics — filled by the statfs vfs_ops callback */
62typedef struct vfs_statfs {
63 uint64_t f_type; /* filesystem magic (e.g. 0xEF53 for ext2) */
64 uint64_t f_bsize; /* block size in bytes */
65 uint64_t f_blocks; /* total data blocks */
66 uint64_t f_bfree; /* free blocks */
67 uint64_t f_bavail; /* free blocks available to unprivileged user */
68 uint64_t f_files; /* total inodes */
69 uint64_t f_ffree; /* free inodes */
70 uint64_t f_namelen; /* max filename length */
71 uint64_t f_fsid; /* unique per-mount id (stamped by vfs_statfs) */
73
74/* A VFS ops table — one per mounted filesystem */
75typedef struct vfs_ops {
76 /* Look up path metadata, return 0 on success or -1 on not found */
77 int (*lookup)(const char *path, vfs_inode_info_t *out);
78 /* Read bytes from inode; returns bytes read or -1 */
79 int (*read)(uint32_t ino, uint64_t off, void *buf, uint32_t len);
80 /* Iterate directory entries at inode; calls cb per entry */
81 int (*readdir)(uint32_t ino, uint64_t *offset, vfs_dirent_cb_t cb, void *ud);
82 /* Write bytes to inode; returns bytes written or -1 */
83 int (*write)(uint32_t ino, uint64_t off, const void *buf, uint32_t len);
84 /* Flush inode metadata to disk; returns 0 on success or -1 */
85 int (*flush)(uint32_t ino);
86 /* Filesystem-specific file/directory creation and deletion.
87 * NULL if the filesystem is read-only or does not support this operation. */
88 int (*create)(uint32_t parent_ino, const char *name, uint16_t mode, uint32_t *new_ino_out);
89 int (*unlink)(uint32_t parent_ino, const char *name); /* file only; use rmdir for dirs */
90 int (*rename)(uint32_t old_parent_ino, const char *old_name,
91 uint32_t new_parent_ino, const char *new_name);
92 int (*mkdir)(uint32_t parent_ino, const char *name, uint32_t *new_ino_out); /* dir creation; NULL if unsupported */
93 int (*rmdir)(uint32_t parent_ino, const char *name); /* empty dir removal; NULL if unsupported */
94 /* Set the active root inode before path resolution; NULL if unused (e.g. ext2) */
95 void (*set_root)(uint32_t root_ino);
96 /* Truncate a regular file to zero bytes; returns 0 on success, -1 on error.
97 * NULL if the filesystem does not support truncation. */
98 int (*truncate)(uint32_t ino, uint64_t new_size);
99 /* Read the target of a symlink inode into buf (max len bytes, NOT null-terminated
100 * per POSIX readlink(2)). Returns bytes written (>= 0) or -1 on error.
101 * NULL if the filesystem does not support symlinks. */
102 int (*readlink)(uint32_t ino, char *buf, uint32_t len);
103 /* Create a symlink named `name` in directory `parent_ino` pointing to `target`.
104 * Returns 0 on success, -1 on error.
105 * NULL if the filesystem does not support symlink creation. */
106 int (*symlink)(uint32_t parent_ino, const char *name, const char *target);
107 /* Create a device special file (char or block) named `name` in `parent_ino`.
108 * @mode: EXT2_S_IFCHR|perms or EXT2_S_IFBLK|perms.
109 * @dev: Encoded device number (major<<8)|minor.
110 * Returns 0 on success, -1 on error.
111 * NULL if the filesystem does not support device node creation. */
112 int (*mknod)(uint32_t parent_ino, const char *name, uint16_t mode,
113 uint32_t dev, uint32_t *new_ino_out);
114 /* Change permission bits of an inode; @mode contains only the low 12 bits
115 * (permissions + setuid/setgid/sticky). Returns 0 on success, -1 on error.
116 * NULL if the filesystem does not support chmod. */
117 int (*chmod)(uint32_t ino, uint16_t mode);
118 /* Fill filesystem statistics; returns 0 on success, -1 on error.
119 * NULL if the filesystem does not expose usage statistics. */
120 int (*statfs)(vfs_statfs_t *out);
121 /* Release any single-instance global state held by this filesystem so it
122 * can be mounted again. Called by vfs_unregister_mount(). NULL if the
123 * filesystem has no such state to release (e.g. tmpfs, sysfs). */
124 void (*unmount)(void);
126
127/* Filesystem type registry — maps fstype names to mount callbacks */
128#define VFS_MAX_FS_TYPES 16
129
130typedef struct filesystem_type {
131 char name[16]; /* e.g. "ext2", "sysfs", "tmpfs" */
132 /* mount() — called by vfs_mount_fstype() to attach the filesystem.
133 * @source: device or source identifier (may be NULL for pseudo-filesystems)
134 * @target: absolute mount point path (e.g. "/", "/sys")
135 * @data: filesystem-specific options struct (may be NULL); cast to the
136 * appropriate type inside the callback (e.g. ext2_mount_data_t *)
137 * The callback is responsible for calling vfs_register_mount() internally.
138 * Returns 0 on success, negative errno on failure. */
139 int (*mount)(const char *source, const char *target, const void *data);
141
142int register_filesystem(const char *name,
143 int (*mount)(const char *source, const char *target,
144 const void *data));
155int vfs_mount_fstype(const char *fstype, const char *source,
156 const char *target, const void *data);
157
158/* Mount table entry — maps a mount point path to a filesystem ops table */
159#define VFS_MAX_MOUNTS 16
160
161typedef struct vfs_mount {
162 char mount_point[VFS_PATH_MAX]; /* e.g. "/" or "/tmp" */
163 vfs_ops_t *ops; /* filesystem operations */
164 uint32_t root_ino; /* per-mount root inode (0 = fs default) */
165 char fstype[16]; /* e.g. "ext2", "tmpfs", "proc" */
166 char device[32]; /* e.g. "/dev/sda1" or fstype name for pseudo-fs */
168
178int vfs_register_mount(const char *point, vfs_ops_t *ops, uint32_t root_ino);
179
187int vfs_unregister_mount(const char *point);
188
189int vfs_mount_count(void);
190const vfs_mount_t *vfs_get_mount(int idx);
191int vfs_path_devno(const char *path); /* 1-based mount index, 0 if not found */
192int vfs_fd_devno(int fd); /* 1-based mount index for open fd */
193
194/* Forward declarations for socket types — avoids circular includes */
195struct net_sock;
196struct unix_sock;
197
198/* An open file handle */
199typedef struct vfs_file {
202 uint64_t offset; /* current read/write position */
204 uint8_t ftype; /* VFS_FILE_TYPE_REG, VFS_FILE_TYPE_DIR, VFS_FILE_TYPE_PIPE, VFS_FILE_TYPE_CHAR */
205 uint8_t device_type; /* VFS_DEVICE_* for character devices */
206 uint32_t dev; /* encoded (major<<8)|minor for CHR/BLK nodes; 0 otherwise */
207 int flags; /* O_RDONLY (0) or O_WRONLY (1); set by vfs_open */
208 int status_flags; /* O_NONBLOCK (0x800), O_APPEND (0x400), O_ASYNC (0x2000); mutable via fcntl F_SETFL */
210 uint32_t ref_count; /* number of fd slots pointing at this file description */
211 pipe_t *pipe; /* non-NULL iff ftype == VFS_FILE_TYPE_PIPE */
212 /* sock and usock share a slot: an fd is either a lwIP socket or AF_UNIX socket,
213 * never both. Using a union keeps sizeof(vfs_file_t) exactly the same as
214 * the original two-pointer layout. */
215 union {
216 struct net_sock *sock; /* non-NULL iff ftype == VFS_FILE_TYPE_SOCKET */
217 struct unix_sock *usock; /* non-NULL iff ftype == VFS_FILE_TYPE_UNIX_SOCKET */
218 };
220
229void vfs_mount(vfs_ops_t *ops);
230
246int vfs_open(const char *path, int flags, int mode);
247
260int vfs_read(int fd, void *buf, uint32_t len);
261
274int vfs_readdir(int fd, vfs_dirent_cb_t cb, void *ud);
275
287int vfs_write(int fd, const void *buf, uint32_t len);
288
300int vfs_close(int fd);
301
310int vfs_unlink(const char *path);
311
322int vfs_rename(const char *oldpath, const char *newpath);
323
332int vfs_rmdir(const char *path);
333
340int vfs_mkdir(const char *path, int mode);
341
348int vfs_stat(const char *path, vfs_inode_info_t *out);
349int vfs_statfs(const char *path, vfs_statfs_t *out);
350int vfs_fstatfs(int fd, vfs_statfs_t *out);
351
358int vfs_fstat(int fd, vfs_inode_info_t *out);
359
366int vfs_lstat(const char *path, vfs_inode_info_t *out);
367
374int vfs_symlink(const char *path, const char *target);
375
382int vfs_chmod(const char *path, uint16_t mode);
383
391int vfs_mknod(const char *path, uint16_t mode, uint32_t dev);
392
400int vfs_readlink(const char *path, char *buf, uint32_t bufsiz);
401
402#endif /* _MINIOS_FS_VFS_H_ */
struct vfs_inode_info vfs_inode_info_t
Definition ext2.h:29
int(*) vfs_dirent_cb_t(const char *name, uint8_t name_len, uint32_t inode, uint8_t file_type, void *ud)
Definition fs_types.h:29
struct idt_entry_t * offset
Definition irq.h:1
int mount(const char *source, const char *target, const char *fstype, unsigned long flags, const void *data)
Definition miniOS_compat.c:15
Definition vfs.h:130
char name[16]
Definition vfs.h:131
int(*) mount(const char *source, const char *target, const void *data)
Definition vfs.h:139
Kernel socket state.
Definition net_socket.h:57
Definition pipe.h:54
Definition unix_sock.h:20
char path[UNIX_SOCK_PATH_MAX]
Definition unix_sock.h:24
uint8_t buf[UNIX_SOCK_BUF_SIZE]
Definition unix_sock.h:28
Definition vfs.h:199
uint32_t ref_count
Definition vfs.h:210
uint32_t inode
Definition vfs.h:201
vfs_ops_t * ops
Definition vfs.h:209
int flags
Definition vfs.h:207
uint32_t dev
Definition vfs.h:206
uint64_t size
Definition vfs.h:203
uint8_t in_use
Definition vfs.h:200
uint8_t ftype
Definition vfs.h:204
uint8_t device_type
Definition vfs.h:205
pipe_t * pipe
Definition vfs.h:211
int status_flags
Definition vfs.h:208
uint64_t offset
Definition vfs.h:202
Definition vfs.h:52
uint32_t inode
Definition vfs.h:53
uint16_t mode
Definition vfs.h:58
uint64_t size
Definition vfs.h:57
uint32_t dev
Definition vfs.h:56
uint8_t device_type
Definition vfs.h:55
uint8_t file_type
Definition vfs.h:54
Definition vfs.h:161
char mount_point[VFS_PATH_MAX]
Definition vfs.h:162
vfs_ops_t * ops
Definition vfs.h:163
uint32_t root_ino
Definition vfs.h:164
char device[32]
Definition vfs.h:166
char fstype[16]
Definition vfs.h:165
Definition vfs.h:75
void(*) set_root(uint32_t root_ino)
Definition vfs.h:95
int(*) lookup(const char *path, vfs_inode_info_t *out)
Definition vfs.h:77
int(*) readlink(uint32_t ino, char *buf, uint32_t len)
Definition vfs.h:102
int(*) mknod(uint32_t parent_ino, const char *name, uint16_t mode, uint32_t dev, uint32_t *new_ino_out)
Definition vfs.h:112
int(*) unlink(uint32_t parent_ino, const char *name)
Definition vfs.h:89
void(*) unmount(void)
Definition vfs.h:124
int(*) mkdir(uint32_t parent_ino, const char *name, uint32_t *new_ino_out)
Definition vfs.h:92
int(*) rmdir(uint32_t parent_ino, const char *name)
Definition vfs.h:93
int(*) create(uint32_t parent_ino, const char *name, uint16_t mode, uint32_t *new_ino_out)
Definition vfs.h:88
int(*) truncate(uint32_t ino, uint64_t new_size)
Definition vfs.h:98
int(*) chmod(uint32_t ino, uint16_t mode)
Definition vfs.h:117
int(*) write(uint32_t ino, uint64_t off, const void *buf, uint32_t len)
Definition vfs.h:83
int(*) symlink(uint32_t parent_ino, const char *name, const char *target)
Definition vfs.h:106
int(*) statfs(vfs_statfs_t *out)
Definition vfs.h:120
int(*) rename(uint32_t old_parent_ino, const char *old_name, uint32_t new_parent_ino, const char *new_name)
Definition vfs.h:90
int(*) read(uint32_t ino, uint64_t off, void *buf, uint32_t len)
Definition vfs.h:79
int(*) readdir(uint32_t ino, uint64_t *offset, vfs_dirent_cb_t cb, void *ud)
Definition vfs.h:81
int(*) flush(uint32_t ino)
Definition vfs.h:85
Definition vfs.h:62
uint64_t f_blocks
Definition vfs.h:65
uint64_t f_bfree
Definition vfs.h:66
uint64_t f_type
Definition vfs.h:63
uint64_t f_bsize
Definition vfs.h:64
uint64_t f_namelen
Definition vfs.h:70
uint64_t f_fsid
Definition vfs.h:71
uint64_t f_bavail
Definition vfs.h:67
uint64_t f_ffree
Definition vfs.h:69
uint64_t f_files
Definition vfs.h:68
int fd
Definition syscall_fs.c:0
unsigned short uint16_t
Definition types.h:31
unsigned int uint32_t
Definition types.h:34
unsigned long int uint64_t
Definition types.h:37
unsigned char uint8_t
Definition types.h:28
struct vfs_statfs vfs_statfs_t
struct vfs_mount vfs_mount_t
int vfs_write(int fd, const void *buf, uint32_t len)
Definition vfs.c:532
int vfs_chmod(const char *path, uint16_t mode)
Definition vfs.c:893
int vfs_fd_devno(int fd)
Definition vfs.c:138
int vfs_read(int fd, void *buf, uint32_t len)
Definition vfs.c:497
int vfs_mknod(const char *path, uint16_t mode, uint32_t dev)
Definition vfs.c:910
struct vfs_inode_info vfs_inode_info_t
int vfs_symlink(const char *path, const char *target)
Definition vfs.c:685
int vfs_close(int fd)
Definition vfs.c:592
int vfs_rename(const char *oldpath, const char *newpath)
Definition vfs.c:949
int vfs_unlink(const char *path)
Definition vfs.c:746
int vfs_rmdir(const char *path)
Definition vfs.c:796
int vfs_mount_count(void)
Definition vfs.c:67
struct filesystem_type filesystem_type_t
int vfs_lstat(const char *path, vfs_inode_info_t *out)
Definition vfs.c:648
struct vfs_ops vfs_ops_t
int vfs_readdir(int fd, vfs_dirent_cb_t cb, void *ud)
Definition vfs.c:572
#define VFS_PATH_MAX
Definition vfs.h:32
int vfs_fstatfs(int fd, vfs_statfs_t *out)
Definition vfs.c:160
int vfs_path_devno(const char *path)
Definition vfs.c:131
int vfs_readlink(const char *path, char *buf, uint32_t bufsiz)
Definition vfs.c:669
int vfs_open(const char *path, int flags, int mode)
Definition vfs.c:329
int vfs_mkdir(const char *path, int mode)
Definition vfs.c:842
int register_filesystem(const char *name, int(*mount)(const char *source, const char *target, const void *data))
Definition vfs.c:38
int vfs_mount_fstype(const char *fstype, const char *source, const char *target, const void *data)
Definition vfs.c:49
int vfs_fstat(int fd, vfs_inode_info_t *out)
Definition vfs.c:725
int vfs_stat(const char *path, vfs_inode_info_t *out)
Definition vfs.c:636
int vfs_unregister_mount(const char *point)
Definition vfs.c:203
struct vfs_file vfs_file_t
const vfs_mount_t * vfs_get_mount(int idx)
Definition vfs.c:69
int vfs_register_mount(const char *point, vfs_ops_t *ops, uint32_t root_ino)
Definition vfs.c:184
uint16_t idx
Definition virtio_net.c:1
uint16_t flags
Definition virtio_net.c:2
uint32_t len
Definition virtio_net.c:1