Orion
Barry Adding pipes e59e4fe (3 years, 1 month ago)
#ifndef KERNEL_VFS_H
#define KERNEL_VFS_H
#include <stdint.h>
#include <stddef.h>
#include <dirent.h>
#include <sys/stat.h>
#include "../spinlock.h"
#include "../mem/paging.h"
#define NFILES 32
#define NAME_MAX 255
#define PATH_MAX 1024
#define MAY_READ 4
#define MAY_WRITE 2
#define MAY_EXECUTE 1
typedef struct FileSystemType FileSystemType;
typedef struct SuperBlock SuperBlock;
typedef struct SuperOps SuperOps;
typedef struct Inode Inode;
typedef struct InodeOps InodeOps;
typedef struct File File;
typedef struct FileOps FileOps;
typedef struct DirEntry DirEntry;
typedef struct Page Page;
typedef struct PageCache PageCache;
typedef struct Custody Custody;
typedef struct CustodyChain CustodyChain;
/* Structure for a File System Type */
struct FileSystemType {
const char *name;
Inode *(*mount)(FileSystemType *, int, const char *, void *);
void (*kill_sb)(SuperBlock *);
pid_t owner;
FileSystemType *next;
};
/* Structure for a Super Block */
struct SuperBlock {
FileSystemType *type;
SuperOps *ops;
Spinlock lock;
Inode *root;
Inode *inodes; /* List of cached inodes */
size_t cachedInodes;
File *back;
void *data;
};
struct SuperOps {
Inode *(*alloc_inode)(SuperBlock *);
int (*write_inode)(Inode *);
void (*delete_inode)(Inode *);
};
/* Structure for an Inode */
struct Inode {
ino_t ino;
refcount_t usage;
unsigned short uid, gid;
mode_t mode;
nlink_t nlink;
uint32_t flags;
size_t size;
dev_t dev;
Spinlock lock;
InodeOps *ops;
FileOps *fileOps;
void *extra;
void (*free_extra)(Inode *);
SuperBlock *super;
union {
DirEntry *dirEntries; /* List of Directory Entries */
PageCache *pages; /* List of Pages */
};
Inode *lnext; /* Next inode in super's list */
};
struct InodeOps {
int (*create)(Inode *, DirEntry *, mode_t);
Inode *(*lookup)(Inode *, const char *);
int (*mkdir)(Inode *, DirEntry *, mode_t);
int (*rmdir)(Inode *, DirEntry *);
int (*mknod)(Inode *, DirEntry *, mode_t, dev_t);
int (*rename) (Inode *, DirEntry *, Inode *, DirEntry *);
};
/* Structure for an open File */
struct File {
Inode *inode;
unsigned short uid, gid;
int flags;
mode_t mode;
off_t pos;
Spinlock lock;
FileOps *ops;
CustodyChain *path;
refcount_t usage;
};
struct FileOps {
off_t (*lseek)(File *, off_t, int);
size_t (*read)(File *, char *, size_t, off_t);
size_t (*write)(File *, char *, size_t, off_t);
int (*ioctl)(File *, unsigned long, uintptr_t);
int (*readdir)(File *, DirEnt *, off_t);
int (*open)(File *);
int (*flush)(File *);
int (*release)(File *);
void (*mmap)(File *, void *, size_t, off_t);
};
/* Structure for a Directory Entry */
struct DirEntry {
DirEntry *next;
Inode *inode, *mnt;
uint32_t hash;
char name[NAME_MAX];
Spinlock lock;
SuperBlock *super;
refcount_t usage;
DirEntry *lnext; /* Next directory entry in global list */
};
/* Structure for a Page in a block cache */
struct Page {
page_t frame;
off_t offset;
refcount_t usage;
};
struct PageCache {
Page *page;
PageCache *next;
};
/* Custody Chains */
struct Custody {
Custody *prev, *next;
CustodyChain *chain;
DirEntry *entry;
};
struct CustodyChain {
Custody *start, *end;
size_t size;
Spinlock lock;
};
/* File System Namespace */
typedef struct FileSystem {
Inode *cwd;
CustodyChain cwdCustody;
Inode *root;
refcount_t usage;
} FileSystem;
/* Files Namespace */
typedef struct Files {
File *fd[NFILES];
refcount_t usage;
} Files;
void init_vfs(void);
void register_fstype(FileSystemType *fstype);
Inode *lookup(const char *name, CustodyChain *chain);
int open(const char *name, int flags, ...); /* mode_t mode */
int close(int fd);
int read(int fd, void *buf, size_t count);
int write(int fd, void *buf, size_t count);
int ioctl(int fd, unsigned long request, ...);
off_t lseek(int fd, off_t offset, int whence);
int stat(const char *pathname, struct stat *statbuf);
size_t getdents(int fd, void *buf, size_t count);
int mkdir(const char *pathname, mode_t mode);
int rmdir(const char *pathname);
int mknod(const char *pathname, mode_t mode, dev_t dev);
int rename(const char *oldpath, const char *newpath);
int dup(int oldfd);
int dup2(int oldfd, int newfd);
int pipe(int pipefd[2]);
int mount(const char *src, const char *target, const char *type,
unsigned long flags, void *data);
int chdir(const char *path);
int chroot(const char *path);
char *getcwd(char *buf, size_t size);
void init_custody_chain(CustodyChain *chain);
CustodyChain *create_custody_chain(void);
void clean_custody_chain(CustodyChain *chain);
void destroy_custody_chain(CustodyChain *chain);
void copy_custody_chain(CustodyChain *chain, CustodyChain *newchain);
void add_custody(CustodyChain *chain, DirEntry *entry);
DirEntry *remove_custody(CustodyChain *chain);
char *custody_path(CustodyChain *chain, char *buf, size_t size);
File *file_get(File *file);
void file_put(File *file);
size_t file_read(File *file, char *buf, size_t size);
size_t file_write(File *file, char *buf, size_t size);
int file_ioctl(File *file, unsigned long reqeust, uintptr_t argp);
int file_readdir(File *file, DirEnt *dent, off_t index);
int file_open(File *file);
void file_mmap(File *file, void *buf, size_t len, off_t offset);
#endif