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