Initial VFS
[akaros.git] / kern / include / vfs.h
1 /* Barret Rhoden <brho@cs.berkeley.edu>
2  *
3  * VFS, based on the Linux VFS as described in LKD 2nd Ed (Robert Love), which
4  * was probably written by Linus.  A lot of it was changed (reduced) to handle
5  * what ROS will need, at least initially.  Hopefully it'll be similar enough
6  * to interface with ext2 and other Linux FSs.
7  *
8  * struct qstr came directly from Linux.
9  * Lawyers can sort out the copyrights and whatnot with these interfaces and
10  * structures.
11  */
12
13 #ifndef ROS_KERN_VFS_H
14 #define ROS_KERN_VFS_H
15
16 #include <ros/common.h>
17 #include <sys/queue.h>
18 #include <arch/bitmask.h>
19 #include <atomic.h>
20 #include <timing.h>
21
22 // TODO: temp typedefs, etc.  remove when we support this stuff.
23 typedef int dev_t;
24 typedef int kdev_t;
25 typedef int ino_t;
26 typedef long off_t; // out there in other .h's, but not in the kernel yet
27 struct block_device     {int x;};
28 struct io_writeback     {int x;};
29 struct event_poll {int x;};
30 struct poll_table_struct {int x;};
31 // end temp typedefs
32
33 struct super_block;
34 struct super_operations;
35 struct dentry;
36 struct dentry_operations;
37 struct inode;
38 struct inode_operations;
39 struct file;
40 struct file_operations;
41 struct file_system_type;
42 struct vm_area_struct;
43 struct vfsmount;
44
45 /* part of the kernel interface, ripped from man pages, ought to work. */
46 // TODO: eventually move this to ros/fs.h or something.
47 #define MAX_FILENAME 255
48 struct dirent { // or maybe something else to not conflict with userspace
49         ino_t          d_ino;       /* inode number */
50         off_t          d_off;       /* offset to the next dirent */
51         unsigned short d_reclen;    /* length of this record */
52         char           d_name[MAX_FILENAME + 1]; /* filename */
53 };
54
55 struct iovec {
56     void *iov_base;
57     size_t iov_len;
58 };
59
60 /* List def's we need */
61 TAILQ_HEAD(sb_tailq, super_block);
62 TAILQ_HEAD(dentry_tailq, dentry);
63 SLIST_HEAD(dentry_slist, dentry);
64 TAILQ_HEAD(inode_tailq, inode);
65 SLIST_HEAD(inode_slist, inode);
66 TAILQ_HEAD(file_tailq, file);
67 TAILQ_HEAD(io_wb_tailq, io_writeback);
68 TAILQ_HEAD(event_poll_tailq, event_poll);
69 TAILQ_HEAD(vfsmount_tailq, vfsmount);
70
71 /* Linux's quickstring - saves recomputing the hash and length. */
72 struct qstr {
73     unsigned int hash;
74     unsigned int len;
75     const unsigned char *name;
76 };
77
78
79 /* Superblock: Specific instance of a mounted filesystem.  All synchronization
80  * is done with the one spinlock. */
81
82 extern struct sb_tailq super_blocks;                    /* list of all sbs */
83 extern spinlock_t super_blocks_lock;
84
85 struct super_block {
86         TAILQ_ENTRY(superblock)         s_list;                 /* list of all sbs */
87         dev_t                                           s_dev;                  /* id */
88         unsigned long                           s_blocksize;
89         bool                                            s_dirty;
90         unsigned long long                      s_maxbytes;             /* max file size */
91         struct file_system_type         *s_type;
92         struct super_operations         *s_op;
93         unsigned long                           s_flags;
94         unsigned long                           s_magic;
95         struct vfsmount                         *s_mount;               /* vfsmount point */
96         spinlock_t                                      s_lock;                 /* used for all sync */
97         atomic_t                                        s_refcnt;
98         bool                                            s_syncing;              /* currently syncing metadata */
99         struct inode_tailq                      s_dirty_i;              /* dirty inodes */
100         struct io_wb_tailq                      s_io_wb;                /* writebacks */
101         struct dentry_slist                     s_anon_d;               /* anonymous dentries */
102         struct file_tailq                       s_files;                /* assigned files */
103         struct block_device                     *s_bdev;
104         TAILQ_ENTRY(superblock)         s_instances;    /* list of sbs of this fs type*/
105         char                                            s_name[32];
106         void                                            *s_fs_info;
107 };
108
109 struct super_operations {
110         struct inode *(*alloc_inode) (struct super_block *sb);
111         void (*destroy_inode) (struct inode *);         /* dealloc.  might need more */
112         void (*read_inode) (struct inode *);
113         void (*dirty_inode) (struct inode *);
114         void (*write_inode) (struct inode *, int);
115         void (*delete_inode) (struct inode *);          /* deleted from disk */
116         void (*put_super) (struct super_block *);       /* releases sb */
117         void (*write_super) (struct super_block *);     /* sync with sb on disk */
118         int (*sync_fs) (struct super_block *, int);
119         int (*remount_fs) (struct super_block *, int *, char *);
120         void (*umount_begin) (struct super_block *);/* called by NFS */
121 };
122
123 /* this will create/init a SB for a FS */
124 void alloc_super(void);
125
126 /* Inode: represents a specific file */
127 struct inode {
128         SLIST_ENTRY(inode)                      i_hash;                 /* inclusion in a hash table */
129         TAILQ_ENTRY(inode)                      i_list;                 /* all inodes in the FS */
130         struct dentry_tailq                     i_dentry;               /* all dentries pointing here*/
131         unsigned long                           i_ino;
132         atomic_t                                        i_refcnt;
133         int                                                     i_mode;
134         unsigned int                            i_nlink;                /* hard links */
135         uid_t                                           i_uid;
136         gid_t                                           i_gid;
137         kdev_t                                          i_rdev;                 /* real device node */
138         size_t                                          i_size;
139         struct timespec                         i_atime;
140         struct timespec                         i_mtime;
141         struct timespec                         i_ctime;
142         unsigned long                           i_blksize;
143         unsigned long                           i_blocks;               /* filesize in blocks */
144         spinlock_t                                      i_lock;
145         struct inode_operations         *i_ops;
146         struct file_operations          *i_fop;
147         struct super_block                      *i_sb;
148         //struct address_space          *i_mapping;             /* linux mapping structs */
149         //struct address_space          i_data;                 /* rel page caches */
150         union {
151                 struct pipe_inode_info          *i_pipe;
152                 struct block_device                     *i_bdev;
153                 struct char_device                      *i_cdev;
154         };
155         unsigned long                           i_state;
156         unsigned long                           dirtied_when;   /* in jiffies */
157         unsigned int                            i_flags;                /* filesystem flags */
158         bool                                            i_socket;
159         atomic_t                                        i_writecount;   /* number of writers */
160         void                                            *i_fs_info;
161 };
162
163 struct inode_operations {
164         int (*create) (struct inode *, struct dentry *, int);
165         struct dentry *(*lookup) (struct inode *, struct dentry *);
166         int (*link) (struct dentry *, struct inode *, struct dentry *);
167         int (*unlink) (struct inode *, struct dentry *);
168         int (*symlink) (struct inode *, struct dentry *, const char *);
169         int (*mkdir) (struct inode *, struct dentry *, int);
170         int (*rmdir) (struct inode *, struct dentry *);
171         int (*mknod) (struct inode *, struct dentry *, int, dev_t);
172         int (*rename) (struct inode *, struct dentry *,
173                        struct inode *, struct dentry *);
174         int (*readlink) (struct dentry *, char *, int);
175         void (*truncate) (struct inode *);                      /* set i_size before calling */
176         int (*permission) (struct inode *, int);
177 };
178
179 // TODO: might want a static dentry for /, though processes can get to their
180 // root via their fs_struct or even the default namespace.
181 // TODO: should have a dentry_htable or something.  we have the structs built
182 // in to the dentry right now (linux style).  Need some form of locking too
183
184 #define DNAME_INLINE_LEN 32
185 /* Dentry: in memory object, corresponding to an element of a path.  E.g. /,
186  * usr, bin, and vim are all dentries.  All have inodes.  Vim happens to be a
187  * file instead of a directory.
188  * They can be used (valid inode, currently in use), unused (valid, not used),
189  * or negative (not a valid inode (deleted or bad path), but kept to resolve
190  * requests quickly.  If none of these, dealloc it back to the slab cache.
191  * Unused and negatives go in the LRU list. */
192 struct dentry {
193         atomic_t                                        d_refcnt;               /* don't discard when 0 */
194         unsigned long                           d_vfs_flags;    /* dentry cache flags */
195         spinlock_t                                      d_lock;
196         struct inode                            *d_inode;
197         TAILQ_ENTRY(dentry)                     d_lru;                  /* unused list */
198         struct dentry_tailq                     d_child;
199         struct dentry_tailq                     d_subdirs;
200         unsigned long                           d_time;                 /* revalidate time (jiffies)*/
201         struct dentry_operations        *d_op;
202         struct super_block                      *d_sb;
203         unsigned int                            d_flags;
204         bool                                            d_mount_point;
205         void                                            *d_fs_info;
206         struct dentry                           *d_parent;
207         struct qstr                                     d_name;                 /* pts to iname and holds hash*/
208         SLIST_ENTRY(dentry)                     d_hash;                 /* link for the dcache */
209         struct dentry_slist                     *d_bucket;              /* hash bucket of this dentry */
210         unsigned char                           d_iname[DNAME_INLINE_LEN];
211 };
212
213 /* not sure yet if we want to call delete when refcnt == 0 (move it to LRU) or
214  * when its time to remove it from the dcache. */
215 struct dentry_operations {
216         int (*d_revalidate) (struct dentry *, int);     /* usually a noop */
217         int (*d_hash) (struct dentry *, struct qstr *);
218         int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
219         int (*d_delete) (struct dentry *);
220         void (*d_iput) (struct dentry *, struct inode *);
221 };
222
223 /* File: represents a file opened by a process. */
224 struct file {
225         TAILQ_ENTRY(file)                       f_list;                 /* list of all files */
226         struct dentry                           *f_dentry;
227         struct vfsmount                         *f_vfsmnt;
228         struct file_operations          *f_op;
229         atomic_t                                        f_refcnt;
230         unsigned int                            f_flags;
231         int                                                     f_mode;
232         off_t                                           f_pos;                  /* offset / file pointer */
233         unsigned int                            f_uid;
234         unsigned int                            f_gid;
235         int                                                     f_error;
236         struct event_poll_tailq         f_ep_links;
237         spinlock_t                                      f_ep_lock;
238         void                                            *f_fs_info;             /* tty driver hook */
239         //struct address_space          *f_mapping;             /* page cache mapping */
240 };
241
242 struct file_operations {
243         struct module *owner;
244         off_t (*llseek) (struct file *, off_t, int);
245         ssize_t (*read) (struct file *, char *, size_t, off_t *);
246         ssize_t (*write) (struct file *, const char *, size_t, off_t *);
247         int (*readdir) (struct file *, struct dirent *);
248         int (*mmap) (struct file *, struct vm_area_struct *);
249         int (*open) (struct inode *, struct file *);
250         int (*flush) (struct file *);
251         int (*release) (struct inode *, struct file *);
252         int (*fsync) (struct file *, struct dentry *, int);
253         unsigned int (*poll) (struct file *, struct poll_table_struct *);
254         ssize_t (*readv) (struct file *, const struct iovec *, unsigned long,
255                           off_t *);
256         ssize_t (*writev) (struct file *, const struct iovec *, unsigned long,
257                           off_t *);
258         int (*check_flags) (int flags);                         /* most FS's ignore this */
259 };
260
261 /* FS structs.  One of these per FS (e.g., ext2) */
262 struct file_system_type {
263         const char                                      *name;
264         int                                                     fs_flags;
265         struct superblock                       *(*get_sb) (struct file_system_type *, int,
266                                                 char *, void *);
267         void                                            (*kill_sb) (struct super_block *);
268         struct file_system_type         *next;                  /* next FS */
269         struct sb_tailq                         fs_supers;              /* all of this FS's sbs */
270 };
271
272 /* A mount point: more focused on the mounting, and solely in memory, compared
273  * to the SB which is focused on FS definitions (and exists on disc). */
274 struct vfsmount {
275         TAILQ_ENTRY(vfsmount)           mnt_list;               /* might want a hash instead */
276         struct vfsmount                         *mnt_parent;
277         struct dentry                           *mnt_mountpoint;/* do we need both of them? */
278         struct dentry                           *mnt_root;              /* do we need both of them? */
279         struct super_block                      *mnt_sb;
280         struct vfsmount_tailq           mnt_child_mounts;
281         TAILQ_ENTRY(vfsmount)           mnt_child_link;
282         atomic_t                                        mnt_refcnt;
283         int                                                     mnt_flags;
284         char                                            *mnt_devname;
285         struct namespace                        *mnt_namespace;
286 };
287
288 /* Per-process structs */
289 #define NR_OPEN_FILES_DEFAULT 32
290 #define NR_FILE_DESC_DEFAULT 32
291 #define NR_FILE_DESC_MAX 1024
292
293 /* Bitmask for file descriptors, big for when we exceed the initial small.  We
294  * could just use the fd_array to check for openness instead of the bitmask,
295  * but eventually we might want to use the bitmasks for other things (like
296  * which files are close_on_exec. */
297 struct fd_set {
298     uint8_t fds_bits[BYTES_FOR_BITMASK(NR_FILE_DESC_MAX)];
299 };
300 struct small_fd_set {
301     uint8_t fds_bits[BYTES_FOR_BITMASK(NR_FILE_DESC_DEFAULT)];
302 };
303
304 /* All open files for a process */
305 struct files_struct {
306         atomic_t                                        refcnt;
307         spinlock_t                                      lock;
308         int                                                     max_files;              /* max files ptd to by fd */
309         int                                                     max_fdset;              /* max of the current fd_set */
310         int                                                     next_fd;                /* next number available */
311         struct file                                     **fd;                   /* initially pts to fd_array */
312         struct fd_set                           *open_fds;              /* init, pts to open_fds_init */
313         struct small_fd_set                     open_fds_init;
314         struct file                                     *fd_array[NR_OPEN_FILES_DEFAULT];
315 };
316
317 /* Process specific filesysten info */
318 struct fs_struct {
319         atomic_t                                        refcnt;
320         spinlock_t                                      lock;
321         int                                                     umask;
322         struct dentry                           *root;
323         struct dentry                           *pwd;
324 };
325
326 /* Each process can have it's own (eventually), but default to the same NS */
327 struct namespace {
328         atomic_t                                        refcnt;
329         spinlock_t                                      lock;
330         struct vfsmount                         *root;
331         struct vfsmount_tailq           vfsmounts;      /* all vfsmounts in this ns */
332 };
333
334 extern struct namespace default_ns;
335
336 #endif /* ROS_KERN_VFS_H */