ish/kernel/fs.h
2018-12-22 19:38:41 -08:00

171 lines
5.6 KiB
C

#ifndef FS_H
#define FS_H
#include "misc.h"
#include "util/list.h"
#include "fs/stat.h"
#include "fs/dev.h"
#include "emu/memory.h"
#include <dirent.h>
#include <sqlite3.h>
struct fs_info {
atomic_uint refcount;
mode_t_ umask;
struct fd *pwd;
struct fd *root;
lock_t lock;
};
struct fs_info *fs_info_new(void);
struct fs_info *fs_info_copy(struct fs_info *fs);
void fs_info_release(struct fs_info *fs);
void fs_chdir(struct fs_info *fs, struct fd *pwd);
#define MAX_PATH 4096
#define MAX_NAME 256
struct attr {
enum attr_type {
attr_uid,
attr_gid,
attr_mode,
attr_size,
} type;
union {
uid_t_ uid;
uid_t_ gid;
mode_t_ mode;
off_t_ size;
};
};
#define make_attr(_type, thing) \
((struct attr) {.type = attr_##_type, ._type = thing})
#define AT_SYMLINK_NOFOLLOW_ 0x100
struct fd *generic_open(const char *path, int flags, int mode);
struct fd *generic_openat(struct fd *at, const char *path, int flags, int mode);
int generic_getpath(struct fd *fd, char *buf);
int generic_linkat(struct fd *src_at, const char *src_raw, struct fd *dst_at, const char *dst_raw);
int generic_unlinkat(struct fd *at, const char *path);
int generic_rmdirat(struct fd *at, const char *path);
int generic_renameat(struct fd *src_at, const char *src, struct fd *dst_at, const char *dst);
int generic_symlinkat(const char *target, struct fd *at, const char *link);
int generic_mknod(const char *path, mode_t_ mode, dev_t_ dev);
#define AC_R 4
#define AC_W 2
#define AC_X 1
#define AC_F 0
int generic_accessat(struct fd *dirfd, const char *path, int mode);
int generic_statat(struct fd *at, const char *path, struct statbuf *stat, bool follow_links);
int generic_setattrat(struct fd *at, const char *path, struct attr attr, bool follow_links);
int generic_utime(struct fd *at, const char *path, struct timespec atime, struct timespec mtime, bool follow_links);
ssize_t generic_readlinkat(struct fd *at, const char *path, char *buf, size_t bufsize);
int generic_mkdirat(struct fd *at, const char *path, mode_t_ mode);
struct mount {
const char *point;
const char *source;
const struct fs_ops *fs;
unsigned refcount;
struct list mounts;
int root_fd;
union {
void *data;
struct {
sqlite3 *db;
struct {
sqlite3_stmt *begin;
sqlite3_stmt *commit;
sqlite3_stmt *rollback;
sqlite3_stmt *read_stat;
sqlite3_stmt *write_stat;
sqlite3_stmt *delete_stat;
sqlite3_stmt *write_path;
sqlite3_stmt *delete_path;
} stmt;
lock_t lock;
};
};
};
extern lock_t mounts_lock;
// returns a reference, which must be released
struct mount *mount_find(char *path);
void mount_release(struct mount *mount);
// must hold mounts_lock while calling these, or traversing mounts
int do_mount(const struct fs_ops *fs, const char *source, const char *point);
int do_umount(const char *point);
int mount_remove(struct mount *mount);
extern struct list mounts;
// open flags
#define O_RDONLY_ 0
#define O_WRONLY_ (1 << 0)
#define O_RDWR_ (1 << 1)
#define O_CREAT_ (1 << 6)
#define O_TRUNC_ (1 << 9)
#define O_APPEND_ (1 << 10)
#define O_NONBLOCK_ (1 << 11)
#define O_CLOEXEC_ (1 << 19)
// generic ioctls
#define FIONREAD_ 0x541b
#define FIONBIO_ 0x5421
struct fs_ops {
const char *name;
int (*mount)(struct mount *mount);
int (*umount)(struct mount *mount);
int (*statfs)(struct mount *mount, struct statfsbuf *stat);
struct fd *(*open)(struct mount *mount, const char *path, int flags, int mode);
ssize_t (*readlink)(struct mount *mount, const char *path, char *buf, size_t bufsize);
int (*link)(struct mount *mount, const char *src, const char *dst);
int (*unlink)(struct mount *mount, const char *path);
int (*rmdir)(struct mount *mount, const char *path);
int (*rename)(struct mount *mount, const char *src, const char *dst);
int (*symlink)(struct mount *mount, const char *target, const char *link);
int (*mknod)(struct mount *mount, const char *path, mode_t_ mode, dev_t_ dev);
int (*stat)(struct mount *mount, const char *path, struct statbuf *stat, bool follow_links);
int (*fstat)(struct fd *fd, struct statbuf *stat);
int (*setattr)(struct mount *mount, const char *path, struct attr attr);
int (*fsetattr)(struct fd *fd, struct attr attr);
int (*utime)(struct mount *mount, const char *path, struct timespec atime, struct timespec mtime);
// Returns the path of the file descriptor, buf must be at least MAX_PATH
int (*getpath)(struct fd *fd, char *buf);
int (*mkdir)(struct mount *mount, const char *path, mode_t_ mode);
int (*flock)(struct fd *fd, int operation);
};
struct mount *find_mount_and_trim_path(char *path);
const char *fix_path(const char *path); // TODO reconsider
// real fs
extern const struct fs_ops realfs;
extern const struct fs_ops fakefs;
extern const struct fd_ops realfs_fdops;
int realfs_truncate(struct mount *mount, const char *path, off_t_ size);
int realfs_utime(struct mount *mount, const char *path, struct timespec atime, struct timespec mtime);
int realfs_statfs(struct mount *mount, struct statfsbuf *stat);
int realfs_flock(struct fd *fd, int operation);
int realfs_getpath(struct fd *fd, char *buf);
ssize_t realfs_read(struct fd *fd, void *buf, size_t bufsize);
ssize_t realfs_write(struct fd *fd, const void *buf, size_t bufsize);
int realfs_getflags(struct fd *fd);
int realfs_setflags(struct fd *fd, dword_t arg);
int realfs_close(struct fd *fd);
// adhoc fs
struct fd *adhoc_fd_create(void);
#endif