push
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
#ifndef DEVFS_H
|
||||
#define DEVFS_H
|
||||
|
||||
#include "vfs.h"
|
||||
|
||||
vnode_t *devfs_create_root(void);
|
||||
void devfs_register(const char *name, vnode_t *node);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,161 @@
|
||||
#ifndef EXT2_H
|
||||
#define EXT2_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "../drivers/blkdev.h"
|
||||
#include "vfs.h"
|
||||
|
||||
#define EXT2_SUPER_MAGIC 0xEF53
|
||||
#define EXT2_SUPER_OFFSET 1024
|
||||
#define EXT2_ROOT_INO 2
|
||||
#define EXT2_GOOD_OLD_REV 0
|
||||
#define EXT2_DYNAMIC_REV 1
|
||||
#define EXT2_VALID_FS 1
|
||||
#define EXT2_ERROR_FS 2
|
||||
|
||||
#define EXT2_S_IFSOCK 0xC000
|
||||
#define EXT2_S_IFLNK 0xA000
|
||||
#define EXT2_S_IFREG 0x8000
|
||||
#define EXT2_S_IFBLK 0x6000
|
||||
#define EXT2_S_IFDIR 0x4000
|
||||
#define EXT2_S_IFCHR 0x2000
|
||||
#define EXT2_S_IFIFO 0x1000
|
||||
|
||||
#define EXT2_FT_UNKNOWN 0
|
||||
#define EXT2_FT_REG_FILE 1
|
||||
#define EXT2_FT_DIR 2
|
||||
#define EXT2_FT_CHRDEV 3
|
||||
#define EXT2_FT_BLKDEV 4
|
||||
#define EXT2_FT_FIFO 5
|
||||
#define EXT2_FT_SOCK 6
|
||||
#define EXT2_FT_SYMLINK 7
|
||||
|
||||
#define EXT2_NDIR_BLOCKS 12
|
||||
#define EXT2_IND_BLOCK 12
|
||||
#define EXT2_DIND_BLOCK 13
|
||||
#define EXT2_TIND_BLOCK 14
|
||||
#define EXT2_N_BLOCKS 15
|
||||
#define EXT2_NAME_LEN 255
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t s_inodes_count;
|
||||
uint32_t s_blocks_count;
|
||||
uint32_t s_r_blocks_count;
|
||||
uint32_t s_free_blocks_count;
|
||||
uint32_t s_free_inodes_count;
|
||||
uint32_t s_first_data_block;
|
||||
uint32_t s_log_block_size;
|
||||
uint32_t s_log_frag_size;
|
||||
uint32_t s_blocks_per_group;
|
||||
uint32_t s_frags_per_group;
|
||||
uint32_t s_inodes_per_group;
|
||||
uint32_t s_mtime;
|
||||
uint32_t s_wtime;
|
||||
uint16_t s_mnt_count;
|
||||
uint16_t s_max_mnt_count;
|
||||
uint16_t s_magic;
|
||||
uint16_t s_state;
|
||||
uint16_t s_errors;
|
||||
uint16_t s_minor_rev_level;
|
||||
uint32_t s_lastcheck;
|
||||
uint32_t s_checkinterval;
|
||||
uint32_t s_creator_os;
|
||||
uint32_t s_rev_level;
|
||||
uint16_t s_def_resuid;
|
||||
uint16_t s_def_resgid;
|
||||
uint32_t s_first_ino;
|
||||
uint16_t s_inode_size;
|
||||
uint16_t s_block_group_nr;
|
||||
uint32_t s_feature_compat;
|
||||
uint32_t s_feature_incompat;
|
||||
uint32_t s_feature_ro_compat;
|
||||
uint8_t s_uuid[16];
|
||||
char s_volume_name[16];
|
||||
char s_last_mounted[64];
|
||||
uint32_t s_algo_bitmap;
|
||||
uint8_t s_prealloc_blocks;
|
||||
uint8_t s_prealloc_dir_blocks;
|
||||
uint16_t s_padding1;
|
||||
uint8_t s_journal_uuid[16];
|
||||
uint32_t s_journal_inum;
|
||||
uint32_t s_journal_dev;
|
||||
uint32_t s_last_orphan;
|
||||
uint32_t s_hash_seed[4];
|
||||
uint8_t s_def_hash_version;
|
||||
uint8_t s_reserved_pad[3];
|
||||
uint32_t s_default_mount_options;
|
||||
uint32_t s_first_meta_bg;
|
||||
uint8_t s_reserved[760];
|
||||
} ext2_superblock_t;
|
||||
|
||||
_Static_assert(sizeof(ext2_superblock_t) == 1024, "ext2 superblock size");
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t bg_block_bitmap;
|
||||
uint32_t bg_inode_bitmap;
|
||||
uint32_t bg_inode_table;
|
||||
uint16_t bg_free_blocks_count;
|
||||
uint16_t bg_free_inodes_count;
|
||||
uint16_t bg_used_dirs_count;
|
||||
uint16_t bg_pad;
|
||||
uint8_t bg_reserved[12];
|
||||
} ext2_group_desc_t;
|
||||
|
||||
_Static_assert(sizeof(ext2_group_desc_t) == 32, "ext2 group desc size");
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint16_t i_mode;
|
||||
uint16_t i_uid;
|
||||
uint32_t i_size;
|
||||
uint32_t i_atime;
|
||||
uint32_t i_ctime;
|
||||
uint32_t i_mtime;
|
||||
uint32_t i_dtime;
|
||||
uint16_t i_gid;
|
||||
uint16_t i_links_count;
|
||||
uint32_t i_blocks;
|
||||
uint32_t i_flags;
|
||||
uint32_t i_osd1;
|
||||
uint32_t i_block[EXT2_N_BLOCKS];
|
||||
uint32_t i_generation;
|
||||
uint32_t i_file_acl;
|
||||
uint32_t i_dir_acl;
|
||||
uint32_t i_faddr;
|
||||
uint8_t i_osd2[12];
|
||||
} ext2_inode_t;
|
||||
|
||||
_Static_assert(sizeof(ext2_inode_t) == 128, "ext2 inode size");
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t inode;
|
||||
uint16_t rec_len;
|
||||
uint8_t name_len;
|
||||
uint8_t file_type;
|
||||
char name[EXT2_NAME_LEN];
|
||||
} ext2_dir_entry_t;
|
||||
|
||||
typedef struct {
|
||||
blkdev_t *dev;
|
||||
ext2_superblock_t sb;
|
||||
ext2_group_desc_t *gdt;
|
||||
uint32_t block_size;
|
||||
uint32_t groups_count;
|
||||
uint32_t inodes_per_block;
|
||||
uint32_t inode_size;
|
||||
uint32_t ptrs_per_block;
|
||||
bool dirty;
|
||||
} ext2_t;
|
||||
|
||||
typedef struct {
|
||||
ext2_t *fs;
|
||||
uint32_t ino;
|
||||
} ext2_vdata_t;
|
||||
|
||||
int ext2_format(blkdev_t *dev, const char *label);
|
||||
vnode_t *ext2_mount(blkdev_t *dev);
|
||||
void ext2_unmount(ext2_t *fs);
|
||||
void ext2_sync(ext2_t *fs);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,146 @@
|
||||
#ifndef FAT32_H
|
||||
#define FAT32_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "../drivers/blkdev.h"
|
||||
#include "vfs.h"
|
||||
|
||||
#define FAT32_SECTOR_SIZE 512
|
||||
#define FAT32_EOC 0x0FFFFFFF
|
||||
#define FAT32_EOC_MIN 0x0FFFFFF8
|
||||
#define FAT32_FREE_CLUSTER 0x00000000
|
||||
#define FAT32_BAD_CLUSTER 0x0FFFFFF7
|
||||
#define FAT32_CLUSTER_MASK 0x0FFFFFFF
|
||||
|
||||
#define FAT32_FSINFO_LEAD_SIG 0x41615252
|
||||
#define FAT32_FSINFO_STRUCT_SIG 0x61417272
|
||||
#define FAT32_FSINFO_TRAIL_SIG 0xAA550000
|
||||
|
||||
#define FAT_ATTR_READ_ONLY 0x01
|
||||
#define FAT_ATTR_HIDDEN 0x02
|
||||
#define FAT_ATTR_SYSTEM 0x04
|
||||
#define FAT_ATTR_VOLUME_ID 0x08
|
||||
#define FAT_ATTR_DIRECTORY 0x10
|
||||
#define FAT_ATTR_ARCHIVE 0x20
|
||||
#define FAT_ATTR_LONG_NAME 0x0F
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t bs_jmp[3];
|
||||
uint8_t bs_oem[8];
|
||||
uint16_t bpb_bytes_per_sector;
|
||||
uint8_t bpb_sectors_per_cluster;
|
||||
uint16_t bpb_reserved_sectors;
|
||||
uint8_t bpb_num_fats;
|
||||
uint16_t bpb_root_entries;
|
||||
uint16_t bpb_total_sectors_16;
|
||||
uint8_t bpb_media;
|
||||
uint16_t bpb_fat_size_16;
|
||||
uint16_t bpb_sectors_per_track;
|
||||
uint16_t bpb_num_heads;
|
||||
uint32_t bpb_hidden_sectors;
|
||||
uint32_t bpb_total_sectors_32;
|
||||
uint32_t bpb_fat_size_32;
|
||||
uint16_t bpb_ext_flags;
|
||||
uint16_t bpb_fs_version;
|
||||
uint32_t bpb_root_cluster;
|
||||
uint16_t bpb_fs_info;
|
||||
uint16_t bpb_backup_boot;
|
||||
uint8_t bpb_reserved[12];
|
||||
uint8_t bs_drive_num;
|
||||
uint8_t bs_reserved1;
|
||||
uint8_t bs_boot_sig;
|
||||
uint32_t bs_vol_id;
|
||||
uint8_t bs_vol_label[11];
|
||||
uint8_t bs_fs_type[8];
|
||||
uint8_t bs_boot_code[420];
|
||||
uint16_t bs_signature;
|
||||
} fat32_bpb_t;
|
||||
|
||||
_Static_assert(sizeof(fat32_bpb_t) == 512, "fat32 bpb size");
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t lead_sig;
|
||||
uint8_t reserved1[480];
|
||||
uint32_t struct_sig;
|
||||
uint32_t free_count;
|
||||
uint32_t next_free;
|
||||
uint8_t reserved2[12];
|
||||
uint32_t trail_sig;
|
||||
} fat32_fsinfo_t;
|
||||
|
||||
_Static_assert(sizeof(fat32_fsinfo_t) == 512, "fat32 fsinfo size");
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t name[11];
|
||||
uint8_t attr;
|
||||
uint8_t nt_reserved;
|
||||
uint8_t create_time_tenth;
|
||||
uint16_t create_time;
|
||||
uint16_t create_date;
|
||||
uint16_t access_date;
|
||||
uint16_t cluster_hi;
|
||||
uint16_t modify_time;
|
||||
uint16_t modify_date;
|
||||
uint16_t cluster_lo;
|
||||
uint32_t file_size;
|
||||
} fat32_dirent_t;
|
||||
|
||||
_Static_assert(sizeof(fat32_dirent_t) == 32, "fat32 dirent size");
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t order;
|
||||
uint8_t name1[10];
|
||||
uint8_t attr;
|
||||
uint8_t type;
|
||||
uint8_t checksum;
|
||||
uint8_t name2[12];
|
||||
uint16_t cluster_lo;
|
||||
uint8_t name3[4];
|
||||
} fat32_lfn_t;
|
||||
|
||||
_Static_assert(sizeof(fat32_lfn_t) == 32, "fat32 lfn size");
|
||||
|
||||
typedef struct {
|
||||
blkdev_t *dev;
|
||||
uint32_t bytes_per_sector;
|
||||
uint32_t sectors_per_cluster;
|
||||
uint32_t bytes_per_cluster;
|
||||
uint32_t reserved_sectors;
|
||||
uint32_t num_fats;
|
||||
uint32_t fat_size_sectors;
|
||||
uint32_t total_sectors;
|
||||
uint32_t root_cluster;
|
||||
uint32_t first_fat_sector;
|
||||
uint32_t first_data_sector;
|
||||
uint32_t total_clusters;
|
||||
uint32_t fsinfo_sector;
|
||||
uint32_t next_free_hint;
|
||||
uint32_t free_count;
|
||||
bool dirty;
|
||||
bool readonly;
|
||||
uint8_t *shared_buf;
|
||||
} fat32_t;
|
||||
|
||||
typedef struct {
|
||||
fat32_t *fs;
|
||||
uint32_t first_cluster;
|
||||
uint32_t dir_cluster;
|
||||
uint32_t dir_entry_offset;
|
||||
uint32_t file_size;
|
||||
uint8_t attr;
|
||||
|
||||
uint32_t cached_cluster;
|
||||
uint32_t cached_index;
|
||||
bool size_dirty;
|
||||
|
||||
uint8_t *io_buf;
|
||||
} fat32_vdata_t;
|
||||
|
||||
int fat32_format(blkdev_t *dev, const char *label);
|
||||
vnode_t *fat32_mount(blkdev_t *dev);
|
||||
void fat32_unmount(fat32_t *fs);
|
||||
int fat32_sync(fat32_t *fs);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
#ifndef INITRAMFS_H
|
||||
#define INITRAMFS_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <stdint.h>
|
||||
|
||||
int initramfs_mount(const void *data, size_t size);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
#ifndef RAMFS_H
|
||||
#define RAMFS_H
|
||||
|
||||
#include "vfs.h"
|
||||
|
||||
#define RAMFS_MAX_CHILDREN 64
|
||||
#define RAMFS_MAX_FILE_SIZE (4 * 1024 * 1024)
|
||||
|
||||
vnode_t *ramfs_create_root(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,181 @@
|
||||
#ifndef VFS_H
|
||||
#define VFS_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stddef.h>
|
||||
#include <stdbool.h>
|
||||
#include "../syscall/errno.h"
|
||||
|
||||
#define VFS_MAX_PATH 512
|
||||
#define VFS_MAX_NAME 256
|
||||
#define VFS_MAX_MOUNTS 16
|
||||
#define VFS_MAX_OPEN_FILES 512
|
||||
|
||||
#define O_RDONLY 0x000
|
||||
#define O_WRONLY 0x001
|
||||
#define O_RDWR 0x002
|
||||
#define O_ACCMODE 0x003
|
||||
#define O_CREAT 0x040
|
||||
#define O_TRUNC 0x200
|
||||
#define O_APPEND 0x400
|
||||
#define O_DIRECTORY 0x10000
|
||||
#define O_NONBLOCK 0x800
|
||||
|
||||
#define SEEK_SET 0
|
||||
#define SEEK_CUR 1
|
||||
#define SEEK_END 2
|
||||
|
||||
#define FD_CLOEXEC (1 << 0)
|
||||
#define TASK_MAX_FDS 256
|
||||
|
||||
typedef enum {
|
||||
VFS_NODE_FILE = 0,
|
||||
VFS_NODE_DIR = 1,
|
||||
VFS_NODE_CHARDEV = 2,
|
||||
VFS_NODE_BLKDEV = 3,
|
||||
VFS_NODE_SYMLINK = 4,
|
||||
VFS_NODE_PIPE = 5,
|
||||
} vnode_type_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t st_ino;
|
||||
vnode_type_t st_type;
|
||||
uint32_t st_mode;
|
||||
uint32_t st_uid;
|
||||
uint32_t st_gid;
|
||||
uint64_t st_size;
|
||||
uint64_t st_blocks;
|
||||
} vfs_stat_t;
|
||||
|
||||
typedef struct {
|
||||
uint64_t d_ino;
|
||||
uint8_t d_type;
|
||||
char d_name[VFS_MAX_NAME];
|
||||
} vfs_dirent_t;
|
||||
|
||||
typedef struct vnode vnode_t;
|
||||
typedef struct vfs_mount vfs_mount_t;
|
||||
|
||||
typedef struct vnode_ops {
|
||||
int64_t (*read) (vnode_t *node, void *buf, size_t len, uint64_t offset);
|
||||
int64_t (*write) (vnode_t *node, const void *buf, size_t len, uint64_t offset);
|
||||
int (*truncate)(vnode_t *node, uint64_t new_size);
|
||||
int (*lookup) (vnode_t *dir, const char *name, vnode_t **out);
|
||||
int (*readdir) (vnode_t *dir, uint64_t index, vfs_dirent_t *out);
|
||||
int (*mkdir) (vnode_t *dir, const char *name, uint32_t mode);
|
||||
int (*create) (vnode_t *dir, const char *name, uint32_t mode, vnode_t **out);
|
||||
int (*unlink) (vnode_t *dir, const char *name);
|
||||
int (*rename) (vnode_t *src_dir, const char *src_name,
|
||||
vnode_t *dst_dir, const char *dst_name);
|
||||
int (*stat) (vnode_t *node, vfs_stat_t *out);
|
||||
void (*ref) (vnode_t *node);
|
||||
void (*unref) (vnode_t *node);
|
||||
int64_t (*ioctl) (vnode_t *node, uint64_t req, void *arg);
|
||||
} vnode_ops_t;
|
||||
|
||||
struct vnode {
|
||||
vnode_type_t type;
|
||||
uint32_t mode;
|
||||
uint32_t uid;
|
||||
uint32_t gid;
|
||||
uint64_t size;
|
||||
uint64_t ino;
|
||||
const vnode_ops_t *ops;
|
||||
void *fs_data;
|
||||
volatile int refcount;
|
||||
vfs_mount_t *mounted;
|
||||
};
|
||||
|
||||
struct vfs_mount {
|
||||
char path[VFS_MAX_PATH];
|
||||
char device[32];
|
||||
char fstype[16];
|
||||
vnode_t *root;
|
||||
bool used;
|
||||
void *fs_priv;
|
||||
void (*unmount)(void *fs_priv);
|
||||
void (*sync)(void *fs_priv);
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
vnode_t *vnode;
|
||||
uint64_t offset;
|
||||
int flags;
|
||||
volatile int refcount;
|
||||
} vfs_file_t;
|
||||
|
||||
typedef struct {
|
||||
vfs_file_t *file;
|
||||
int fd_flags;
|
||||
} fd_entry_t;
|
||||
|
||||
typedef struct fd_table fd_table_t;
|
||||
|
||||
struct fd_table {
|
||||
fd_entry_t entries[TASK_MAX_FDS];
|
||||
};
|
||||
|
||||
void vfs_init (void);
|
||||
int vfs_mount (const char *path, vnode_t *fs_root);
|
||||
|
||||
int vfs_mount_fs(const char *path, vnode_t *fs_root,
|
||||
void *fs_priv, void (*unmount_fn)(void *),
|
||||
void (*sync_fn)(void *));
|
||||
|
||||
int vfs_umount (const char *path);
|
||||
int vfs_lookup (const char *path, vnode_t **out);
|
||||
|
||||
int vfs_open (const char *path, int flags, uint32_t mode, vfs_file_t **out);
|
||||
void vfs_close (vfs_file_t *file);
|
||||
int64_t vfs_read (vfs_file_t *file, void *buf, size_t len);
|
||||
int64_t vfs_write (vfs_file_t *file, const void *buf, size_t len);
|
||||
int64_t vfs_seek (vfs_file_t *file, int64_t offset, int whence);
|
||||
int vfs_stat (const char *path, vfs_stat_t *out);
|
||||
int vfs_fstat (vfs_file_t *file, vfs_stat_t *out);
|
||||
int64_t vfs_ioctl (vfs_file_t *file, uint64_t req, void *arg);
|
||||
int vfs_readdir(vfs_file_t *file, vfs_dirent_t *out);
|
||||
int vfs_mkdir (const char *path, uint32_t mode);
|
||||
|
||||
void vnode_ref (vnode_t *node);
|
||||
void vnode_unref (vnode_t *node);
|
||||
vfs_file_t *vfs_file_alloc(void);
|
||||
void vfs_file_free (vfs_file_t *file);
|
||||
|
||||
fd_table_t *fd_table_create (void);
|
||||
fd_table_t *fd_table_clone (const fd_table_t *src);
|
||||
void fd_table_cloexec(fd_table_t *table);
|
||||
void fd_table_destroy(fd_table_t *table);
|
||||
|
||||
int fd_alloc (fd_table_t *table, vfs_file_t *file, int min_fd);
|
||||
vfs_file_t *fd_get (const fd_table_t *table, int fd);
|
||||
int fd_close (fd_table_t *table, int fd);
|
||||
int fd_dup2 (fd_table_t *table, int oldfd, int newfd);
|
||||
int fd_set_flags(fd_table_t *table, int fd, int flags);
|
||||
int fd_get_flags(const fd_table_t *table, int fd);
|
||||
void vfs_sync_all(void);
|
||||
int vfs_init_stdio(void *task_ptr);
|
||||
|
||||
typedef struct {
|
||||
char path[VFS_MAX_PATH];
|
||||
char device[32];
|
||||
char fstype[16];
|
||||
uint32_t flags;
|
||||
} vfs_mount_info_t;
|
||||
|
||||
int vfs_set_mount_info(const char *path, const char *device, const char *fstype);
|
||||
int vfs_list_mounts(vfs_mount_info_t *out, int max);
|
||||
|
||||
typedef struct {
|
||||
uint64_t f_bsize;
|
||||
uint64_t f_blocks;
|
||||
uint64_t f_bfree;
|
||||
uint64_t f_bavail;
|
||||
uint64_t f_files;
|
||||
uint64_t f_ffree;
|
||||
uint32_t f_flag;
|
||||
uint32_t f_namemax;
|
||||
} vfs_statvfs_t;
|
||||
|
||||
int vfs_statvfs(const char *path, vfs_statvfs_t *out);
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user