Primitive path_lookup()
[akaros.git] / kern / include / vfs.h
index 90c62de..5abbe97 100644 (file)
 #include <arch/bitmask.h>
 #include <atomic.h>
 #include <timing.h>
-#include <page_alloc.h>
+#include <radix.h>
+
+/* ghetto preprocessor hacks (since proc includes vfs) */
+struct page;
+struct vm_region;
 
 // TODO: temp typedefs, etc.  remove when we support this stuff.
 typedef int dev_t;
@@ -31,6 +35,8 @@ struct event_poll {int x;};
 struct poll_table_struct {int x;};
 // end temp typedefs
 
+struct page_map;       /* analagous to linux's address_space object */
+struct page_map_operations;
 struct super_block;
 struct super_operations;
 struct dentry;
@@ -40,7 +46,6 @@ struct inode_operations;
 struct file;
 struct file_operations;
 struct fs_type;
-struct vm_area_struct;
 struct vfsmount;
 
 /* part of the kernel interface, ripped from man pages, ought to work. */
@@ -80,8 +85,11 @@ struct qstr {
 /* Helpful structure to pass around during lookup operations.  At each point,
  * it tracks the the answer, the name of the previous, how deep the symlink
  * following has gone, and the symlink pathnames.  *dentry and *mnt up the
- * refcnt of those objects too, so whoever receives this will need to decref.
- * We'll see how this works out... */
+ * refcnt of those objects too, so whoever 'receives; this will need to decref.
+ * This is meant to be pinning only the 'answer' to a path_lookup, and not the
+ * intermediate steps.  The intermediates get pinned due to the existence of
+ * their children in memory.  Internally, the VFS will refcnt any item whenever
+ * it is in this struct. */
 #define MAX_SYMLINK_DEPTH 6 // arbitrary.
 struct nameidata {
        struct dentry                           *dentry;                /* dentry of the obj */
@@ -94,6 +102,46 @@ struct nameidata {
        int                                                     intent;                 /* access type for the file */
 };
 
+/* nameidata lookup flags and access type fields */
+#define LOOKUP_FOLLOW          0x01    /* if the last is a symlink, follow */
+#define LOOKUP_DIRECTORY       0x02    /* last component must be a directory */
+#define LOOKUP_CONTINUE        0x04    /* still filenames to go */
+#define LOOKUP_PARENT          0x08    /* lookup the dir that includes the item */
+#define LOOKUP_OPEN            0x10    /* intent is to open a file */
+#define LOOKUP_CREATE          0x11    /* create a file if it doesn't exist */
+#define LOOKUP_ACCESS          0x12    /* access / check user permissions */
+
+/* Every object that has pages, like an inode or the swap (or even direct block
+ * devices) has a page_map, tracking which of its pages are currently in memory.
+ * It is a map, per object, from index to physical page frame. */
+struct page_map {
+       struct inode                            *pm_host;               /* inode of the owner, if any */
+       struct radix_tree                       pm_tree;                /* tracks present pages */
+       spinlock_t                                      pm_tree_lock;   /* spinlock => we can't block */
+       unsigned long                           pm_num_pages;   /* how many pages are present */
+       struct page_map_operations      *pm_op;
+       unsigned int                            pm_flags;
+       /*... and private lists, backing block dev info, other mappings, etc. */
+};
+
+/* Operations performed on a page_map.  These are usually FS specific, which
+ * get assigned when the inode is created.
+ * Will fill these in as they are created/needed/used. */
+struct page_map_operations {
+       int (*readpage) (struct file *, struct page *); /* read from backing store*/
+/*     readpages: read a list of pages
+       writepage: write from a page to its backing store
+       writepages: write a list of pages
+       sync_page: start the IO of already scheduled ops
+       set_page_dirty: mark the given page dirty
+       prepare_write: prepare to write (disk backed pages)
+       commit_write: complete a write (disk backed pages)
+       bmap: get a logical block number from a file block index
+       invalidate page: invalidate, part of truncating
+       release page: prepare to release 
+       direct_io: bypass the page cache */
+};
+
 /* Superblock: Specific instance of a mounted filesystem.  All synchronization
  * is done with the one spinlock. */
 
@@ -149,7 +197,8 @@ struct inode {
        struct dentry_tailq                     i_dentry;               /* all dentries pointing here*/
        unsigned long                           i_ino;
        atomic_t                                        i_refcnt;
-       int                                                     i_mode;
+       int                                                     i_mode;                 /* access mode */
+       unsigned short                          i_type;                 /* file type */
        unsigned int                            i_nlink;                /* hard links */
        uid_t                                           i_uid;
        gid_t                                           i_gid;
@@ -164,8 +213,8 @@ struct inode {
        struct inode_operations         *i_op;
        struct file_operations          *i_fop;
        struct super_block                      *i_sb;
-       //struct address_space          *i_mapping;             /* linux mapping structs */
-       //struct address_space          i_data;                 /* rel page caches */
+       struct page_map                         *i_mapping;             /* usually points to i_data */
+       struct page_map                         i_pm;                   /* this inode's page cache */
        union {
                struct pipe_inode_info          *i_pipe;
                struct block_device                     *i_bdev;
@@ -173,7 +222,7 @@ struct inode {
        };
        unsigned long                           i_state;
        unsigned long                           dirtied_when;   /* in jiffies */
-       unsigned int                            i_flags;                /* filesystem flags */
+       unsigned int                            i_flags;                /* filesystem mount flags */
        bool                                            i_socket;
        atomic_t                                        i_writecount;   /* number of writers */
        void                                            *i_fs_info;
@@ -239,6 +288,11 @@ struct dentry_operations {
        void (*d_iput) (struct dentry *, struct inode *);
 };
 
+/* Yanked from glibc-2.11.1/posix/unistd.h */
+#define SEEK_SET   0   /* Seek from beginning of file.  */
+#define SEEK_CUR   1   /* Seek from current position.  */
+#define SEEK_END   2   /* Seek from end of file.  */
+
 /* File: represents a file opened by a process. */
 struct file {
        TAILQ_ENTRY(file)                       f_list;                 /* list of all files */
@@ -255,7 +309,7 @@ struct file {
        struct event_poll_tailq         f_ep_links;
        spinlock_t                                      f_ep_lock;
        void                                            *f_fs_info;             /* tty driver hook */
-       //struct address_space          *f_mapping;             /* page cache mapping */
+       struct page_map                         *f_mapping;             /* page cache mapping */
 
        /* Ghetto appserver support */
        int fd; // all it contains is an appserver fd (for pid 0, aka kernel)
@@ -268,7 +322,7 @@ struct file_operations {
        ssize_t (*read) (struct file *, char *, size_t, off_t *);
        ssize_t (*write) (struct file *, const char *, size_t, off_t *);
        int (*readdir) (struct file *, struct dirent *);
-       int (*mmap) (struct file *, struct vm_area_struct *);
+       int (*mmap) (struct file *, struct vm_region *);
        int (*open) (struct inode *, struct file *);
        int (*flush) (struct file *);
        int (*release) (struct inode *, struct file *);
@@ -327,7 +381,6 @@ struct small_fd_set {
 
 /* All open files for a process */
 struct files_struct {
-       atomic_t                                        refcnt;
        spinlock_t                                      lock;
        int                                                     max_files;              /* max files ptd to by fd */
        int                                                     max_fdset;              /* max of the current fd_set */
@@ -340,7 +393,6 @@ struct files_struct {
 
 /* Process specific filesysten info */
 struct fs_struct {
-       atomic_t                                        refcnt;
        spinlock_t                                      lock;
        int                                                     umask;
        struct dentry                           *root;
@@ -370,15 +422,41 @@ extern struct kmem_cache *dentry_kcache;
 extern struct kmem_cache *inode_kcache;
 extern struct kmem_cache *file_kcache;
 
-/* VFS Functions */
+/* Misc VFS functions */
 void vfs_init(void);
 void qstr_builder(struct dentry *dentry, char *l_name);
+int path_lookup(char *path, int flags, struct nameidata *nd);
+void path_release(struct nameidata *nd);
+
+/* Superblock functions */
 struct super_block *get_sb(void);
 void init_sb(struct super_block *sb, struct vfsmount *vmnt,
              struct dentry_operations *d_op, unsigned long root_ino,
              void *d_fs_info);
+
+/* Dentry Functions */
 struct dentry *get_dentry(struct super_block *sb, struct dentry *parent,
                           char *name);
 void dcache_put(struct dentry *dentry);
 
+/* Inode Functions */
+int check_perms(struct inode *inode, int access_mode);
+
+/* File functions */
+ssize_t generic_file_read(struct file *file, char *buf, size_t count,
+                          off_t *offset);
+ssize_t generic_file_write(struct file *file, const char *buf, size_t count,
+                           off_t *offset);
+
+/* Page cache functions */
+struct page *pm_find_page(struct page_map *pm, unsigned long index);
+int pm_insert_page(struct page_map *pm, unsigned long index, struct page *page);
+int pm_remove_page(struct page_map *pm, struct page *page);
+int file_load_page(struct file *file, unsigned long index, struct page **pp);
+
+/* Process-related File management functions */
+struct file *get_file_from_fd(struct files_struct *open_files, int fd);
+struct file *put_file_from_fd(struct files_struct *open_files, int file_desc);
+int insert_file(struct files_struct *open_files, struct file *file);
+
 #endif /* ROS_KERN_VFS_H */