Skip to content

VFS

struct vfs_stat {
    mode_t    mode;
    uint64_t  size;
    uint64_t  inode;
    uint32_t  nlink;
    uint64_t  atime;
    uint64_t  mtime;
    uint64_t  ctime;
    uint16_t  present_mask;
};
struct vfs_dirent {
    char             name[VFS_NAME_MAX];
    mode_t           mode;
    struct vfs_node  *node;
    void             *dirent_data;
};
struct vfs_ops {
    enum errno  (*read)(struct vfs_node *node, void *buf, uint64_t size, uint64_t offset);
    enum errno  (*write)(struct vfs_node *node, const void *buf, uint64_t size, uint64_t offset);
    enum errno  (*open)(struct vfs_node *node, uint32_t flags);
    enum errno  (*close)(struct vfs_node *node);
    enum errno  (*create)(struct vfs_node *parent, const char *name, mode_t mode);
    enum errno  (*mknod)(struct vfs_node *parent, const char *name, mode_t mode, uint32_t dev);
    enum errno  (*symlink)(struct vfs_node *parent, const char *target, const char *link_name);
    enum errno  (*mount)(struct vfs_node *mountpoint, struct vfs_node *target, const char *name);
    enum errno  (*unmount)(struct vfs_mount *mountpoint);
    enum errno  (*stat)(struct vfs_node *node, struct vfs_stat *out);
    enum errno  (*readdir)(struct vfs_node *node, struct vfs_dirent *out, uint64_t index);
    enum errno  (*mkdir)(struct vfs_node *parent, const char *name, mode_t mode);
    enum errno  (*rmdir)(struct vfs_node *parent, const char *name);
    enum errno  (*unlink)(struct vfs_node *parent, const char *name);
    enum errno  (*rename)(struct vfs_node *old_parent, const char *old_name, struct vfs_node *new_parent, const char *new_name);
    enum errno  (*truncate)(struct vfs_node *node, uint64_t length);
    enum errno  (*readlink)(struct vfs_node *node, char *buf, uint64_t size);
    enum errno  (*link)(struct vfs_node *parent, struct vfs_node *target, const char *link_name);
    enum errno  (*chmod)(struct vfs_node *node, mode_t mode);
    enum errno  (*chown)(struct vfs_node *node, uid_t uid, gid_t gid);
    enum errno  (*utime)(struct vfs_node *node, uint64_t atime, uint64_t mtime);
    enum errno  (*destroy)(struct vfs_node *node);
    enum errno  (*finddir)(struct vfs_node *node, const char *name, struct vfs_dirent *out);
};
struct vfs_mount {
    struct vfs_node       *mount_point;
    struct vfs_mount      *mount_mount;
    struct vfs_node       *root;
    const struct vfs_ops  *ops;
    char                  name[256];
    void                  *fs_data;
};
struct vfs_node {
    enum fs_type          fs_type;
    uint64_t              open_handles;
    uint64_t              unique_id;
    uint32_t              flags;
    mode_t                mode;
    uint64_t              size;
    uid_t                 uid;
    gid_t                 gid;
    uint64_t              mtime;
    uint64_t              atime;
    void                  *fs_data;
    void                  *fs_node_data;
    struct vfs_mount      *child_mount;
    const struct vfs_ops  *ops;
};
enum vfs_node_flags : uint32_t {
    VFS_NODE_NONE = 0x0000,
    VFS_NODE_MOUNTPOINT = 0x0001,
    VFS_NODE_SYMLINK = 0x0002,
    VFS_NODE_HIDDEN = 0x0004,
    VFS_NODE_DEVICE = 0x0008,
    VFS_NODE_PIPE = 0x0010,
    VFS_NODE_SOCKET = 0x0020,
    VFS_NODE_SYNC = 0x0030,
    VFS_NODE_TEMPORARY = 0x0040,
    VFS_NODE_NOATIME = 0x0080,
    VFS_NODE_APPENDONLY = 0x0100,
    VFS_NODE_IMMUTABLE = 0x0200,
    VFS_NODE_NOFOLLOW = 0x0400,
    VFS_NODE_IN_USE = 0x0800,
    VFS_NODE_DIRSYNC = 0x1000,
};
enum vfs_open_opts : uint32_t {
    VFS_OPEN_READ = 0x01,
    VFS_OPEN_WRITE = 0x02,
    VFS_OPEN_RDWR = VFS_OPEN_READ | VFS_OPEN_WRITE,
    VFS_OPEN_APPEND = 0x04,
    VFS_OPEN_CREAT = 0x08,
    VFS_OPEN_TRUNC = 0x10,
    VFS_OPEN_EXCL = 0x20,
    VFS_OPEN_DIR = 0x40,
    VFS_OPEN_SYMLINK_NOFOLLOW = 0x80,
    VFS_OPEN_NONBLOCK = 0x100,
    VFS_OPEN_SYNC = 0x200,
    VFS_OPEN_NOATIME = 0x400,
};
void vfs_node_print(const struct vfs_node *node);
enum errno vfs_mount(struct vfs_node *mountpoint, struct vfs_node *target, const char *name);
enum errno vfs_unmount(struct vfs_mount *mountpoint);
struct vfs_node * vfs_finddir(struct vfs_node *node, const char *fname);
#define VFS_NAME_MAX 256 // this because of ext2
#define VFS_MODE_FILE 0x8000U     // 1000 << 12
#define VFS_MODE_DIR 0x4000U      // 0100 << 12
#define VFS_MODE_SYMLINK 0xA000U  // 1010 << 12
#define VFS_MODE_CHARDEV 0x2000U  // 0010 << 12
#define VFS_MODE_BLOCKDEV 0x6000U // 0110 << 12
#define VFS_MODE_PIPE 0x1000U     // 0001 << 12
#define VFS_MODE_SOCKET 0xC000U   // 1100 << 12
#define VFS_MODE_O_READ 0x0100U  // 0400 (bit 8)
#define VFS_MODE_O_WRITE 0x0080U // 0200 (bit 7)
#define VFS_MODE_O_EXEC 0x0040U  // 0100 (bit 6)
#define VFS_MODE_G_READ 0x0020U  // 0040 (bit 5)
#define VFS_MODE_G_WRITE 0x0010U // 0020 (bit 4)
#define VFS_MODE_G_EXEC 0x0008U  // 0010 (bit 3)
#define VFS_MODE_R_READ 0x0004U  // 0004 (bit 2)
#define VFS_MODE_R_WRITE 0x0002U // 0002 (bit 1)
#define VFS_MODE_R_EXEC 0x0001U  // 0001 (bit 0)
#define VFS_MODE_READ (VFS_MODE_O_READ | VFS_MODE_G_READ | VFS_MODE_R_READ)
#define VFS_MODE_WRITE (VFS_MODE_O_WRITE | VFS_MODE_G_WRITE | VFS_MODE_R_WRITE)
#define VFS_MODE_EXEC (VFS_MODE_O_EXEC | VFS_MODE_G_EXEC | VFS_MODE_R_EXEC)
#define VFS_MODE_TYPE_MASK 0xF000U