CPIO parsing, kfs building, vfs tweaks
[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 #define FS_I_FILE                               0x01
142 #define FS_I_DIR                                0x02
143
144 /* Inode: represents a specific file */
145 struct inode {
146         SLIST_ENTRY(inode)                      i_hash;                 /* inclusion in a hash table */
147         TAILQ_ENTRY(inode)                      i_sb_list;              /* all inodes in the FS */
148         TAILQ_ENTRY(inode)                      i_list;                 /* describes state (dirty) */
149         struct dentry_tailq                     i_dentry;               /* all dentries pointing here*/
150         unsigned long                           i_ino;
151         atomic_t                                        i_refcnt;
152         int                                                     i_mode;
153         unsigned int                            i_nlink;                /* hard links */
154         uid_t                                           i_uid;
155         gid_t                                           i_gid;
156         kdev_t                                          i_rdev;                 /* real device node */
157         size_t                                          i_size;
158         struct timespec                         i_atime;
159         struct timespec                         i_mtime;
160         struct timespec                         i_ctime;
161         unsigned long                           i_blksize;
162         unsigned long                           i_blocks;               /* filesize in blocks */
163         spinlock_t                                      i_lock;
164         struct inode_operations         *i_op;
165         struct file_operations          *i_fop;
166         struct super_block                      *i_sb;
167         //struct address_space          *i_mapping;             /* linux mapping structs */
168         //struct address_space          i_data;                 /* rel page caches */
169         union {
170                 struct pipe_inode_info          *i_pipe;
171                 struct block_device                     *i_bdev;
172                 struct char_device                      *i_cdev;
173         };
174         unsigned long                           i_state;
175         unsigned long                           dirtied_when;   /* in jiffies */
176         unsigned int                            i_flags;                /* filesystem flags */
177         bool                                            i_socket;
178         atomic_t                                        i_writecount;   /* number of writers */
179         void                                            *i_fs_info;
180 };
181
182 struct inode_operations {
183         int (*create) (struct inode *, struct dentry *, int, struct nameidata *);
184         struct dentry *(*lookup) (struct inode *, struct dentry *,
185                                   struct nameidata *);
186         int (*link) (struct dentry *, struct inode *, struct dentry *);
187         int (*unlink) (struct inode *, struct dentry *);
188         int (*symlink) (struct inode *, struct dentry *, const char *);
189         int (*mkdir) (struct inode *, struct dentry *, int);
190         int (*rmdir) (struct inode *, struct dentry *);
191         int (*mknod) (struct inode *, struct dentry *, int, dev_t);
192         int (*rename) (struct inode *, struct dentry *,
193                        struct inode *, struct dentry *);
194         int (*readlink) (struct dentry *, char *, size_t);
195         int (*follow_link) (struct dentry *, struct nameidata *);
196         int (*put_link) (struct dentry *, struct nameidata *);
197         void (*truncate) (struct inode *);                      /* set i_size before calling */
198         int (*permission) (struct inode *, int, struct nameidata *);
199 };
200
201 #define DNAME_INLINE_LEN 32
202 /* Dentry: in memory object, corresponding to an element of a path.  E.g. /,
203  * usr, bin, and vim are all dentries.  All have inodes.  Vim happens to be a
204  * file instead of a directory.
205  * They can be used (valid inode, currently in use), unused (valid, not used),
206  * or negative (not a valid inode (deleted or bad path), but kept to resolve
207  * requests quickly.  If none of these, dealloc it back to the slab cache.
208  * Unused and negatives go in the LRU list. */
209 struct dentry {
210         atomic_t                                        d_refcnt;               /* don't discard when 0 */
211         unsigned long                           d_flags;                /* dentry cache flags */
212         spinlock_t                                      d_lock;
213         struct inode                            *d_inode;
214         TAILQ_ENTRY(dentry)                     d_lru;                  /* unused list */
215         TAILQ_ENTRY(dentry)                     d_alias;                /* linkage for i_dentry */
216         struct dentry_tailq                     d_subdirs;
217         TAILQ_ENTRY(dentry)                     d_subdirs_link;
218         unsigned long                           d_time;                 /* revalidate time (jiffies)*/
219         struct dentry_operations        *d_op;
220         struct super_block                      *d_sb;
221         bool                                            d_mount_point;  /* is an FS mounted over here */
222         struct vfsmount                         *d_mounted_fs;  /* fs mounted here */
223         struct dentry                           *d_parent;
224         struct qstr                                     d_name;                 /* pts to iname and holds hash*/
225         SLIST_ENTRY(dentry)                     d_hash;                 /* link for the dcache */
226         struct dentry_slist                     d_bucket;               /* hash bucket of this dentry */
227         char                                            d_iname[DNAME_INLINE_LEN];
228         void                                            *d_fs_info;
229 };
230
231 /* not sure yet if we want to call delete when refcnt == 0 (move it to LRU) or
232  * when its time to remove it from the dcache. */
233 struct dentry_operations {
234         int (*d_revalidate) (struct dentry *, struct nameidata *);
235         int (*d_hash) (struct dentry *, struct qstr *);
236         int (*d_compare) (struct dentry *, struct qstr *, struct qstr *);
237         int (*d_delete) (struct dentry *);
238         int (*d_release) (struct dentry *);
239         void (*d_iput) (struct dentry *, struct inode *);
240 };
241
242 /* File: represents a file opened by a process. */
243 struct file {
244         TAILQ_ENTRY(file)                       f_list;                 /* list of all files */
245         struct inode                            *f_inode;               /* was dentry.  i prefer this */
246         struct vfsmount                         *f_vfsmnt;
247         struct file_operations          *f_op;
248         atomic_t                                        f_refcnt;
249         unsigned int                            f_flags;
250         int                                                     f_mode;
251         off_t                                           f_pos;                  /* offset / file pointer */
252         unsigned int                            f_uid;
253         unsigned int                            f_gid;
254         int                                                     f_error;
255         struct event_poll_tailq         f_ep_links;
256         spinlock_t                                      f_ep_lock;
257         void                                            *f_fs_info;             /* tty driver hook */
258         //struct address_space          *f_mapping;             /* page cache mapping */
259
260         /* Ghetto appserver support */
261         int fd; // all it contains is an appserver fd (for pid 0, aka kernel)
262         int refcnt;
263         spinlock_t lock;
264 };
265
266 struct file_operations {
267         off_t (*llseek) (struct file *, off_t, int);
268         ssize_t (*read) (struct file *, char *, size_t, off_t *);
269         ssize_t (*write) (struct file *, const char *, size_t, off_t *);
270         int (*readdir) (struct file *, struct dirent *);
271         int (*mmap) (struct file *, struct vm_area_struct *);
272         int (*open) (struct inode *, struct file *);
273         int (*flush) (struct file *);
274         int (*release) (struct inode *, struct file *);
275         int (*fsync) (struct file *, struct dentry *, int);
276         unsigned int (*poll) (struct file *, struct poll_table_struct *);
277         ssize_t (*readv) (struct file *, const struct iovec *, unsigned long,
278                           off_t *);
279         ssize_t (*writev) (struct file *, const struct iovec *, unsigned long,
280                           off_t *);
281         ssize_t (*sendpage) (struct file *, struct page *, int, size_t, off_t, int);
282         int (*check_flags) (int flags);                         /* most FS's ignore this */
283 };
284
285 /* FS structs.  One of these per FS (e.g., ext2) */
286 struct fs_type {
287         const char                                      *name;
288         int                                                     fs_flags;
289         struct super_block                      *(*get_sb) (struct fs_type *, int,
290                                                 char *, struct vfsmount *);
291         void                                            (*kill_sb) (struct super_block *);
292         TAILQ_ENTRY(fs_type)            list;
293         struct sb_tailq                         fs_supers;              /* all of this FS's sbs */
294 };
295
296 /* A mount point: more focused on the mounting, and solely in memory, compared
297  * to the SB which is focused on FS definitions (and exists on disc). */
298 struct vfsmount {
299         TAILQ_ENTRY(vfsmount)           mnt_list;
300         struct vfsmount                         *mnt_parent;
301         struct dentry                           *mnt_mountpoint;/* parent dentry where mnted */
302         struct dentry                           *mnt_root;              /* dentry of root of this fs */
303         struct super_block                      *mnt_sb;
304         struct vfsmount_tailq           mnt_child_mounts;
305         TAILQ_ENTRY(vfsmount)           mnt_child_link;
306         atomic_t                                        mnt_refcnt;
307         int                                                     mnt_flags;
308         char                                            *mnt_devname;
309         struct namespace                        *mnt_namespace;
310 };
311
312 /* Per-process structs */
313 #define NR_OPEN_FILES_DEFAULT 32
314 #define NR_FILE_DESC_DEFAULT 32
315 #define NR_FILE_DESC_MAX 1024
316
317 /* Bitmask for file descriptors, big for when we exceed the initial small.  We
318  * could just use the fd_array to check for openness instead of the bitmask,
319  * but eventually we might want to use the bitmasks for other things (like
320  * which files are close_on_exec. */
321 struct fd_set {
322     uint8_t fds_bits[BYTES_FOR_BITMASK(NR_FILE_DESC_MAX)];
323 };
324 struct small_fd_set {
325     uint8_t fds_bits[BYTES_FOR_BITMASK(NR_FILE_DESC_DEFAULT)];
326 };
327
328 /* All open files for a process */
329 struct files_struct {
330         atomic_t                                        refcnt;
331         spinlock_t                                      lock;
332         int                                                     max_files;              /* max files ptd to by fd */
333         int                                                     max_fdset;              /* max of the current fd_set */
334         int                                                     next_fd;                /* next number available */
335         struct file                                     **fd;                   /* initially pts to fd_array */
336         struct fd_set                           *open_fds;              /* init, pts to open_fds_init */
337         struct small_fd_set                     open_fds_init;
338         struct file                                     *fd_array[NR_OPEN_FILES_DEFAULT];
339 };
340
341 /* Process specific filesysten info */
342 struct fs_struct {
343         atomic_t                                        refcnt;
344         spinlock_t                                      lock;
345         int                                                     umask;
346         struct dentry                           *root;
347         struct dentry                           *pwd;
348 };
349
350 /* Each process can have its own (eventually), but default to the same NS */
351 struct namespace {
352         atomic_t                                        refcnt;
353         spinlock_t                                      lock;
354         struct vfsmount                         *root;
355         struct vfsmount_tailq           vfsmounts;      /* all vfsmounts in this ns */
356 };
357
358 /* Global Structs */
359 extern struct sb_tailq super_blocks;                    /* list of all sbs */
360 extern spinlock_t super_blocks_lock;
361 extern struct fs_type_tailq file_systems;               /* lock this if it's dynamic */
362 extern struct namespace default_ns;
363 // TODO: should have a dentry_htable or something.  we have the structs built
364 // in to the dentry right now (linux style).
365 extern struct dentry_slist dcache;
366 extern spinlock_t dcache_lock;
367
368 /* Slab caches for common objects */
369 extern struct kmem_cache *dentry_kcache;
370 extern struct kmem_cache *inode_kcache;
371 extern struct kmem_cache *file_kcache;
372
373 /* VFS Functions */
374 void vfs_init(void);
375 void qstr_builder(struct dentry *dentry, char *l_name);
376 struct super_block *get_sb(void);
377 void init_sb(struct super_block *sb, struct vfsmount *vmnt,
378              struct dentry_operations *d_op, unsigned long root_ino,
379              void *d_fs_info);
380 struct dentry *get_dentry(struct super_block *sb, struct dentry *parent,
381                           char *name);
382 void dcache_put(struct dentry *dentry);
383
384 #endif /* ROS_KERN_VFS_H */