1// SPDX-License-Identifier: GPL-3.0-or-later
2// Virtual File System Public API
3
4#pragma once
5
6#include <mos/filesystem/fs_types.h>
7#include <mos/filesystem/vfs_types.hpp>
8#include <mos/lib/sync/mutex.hpp>
9#include <mos/types.hpp>
10
11/**
12 * @defgroup vfs Virtual File System
13 * @brief The Virtual File System (VFS) is an abstraction layer that allows the kernel to
14 * interact with different filesystems in a uniform way.
15 * @{
16 */
17
18extern dentry_t *root_dentry;
19
20/**
21 * @brief Open an directory dentry
22 *
23 * @param entry
24 * @param created
25 * @param read
26 * @param write
27 * @param exec
28 * @param truncate
29 * @return file_t
30 */
31PtrResult<FsBaseFile> vfs_do_open_dentry(dentry_t *entry, bool created, bool read, bool write, bool exec, bool truncate);
32
33void vfs_register_filesystem(filesystem_t *fs);
34
35/**
36 * @brief Mount a filesystem at a given existing path
37 *
38 * @param device The device to mount
39 * @param path The path to mount the filesystem at, this absolute path to a directory must exist
40 * @param fs The filesystem type, e.g. "tmpfs"
41 * @param options The options to pass to the filesystem
42 * @return true if the filesystem was mounted successfully
43 * @return false if the filesystem could not be mounted, see the kernel log for more information
44 */
45PtrResult<void> vfs_mount(const char *device, const char *path, const char *fs, const char *options);
46
47/**
48 * @brief Unmount a filesystem at a given path
49 *
50 * @param path The path to the filesystem
51 * @return true
52 * @return false
53 */
54long vfs_unmount(const char *path);
55
56/**
57 * @brief Open a file at a given path
58 *
59 * @param fd The fd of an open directory, or AT_FDCWD to use the current working directory
60 * @param path The path to the file, can be absolute or relative
61 * @param flags open_flags flags
62 * @return file_t* The file, or NULL if the file could not be opened
63 */
64PtrResult<FsBaseFile> vfs_openat(int fd, mos::string_view path, OpenFlags flags);
65
66/**
67 * @brief Stat a file
68 *
69 * @param fd The directory, or a file if FSTATAT_FILE is set
70 * @param path The path to the file
71 * @param flags fstat_flags flags
72 * @param stat The stat struct to store the file information in
73 *
74 * @details
75 * If the FSTATAT_FILE is set, the fd is a file, and the path will be ignored.
76 * If it is not set:
77 * If the path is absolute, the fd will be ignored.
78 * If the path is relative, the fd will be used as the directory to resolve the path from.
79 * If FSTATAT_NOFOLLOW is set, when the path is used, symlinks will not be followed.
80 */
81long vfs_fstatat(fd_t fd, const char *path, file_stat_t *__restrict stat, FStatAtFlags flags);
82
83/**
84 * @brief Read a symbolic link
85 *
86 * @param dirfd The file descriptor of the directory containing the symbolic link
87 * @param path The path to the symbolic link
88 * @param buf The buffer to store the link in
89 * @param size The size of the buffer
90 * @return size_t The size of the link, or 0 if the link could not be read, or the buffer was too small
91 */
92size_t vfs_readlinkat(fd_t dirfd, const char *path, char *buf, size_t size);
93
94/**
95 * @brief Create a symbolic link
96 *
97 * @param path The path to the symbolic link
98 * @param target The target of the symbolic link
99 * @return true
100 * @return false
101 */
102long vfs_symlink(const char *path, const char *target);
103
104/**
105 * @brief Create a directory
106 *
107 * @param path The path to the directory
108 * @return true
109 * @return false
110 */
111PtrResult<void> vfs_mkdir(const char *path);
112PtrResult<void> vfs_rmdir(const char *path);
113
114/**
115 * @brief Get the content of a directory
116 *
117 * @param io The io object of a file_t, must be a directory and opened with FILE_OPEN_READ
118 * @param buf The buffer to store the directory entries in
119 * @param size The size of the buffer
120 *
121 * @return size_t The number of bytes read, or 0 if the end of the directory was reached
122 */
123size_t vfs_list_dir(IO *io, void *buf, size_t size);
124
125/**
126 * @brief Change the current working directory
127 *
128 * @param dirfd The file descriptor of the directory to change to
129 * @param path The path to the directory, relative to the dirfd
130 * @return long 0 on success, or errno on failure
131 */
132long vfs_chdirat(fd_t dirfd, const char *path);
133
134/**
135 * @brief Get the current working directory
136 *
137 * @param buf The buffer to store the path in
138 * @param size The size of the buffer
139 * @return ssize_t The size of the path, or 0 if the buffer was too small
140 */
141ssize_t vfs_getcwd(char *buf, size_t size);
142
143/**
144 * @brief Change the permissions of a file
145 *
146 * @param fd The directory, or a file if FSTATAT_FILE is set
147 * @param path The path to the file
148 * @param perm The new permissions
149 * @param flags fstat_flags flags
150 * @return long 0 on success, or errno on failure
151 */
152long vfs_fchmodat(fd_t fd, const char *path, int perm, int flags);
153
154/**
155 * @brief Remove the name of a file, and possibly the file itself
156 *
157 * @param dirfd The file descriptor of the directory containing the file (or the file itself if AT_EMPTY_PATH is set)
158 * @param path The path to the file
159 * @return long 0 on success, or errno on failure
160 */
161long vfs_unlinkat(fd_t dirfd, const char *path);
162
163/**
164 * @brief Synchronize a file with the filesystem
165 *
166 * @param io The io object of a file_t
167 * @param sync_metadata Whether to sync the metadata
168 * @param start The start of the range to sync
169 * @param end The end of the range to sync
170 * @return long 0 on success, or errno on failure
171 */
172long vfs_fsync(IO *io, bool sync_metadata, off_t start, off_t end);
173
174/** @} */
175