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