Tenok
A Linux-like Real-Time Operating System for Robotics and Internet of Things
fs.h
Go to the documentation of this file.
1 
4 #ifndef __FS_H__
5 #define __FS_H__
6 
7 #include <dirent.h>
8 #include <stdbool.h>
9 #include <stddef.h>
10 #include <stdint.h>
11 #include <string.h>
12 #include <sys/stat.h>
13 #include <sys/types.h>
14 #include <time.h>
15 
16 #include <common/list.h>
17 #include <kernel/time.h>
18 #include <kernel/wait.h>
19 
20 #include "kconfig.h"
21 
22 #define RDEV_ROOTFS 0
23 
24 /* Mode of a new file, the one a Linux system gives under a umask of 022 */
25 #define FS_DEFAULT_FILE_MODE 0644
26 #define FS_DEFAULT_DIR_MODE 0755
27 
28 /* Withheld from the mode a task asks for, which is what turns the 0666 of
29  * an ordinary creation into the 0644 of an ordinary file
30  */
31 #define FS_DEFAULT_UMASK 022
32 
33 /* Every thread has a pipe the file system daemon answers it through. It is
34  * reached by the thread that owns it and by the daemon, never by a program,
35  * so it carries no descriptor number
36  */
37 extern struct file *thread_pipe[THREAD_MAX];
38 
39 /* +---------------------------+
40  * | File table layout |
41  * +-----------+---------------+
42  * | 0 | stdin |
43  * +-----------+---------------+
44  * | 1 | stdout |
45  * +-----------+---------------+
46  * | 2 | stderr |
47  * +-----------+---------------+
48  * | 3 | File 1 |
49  * +-----------+---------------+
50  * | ... | ... |
51  * +-----------+---------------+
52  * | M + 2 | File M |
53  * +-----------+---------------+
54  *
55  * M = OPEN_MAX
56  */
57 
58 typedef void (*drv_init_func_t)(void);
59 
60 enum {
61  FS_CREATE_FILE = 1,
62  FS_OPEN_FILE = 2,
63  FS_OPEN_DIR = 3,
64  FS_MOUNT = 4,
65  FS_GET_CWD = 5,
66  FS_CHANGE_DIR = 6,
67  FS_MAKE_DIR = 7,
68  FS_REMOVE = 8,
69  FS_STAT = 9,
70  FS_RENAME = 10,
71  FS_CHANGE_MODE = 11,
72  FS_CHANGE_TIME = 12,
73 } FS_SERVER_CMDS;
74 
75 struct super_block {
76  bool s_rd_only; /* Read-only flag */
77  uint32_t s_blk_cnt; /* number of the used blocks */
78  uint32_t s_inode_cnt; /* number of the used inodes */
79  uint64_t s_sb_addr; /* Start address of the super block */
80  uint64_t s_ino_addr; /* Start address of the inode table */
81  uint64_t s_blk_addr; /* Start address of the blocks region */
82 };
83 
84 /* Block header will be placed at the top of every blocks of regular files */
85 struct block_header {
86  /* Virtual address of the next block */
87  uint32_t b_next;
88  uint32_t reserved;
89 };
90 
91 struct mount {
92  struct file *dev_file; /* Driver file of the mounted device */
93  struct super_block super_blk; /* Super block of the mounted device */
94 };
95 
96 /* index node */
97 struct inode {
98  /* File type and permission bits: S_IFREG | 0644, and so on */
99  uint16_t i_mode;
100  /* The device on which the file is mounted */
101  uint8_t i_rdev;
102  /* The mounted file is loaded into the rootfs or not */
103  bool i_sync;
104  /* inode number */
105  uint32_t i_ino;
106  /* inode number of the parent directory */
107  uint32_t i_parent;
108  /* File descriptor number */
109  uint32_t i_fd;
110  /* File size (bytes) */
111  uint32_t i_size;
112  /* block_numbers = file_size / (block_size - block_header_size) */
113  uint32_t i_blocks;
114  /* Virtual address for accessing the storage */
115  uint32_t i_data;
116  /* List head of the dentry table */
117  struct list_head i_dentry;
118  /* Seconds since the epoch, last written. Thirty two of them reach 2106 */
119  uint32_t i_mtime;
120  uint32_t reserved[2];
121 };
122 
123 /* Directory entry */
124 struct dentry {
125  /* File name */
126  char d_name[NAME_MAX];
127  /* The inode of the file */
128  uint32_t d_inode;
129  /* The inode of the parent directory */
130  uint32_t d_parent;
131  /* List head of the dentry */
132  struct list_head d_list;
133  uint32_t reserved[2];
134 };
135 
136 struct file {
137  struct inode *f_inode;
138  struct file_operations *f_op;
139  uint32_t f_events;
140  int f_flags;
141  /* Where the next read or write starts. A regular file keeps its own
142  * position in struct reg_file and ignores this one; it is what gives a
143  * device file, /dev/rom for instance, a position of its own.
144  */
145  off_t f_pos;
146  struct list_head list;
147 };
148 
150  off_t (*lseek)(struct file *filp, off_t offset, int whence);
151  ssize_t (*read)(struct file *filp, char *buf, size_t size, off_t offset);
152  ssize_t (*write)(struct file *filp,
153  const char *buf,
154  size_t size,
155  off_t offset);
156  int (*ioctl)(struct file *, unsigned int cmd, unsigned long arg);
157  int (*open)(struct inode *inode, struct file *file);
158 };
159 
160 struct fdtable {
161  /* The flags the file was opened with */
162  int flags;
163  /* The flags of the descriptor itself, which is FD_CLOEXEC and nothing
164  * else. They are kept apart from the ones above because FD_CLOEXEC and
165  * O_WRONLY are both one, and a descriptor would otherwise report the
166  * access mode as the close on exec bit and lose it when the bit is set.
167  */
168  int fd_flags;
169  struct file *file;
170 };
171 
172 void rootfs_init(void);
173 
174 void link_stdin_dev(char *path);
175 void link_stdout_dev(char *path);
176 void link_stderr_dev(char *path);
177 
178 int register_chrdev(char *name, struct file_operations *fops);
179 int register_blkdev(char *name, struct file_operations *fops);
180 
181 bool file_is_opened(struct file *filp);
182 
183 int fs_read_dir(DIR *dirp, struct dirent *dirent);
184 uint32_t fs_get_block_addr(struct inode *inode, int blk_index);
185 uint32_t fs_file_append_block(struct inode *inode);
186 
187 /* What an inode stamps itself with. The clock reads zero until it is set */
188 static inline uint32_t fs_now(void)
189 {
190  struct timespec tp;
191 
192  get_sys_time(&tp);
193 
194  return (uint32_t) tp.tv_sec;
195 }
196 
197 /* Fill in a stat buffer from an inode. Tenok tracks no ownership and no link
198  * count, so those fields read back as zero
199  */
200 static inline void fs_fill_stat(struct stat *statbuf, const struct inode *inode)
201 {
202  memset(statbuf, 0, sizeof(*statbuf));
203 
204  statbuf->st_dev = inode->i_rdev;
205  statbuf->st_ino = inode->i_ino;
206  statbuf->st_mode = inode->i_mode;
207  statbuf->st_nlink = 1;
208  statbuf->st_rdev = inode->i_rdev;
209  statbuf->st_size = inode->i_size;
210  statbuf->st_blksize = FS_BLK_SIZE;
211  statbuf->st_blocks = inode->i_blocks;
212  statbuf->st_mtim.tv_sec = inode->i_mtime;
213 }
214 
215 void request_create_file(int thread_id, const char *path, mode_t mode);
216 void request_mkdir(int thread_id, const char *path, mode_t mode);
217 void request_chmod(int thread_id, const char *path, mode_t mode);
218 void request_utime(int thread_id, const char *path, uint32_t mtime);
219 void request_remove(int thread_id, const char *path, bool rm_dir);
220 void request_stat(int thread_id, const char *path, struct stat *statbuf);
221 void request_rename(int thread_id, const char *oldpath, const char *newpath);
222 void request_open_file(int thread_id, const char *path);
223 void request_open_directory(int reply_fd, const char *path);
224 void request_mount(int thread_id, const char *source, const char *target);
225 void request_getcwd(int thread_id, char *buf, size_t len);
226 void request_chdir(int thread_id, const char *path);
227 
228 void filesysd(void);
229 
230 void fs_print_inode_bitmap(void);
231 void fs_print_block_bitmap(void);
232 
233 #endif
int open(const char *pathname, int flags,...)
Open the file specified by the pathname.
Definition: file.c:36
void fs_print_inode_bitmap(void)
Definition: fs.c:1772
int ioctl(int fd, unsigned long request,...)
Perform device-specific control.
Definition: file.c:147
Definition: fs.h:85
Definition: fs.h:124
Definition: dirent.h:29
Definition: dirent.h:36
Definition: fs.h:160
Definition: fs.h:149
Definition: fs.h:136
Definition: fs.h:97
Definition: list.h:111
Definition: fs.h:91
Definition: stat.h:46
Definition: fs.h:75
Definition: time.h:16
ssize_t write(int fd, const void *buf, size_t count)
Write up to count bytes from the buffer starting at buf to the file referred to by the file descripto...
Definition: file.c:132
ssize_t read(int fd, void *buf, size_t count)
Attempt to read up to count bytes from file descriptor fd into the buffer starting at buf.
Definition: file.c:117