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.h>
8#include <mos/lib/sync/mutex.h>
9#include <mos/types.h>
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
18should_inline const file_ops_t *file_get_ops(file_t *file)
19{
20 if (!file)
21 goto error;
22
23 if (!file->dentry)
24 goto error;
25
26 if (!file->dentry->inode)
27 goto error;
28
29 if (!file->dentry->inode->file_ops)
30 goto error;
31
32 return file->dentry->inode->file_ops;
33
34error:
35 pr_warn("no file_ops for file %p", (void *) file);
36 return NULL;
37}
38
39extern dentry_t *root_dentry;
40
41/**
42 * @brief Open an directory dentry
43 *
44 * @param entry
45 * @param created
46 * @param read
47 * @param write
48 * @param exec
49 * @param truncate
50 * @return file_t
51 */
52file_t *vfs_do_open_dentry(dentry_t *entry, bool created, bool read, bool write, bool exec, bool truncate);
53
54void vfs_register_filesystem(filesystem_t *fs);
55
56/**
57 * @brief Mount a filesystem at a given existing path
58 *
59 * @param device The device to mount
60 * @param path The path to mount the filesystem at, this absolute path to a directory must exist
61 * @param fs The filesystem type, e.g. "tmpfs"
62 * @param options The options to pass to the filesystem
63 * @return true if the filesystem was mounted successfully
64 * @return false if the filesystem could not be mounted, see the kernel log for more information
65 */
66long vfs_mount(const char *device, const char *path, const char *fs, const char *options);
67
68/**
69 * @brief Unmount a filesystem at a given path
70 *
71 * @param path The path to the filesystem
72 * @return true
73 * @return false
74 */
75long vfs_unmount(const char *path);
76
77/**
78 * @brief Open a file at a given path
79 *
80 * @param fd The fd of an open directory, or AT_FDCWD to use the current working directory
81 * @param path The path to the file, can be absolute or relative
82 * @param flags open_flags flags
83 * @return file_t* The file, or NULL if the file could not be opened
84 */
85file_t *vfs_openat(int fd, const char *path, open_flags flags);
86
87/**
88 * @brief Stat a file
89 *
90 * @param fd The directory, or a file if FSTATAT_FILE is set
91 * @param path The path to the file
92 * @param flags fstat_flags flags
93 * @param stat The stat struct to store the file information in
94 *
95 * @details
96 * If the FSTATAT_FILE is set, the fd is a file, and the path will be ignored.
97 * If it is not set:
98 * If the path is absolute, the fd will be ignored.
99 * If the path is relative, the fd will be used as the directory to resolve the path from.
100 * If FSTATAT_NOFOLLOW is set, when the path is used, symlinks will not be followed.
101 */
102long vfs_fstatat(fd_t fd, const char *path, file_stat_t *restrict stat, fstatat_flags flags);
103
104/**
105 * @brief Read a symbolic link
106 *
107 * @param dirfd The file descriptor of the directory containing the symbolic link
108 * @param path The path to the symbolic link
109 * @param buf The buffer to store the link in
110 * @param size The size of the buffer
111 * @return size_t The size of the link, or 0 if the link could not be read, or the buffer was too small
112 */
113size_t vfs_readlinkat(fd_t dirfd, const char *path, char *buf, size_t size);
114
115/**
116 * @brief Create a symbolic link
117 *
118 * @param path The path to the symbolic link
119 * @param target The target of the symbolic link
120 * @return true
121 * @return false
122 */
123long vfs_symlink(const char *path, const char *target);
124
125/**
126 * @brief Create a directory
127 *
128 * @param path The path to the directory
129 * @return true
130 * @return false
131 */
132long vfs_mkdir(const char *path);
133long vfs_rmdir(const char *path);
134
135/**
136 * @brief Get the content of a directory
137 *
138 * @param io The io object of a file_t, must be a directory and opened with FILE_OPEN_READ
139 * @param buf The buffer to store the directory entries in
140 * @param size The size of the buffer
141 *
142 * @return size_t The number of bytes read, or 0 if the end of the directory was reached
143 */
144size_t vfs_list_dir(io_t *io, void *buf, size_t size);
145
146/**
147 * @brief Change the current working directory
148 *
149 * @param dirfd The file descriptor of the directory to change to
150 * @param path The path to the directory, relative to the dirfd
151 * @return long 0 on success, or errno on failure
152 */
153long vfs_chdirat(fd_t dirfd, const char *path);
154
155/**
156 * @brief Get the current working directory
157 *
158 * @param buf The buffer to store the path in
159 * @param size The size of the buffer
160 * @return ssize_t The size of the path, or 0 if the buffer was too small
161 */
162ssize_t vfs_getcwd(char *buf, size_t size);
163
164/**
165 * @brief Change the permissions of a file
166 *
167 * @param fd The directory, or a file if FSTATAT_FILE is set
168 * @param path The path to the file
169 * @param perm The new permissions
170 * @param flags fstat_flags flags
171 * @return long 0 on success, or errno on failure
172 */
173long vfs_fchmodat(fd_t fd, const char *path, int perm, int flags);
174
175/**
176 * @brief Remove the name of a file, and possibly the file itself
177 *
178 * @param dirfd The file descriptor of the directory containing the file (or the file itself if AT_EMPTY_PATH is set)
179 * @param path The path to the file
180 * @return long 0 on success, or errno on failure
181 */
182long vfs_unlinkat(fd_t dirfd, const char *path);
183
184/**
185 * @brief Synchronize a file with the filesystem
186 *
187 * @param io The io object of a file_t
188 * @param sync_metadata Whether to sync the metadata
189 * @param start The start of the range to sync
190 * @param end The end of the range to sync
191 * @return long 0 on success, or errno on failure
192 */
193long vfs_fsync(io_t *io, bool sync_metadata, off_t start, off_t end);
194
195/** @} */
196