MOS Source Code
Loading...
Searching...
No Matches
vfs_types.hpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-3.0-or-later
2
3#pragma once
4
6#include "mos/mm/mm.hpp"
8
9#include <abi-bits/stat.h>
10#include <cstddef>
11#include <mos/allocator.hpp>
13#include <mos/hashmap.hpp>
14#include <mos/io/io.hpp>
15#include <mos/io/io_types.h>
21#include <mos/string.hpp>
22#include <mos/types.hpp>
23
26
27#define FILESYSTEM_DEFINE(var, fsname, mountfn, unmountfn) \
28 filesystem_t var = { \
29 .name = fsname, \
30 .mount = mountfn, \
31 .unmount = unmountfn, \
32 }
33
34#define FILESYSTEM_AUTOREGISTER(fs) \
35 static void __register_##fs() \
36 { \
37 vfs_register_filesystem(&fs); \
38 } \
39 MOS_INIT(VFS, __register_##fs)
40
41struct dentry_t;
42typedef struct _inode_cache inode_cache_t;
43struct inode_t;
44struct mount_t;
45struct superblock_t;
46struct filesystem_t;
47struct BasicFile;
48
56
57struct vfs_listdir_state_t : mos::NamedType<"VFS.ListDir.State">
58{
60 size_t n_count;
61 size_t read_offset;
62};
63
65
66typedef struct
67{
69 bool (*hardlink)(dentry_t *old_dentry, inode_t *dir, dentry_t *new_dentry);
73 bool (*lookup)(inode_t *dir, dentry_t *dentry);
75 bool (*mkdir)(inode_t *dir, dentry_t *dentry, file_perm_t perm);
77 bool (*mknode)(inode_t *dir, dentry_t *dentry, file_type_t type, file_perm_t perm, dev_t dev);
79 bool (*newfile)(inode_t *dir, dentry_t *dentry, file_type_t type, file_perm_t perm);
81 size_t (*readlink)(dentry_t *dentry, char *buffer, size_t buflen);
83 bool (*rename)(inode_t *old_dir, dentry_t *old_dentry, inode_t *new_dir, dentry_t *new_dentry);
85 bool (*rmdir)(inode_t *dir, dentry_t *dentry);
87 bool (*symlink)(inode_t *dir, dentry_t *dentry, const char *symname);
89 bool (*unlink)(inode_t *dir, dentry_t *dentry);
91
92typedef struct
93{
94 bool (*open)(inode_t *inode, BasicFile *file, bool created);
95 ssize_t (*read)(const BasicFile *file, void *buf, size_t size, off_t offset);
96 ssize_t (*write)(const BasicFile *file, const void *buf, size_t size, off_t offset);
98 off_t (*seek)(BasicFile *file, off_t offset, io_seek_whence_t whence);
99 bool (*mmap)(BasicFile *file, vmap_t *vmap, off_t offset);
100 bool (*munmap)(BasicFile *file, vmap_t *vmap, bool *unmapped);
101} file_ops_t;
102
103typedef struct
104{
106 long (*sync_inode)(inode_t *inode);
108
109struct superblock_t final : mos::NamedType<"superblock">
110{
114};
115
116struct dentry_t final : mos::NamedType<"dentry">
117{
122 mos::string name; // for a mounted root, this is EMPTY
123 superblock_t *superblock; // The superblock of the dentry
125};
126
127extern dentry_t *root_dentry;
128
129inline mos::string dentry_name(const dentry_t *dentry)
130{
131 static const mos::string root_name = "<root>";
132 static const mos::string null_name = "<NULL>";
133 const auto name = (dentry)->name;
134 return mos::string(name.value_or(dentry == root_dentry ? root_name : null_name));
135}
136
137typedef struct _inode_cache_ops
138{
143
144 bool (*page_write_begin)(inode_cache_t *cache, off_t file_offset, size_t inpage_size, phyframe_t **page_out, void **data);
145 void (*page_write_end)(inode_cache_t *cache, off_t file_offset, size_t inpage_size, phyframe_t *page, void *data);
146
150 long (*flush_page)(inode_cache_t *cache, uint64_t pgoff, phyframe_t *page);
152
153typedef struct _inode_cache
154{
157 mos::HashMap<size_t, phyframe_t *> pages; // page index -> phyframe_t *
160
161struct inode_t final : mos::NamedType<"inode">
162{
166 size_t size;
169 bool sticky;
170 bool suid;
171 bool sgid;
172 ssize_t nlinks; // number of hard links to this inode
176
177 superblock_t *superblock; // superblock of this inode
178 const inode_ops_t *ops; // operations on this inode
179 const file_ops_t *file_ops; // operations on files of this inode
180 void *private_data; // private data
181 inode_cache_t cache; // page cache for this inode
182
184};
185
186struct filesystem_t final : mos::NamedType<"filesystem">
187{
190 PtrResult<dentry_t> (*mount)(filesystem_t *fs, const char *dev_name, const char *mount_options);
191 void (*unmount)(filesystem_t *fs, dentry_t *mountpoint); // called when the mountpoint is unmounted
192};
193
194struct mount_t final : mos::NamedType<"mount">
195{
197 dentry_t *root; // root of the mounted tree
198 dentry_t *mountpoint; // where the tree is mounted
201};
202
203struct BasicFile : IO
204{
206 spinlock_t offset_lock; // protects the offset field
207 size_t offset; // tracks the current position in the file
209
210 ~BasicFile() = default;
211
212 BasicFile(IOFlags flags, io_type_t type, dentry_t *dentry) : IO(flags, type), dentry(dentry), offset(0), private_data(nullptr)
213 {
214 }
215
216 mos::string name() const override;
217
218 const file_ops_t *get_ops() const
219 {
220 if (!dentry)
221 goto error;
222
223 if (!dentry->inode)
224 goto error;
225
226 if (!dentry->inode->file_ops)
227 goto error;
228
229 return dentry->inode->file_ops;
230
231 error:
232 mWarn << "no file_ops for file " << this;
233 return NULL;
234 }
235};
236
237struct File final : BasicFile, mos::NamedType<"File">
238{
239 File(IOFlags flags, dentry_t *dentry) : BasicFile(flags, IO_FILE, dentry) {};
240 ~File() = default;
241
242 size_t on_read(void *buf, size_t size) override;
243 size_t on_write(const void *buf, size_t size) override;
244 void on_closed() override;
245 off_t on_seek(off_t offset, io_seek_whence_t whence) override;
246 bool on_mmap(vmap_t *vmap, off_t offset) override;
247 bool on_munmap(vmap_t *vmap, bool *unmapped) override;
248};
249
250struct Directory final : BasicFile, mos::NamedType<"Directory">
251{
252 Directory(IOFlags flags, dentry_t *dentry) : BasicFile(flags, IO_DIR, dentry) {};
253 ~Directory() = default;
254
255 size_t on_read(void *buf, size_t size) override;
256 void on_closed() override;
257};
fstatat_flags
Definition fs_types.h:40
u16 file_perm_t
Definition fs_types.h:52
open_flags
Definition fs_types.h:26
file_type_t
Definition fs_types.h:14
MOSAPI void(1, 2) fatal_abort(const char *fmt
list_node_t list_head
A linked list head.
Definition list.hpp:23
dentry_t * root_dentry
Definition vfs.cpp:35
io_type_t
Definition io.hpp:17
@ IO_FILE
Definition io.hpp:19
@ IO_DIR
Definition io.hpp:20
io_seek_whence_t
Definition io_types.h:6
futex_word_t mutex_t
Definition mutex.hpp:8
basic_string_view< char > string_view
mos::basic_string< char, mos::default_allocator > string
Definition string.hpp:352
#define uint64_t
#define NULL
Definition pb_syshdr.h:46
int bool
Definition pb_syshdr.h:57
uint32_t size_t
Definition pb_syshdr.h:42
size_t size
Definition slab.cpp:32
const char * name
Definition slab.cpp:33
spinlock_t offset_lock
const file_ops_t * get_ops() const
mos::string name() const override
Definition vfs.cpp:403
size_t offset
BasicFile(IOFlags flags, io_type_t type, dentry_t *dentry)
~BasicFile()=default
void * private_data
dentry_t * dentry
Directory(IOFlags flags, dentry_t *dentry)
~Directory()=default
void on_closed() override
Definition vfs.cpp:90
size_t on_read(void *buf, size_t size) override
Definition vfs.cpp:85
off_t on_seek(off_t offset, io_seek_whence_t whence) override
Definition vfs.cpp:150
size_t on_write(const void *buf, size_t size) override
Definition vfs.cpp:136
File(IOFlags flags, dentry_t *dentry)
~File()=default
bool on_mmap(vmap_t *vmap, off_t offset) override
Definition vfs.cpp:237
bool on_munmap(vmap_t *vmap, bool *unmapped) override
Definition vfs.cpp:250
void on_closed() override
Definition vfs.cpp:62
size_t on_read(void *buf, size_t size) override
Definition vfs.cpp:120
IO(IOFlags flags, io_type_t type)
Definition io.cpp:35
superblock_t * superblock
mos::string name
bool is_mountpoint
spinlock_t lock
atomic_t refcount
inode_t * inode
bool(* munmap)(BasicFile *file, vmap_t *vmap, bool *unmapped)
unmap the file from memory
ssize_t(* write)(const BasicFile *file, const void *buf, size_t size, off_t offset)
write to the file
Definition vfs_types.hpp:96
ssize_t(* read)(const BasicFile *file, void *buf, size_t size, off_t offset)
read from the file
Definition vfs_types.hpp:95
bool(* mmap)(BasicFile *file, vmap_t *vmap, off_t offset)
map the file into memory
Definition vfs_types.hpp:99
bool(* open)(inode_t *inode, BasicFile *file, bool created)
called when a file is opened, or created
Definition vfs_types.hpp:94
off_t(* seek)(BasicFile *file, off_t offset, io_seek_whence_t whence)
seek to a new position in the file
Definition vfs_types.hpp:98
void(* release)(BasicFile *file)
called when the last reference to the file is dropped
Definition vfs_types.hpp:97
void(* unmount)(filesystem_t *fs, dentry_t *mountpoint)
mos::string name
PtrResult< dentry_t >(* mount)(filesystem_t *fs, const char *dev_name, const char *mount_options)
PtrResult< phyframe_t >(* fill_cache)(inode_cache_t *cache, uint64_t pgoff)
Read a page from the underlying storage, at file offset pgoff * MOS_PAGE_SIZE.
long(* flush_page)(inode_cache_t *cache, uint64_t pgoff, phyframe_t *page)
Flush a page to the underlying storage.
bool(* page_write_begin)(inode_cache_t *cache, off_t file_offset, size_t inpage_size, phyframe_t **page_out, void **data)
void(* page_write_end)(inode_cache_t *cache, off_t file_offset, size_t inpage_size, phyframe_t *page, void *data)
inode_t * owner
mos::HashMap< size_t, phyframe_t * > pages
const inode_cache_ops_t * ops
bool(* mkdir)(inode_t *dir, dentry_t *dentry, file_perm_t perm)
create a new directory
Definition vfs_types.hpp:75
size_t(* readlink)(dentry_t *dentry, char *buffer, size_t buflen)
read the contents of a symbolic link
Definition vfs_types.hpp:81
bool(* unlink)(inode_t *dir, dentry_t *dentry)
remove a file name, this is called after nlinks is decremented
Definition vfs_types.hpp:89
bool(* hardlink)(dentry_t *old_dentry, inode_t *dir, dentry_t *new_dentry)
create a hard link
Definition vfs_types.hpp:69
bool(* newfile)(inode_t *dir, dentry_t *dentry, file_type_t type, file_perm_t perm)
create a new file
Definition vfs_types.hpp:79
bool(* rmdir)(inode_t *dir, dentry_t *dentry)
remove a directory
Definition vfs_types.hpp:85
bool(* lookup)(inode_t *dir, dentry_t *dentry)
lookup a file in a directory, if it's unset for a directory, the VFS will use the default lookup
Definition vfs_types.hpp:73
void(* iterate_dir)(dentry_t *dentry, vfs_listdir_state_t *iterator_state, dentry_iterator_op op)
iterate over the contents of a directory
Definition vfs_types.hpp:71
bool(* symlink)(inode_t *dir, dentry_t *dentry, const char *symname)
create a symbolic link
Definition vfs_types.hpp:87
bool(* rename)(inode_t *old_dir, dentry_t *old_dentry, inode_t *new_dir, dentry_t *new_dentry)
rename a file
Definition vfs_types.hpp:83
bool(* mknode)(inode_t *dir, dentry_t *dentry, file_type_t type, file_perm_t perm, dev_t dev)
create a new device file
Definition vfs_types.hpp:77
superblock_t * superblock
uid_t uid
u64 modified
u64 accessed
u64 created
file_perm_t perm
const inode_ops_t * ops
bool sgid
size_t size
file_type_t type
const file_ops_t * file_ops
atomic_t refcount
number of references to this inode
bool suid
inode_cache_t cache
bool sticky
gid_t gid
void * private_data
ssize_t nlinks
superblock_t * superblock
dentry_t * root
dentry_t * mountpoint
filesystem_t * fs
bool(* drop_inode)(inode_t *inode)
The inode has zero links and the last reference to the file has been dropped.
long(* sync_inode)(inode_t *inode)
flush the inode to disk
dentry_t * root
const superblock_ops_t * ops
filesystem_t * fs
Definition vfs_types.hpp:50
mos::string name
Definition vfs_types.hpp:53
as_linked_list
Definition vfs_types.hpp:51
file_type_t type
Definition vfs_types.hpp:54
ino_t ino
Definition vfs_types.hpp:52
size_t read_offset
user has read up to this offset, start from this offset when reading more entries
Definition vfs_types.hpp:61
size_t n_count
number of entries in the list
Definition vfs_types.hpp:60
Definition mm.hpp:60
constexpr auto mWarn
Definition syslog.hpp:154
static char buffer[2048]
ssize_t off_t
Definition types.h:80
u32 uid_t
Definition types.h:71
u32 gid_t
Definition types.h:72
unsigned long long u64
Definition types.h:19
signed long ssize_t
Definition types.h:79
std::atomic_size_t atomic_t
Definition types.hpp:11
#define MOS_ENUM_FLAGS(enum, flags)
Definition types.hpp:232
mos::string dentry_name(const dentry_t *dentry)
void dentry_iterator_op(vfs_listdir_state_t *state, u64 ino, mos::string_view name, file_type_t type)
Definition vfs_types.hpp:64