X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/ab281459f86543c6b8c11ecccc3e743c3d69577e..0f73e6cc9945f9b4a074bb62b9708d1751fa3723:/lunaix-os/includes/lunaix/fs.h?ds=sidebyside diff --git a/lunaix-os/includes/lunaix/fs.h b/lunaix-os/includes/lunaix/fs.h index 539f0a8..d599023 100644 --- a/lunaix-os/includes/lunaix/fs.h +++ b/lunaix-os/includes/lunaix/fs.h @@ -6,25 +6,42 @@ #include #include #include +#include #include #include #include -#include #include + #include +#include + #define VFS_NAME_MAXLEN 128 #define VFS_MAX_FD 32 -#define VFS_IFDIR 0x1 -#define VFS_IFFILE 0x2 -#define VFS_IFSEQDEV 0x4 -#define VFS_IFVOLDEV 0x8 -#define VFS_IFSYMLINK 0x16 +#define VFS_IFDIR F_DIR +#define VFS_IFFILE F_FILE +#define VFS_IFDEV (F_DEV | F_FILE) +#define VFS_IFSEQDEV (F_SEQDEV | F_FILE) +#define VFS_IFVOLDEV (F_VOLDEV | F_FILE) +#define VFS_IFSYMLINK (F_SYMLINK | F_FILE) + +#define VFS_DEVFILE(type) ((type) & F_DEV) +#define VFS_DEVTYPE(type) ((type) & ((F_SEQDEV | F_VOLDEV) ^ F_DEV)) +// Walk, mkdir if component encountered is non-exists. #define VFS_WALK_MKPARENT 0x1 + +// Walk, relative to current FS. #define VFS_WALK_FSRELATIVE 0x2 + +/* + Terminate the walk on the immediate parent, + name of child (last component) is returned through `component` +*/ #define VFS_WALK_PARENT 0x4 + +// Do not follow the symbolic link #define VFS_WALK_NOFOLLOW 0x8 #define VFS_HASHTABLE_BITS 10 @@ -36,11 +53,11 @@ #define FSTYPE_ROFS 0x1 -#define DO_STATUS(errno) SYSCALL_ESTATUS(__current->k_status = errno) -#define DO_STATUS_OR_RETURN(errno) ({ errno < 0 ? DO_STATUS(errno) : errno; }) - #define TEST_FD(fd) (fd >= 0 && fd < VFS_MAX_FD) +#define EXPORT_FILE_SYSTEM(fs_id, init_fn) \ + export_ldga_el(fs, fs_id, ptr_t, init_fn) + #define VFS_VALID_CHAR(chr) \ (('A' <= (chr) && (chr) <= 'Z') || ('a' <= (chr) && (chr) <= 'z') || \ ('0' <= (chr) && (chr) <= '9') || (chr) == '.' || (chr) == '_' || \ @@ -60,7 +77,7 @@ lru_use_one(dnode_lru, &dnode->lru); \ }) -typedef uint32_t inode_t; +typedef u32_t inode_t; struct v_dnode; struct v_inode; @@ -83,7 +100,7 @@ struct filesystem { struct hlist_node fs_list; struct hstr fs_name; - uint32_t types; + u32_t types; int fs_id; int (*mount)(struct v_superblock* vsb, struct v_dnode* mount_point); int (*unmount)(struct v_superblock* vsb); @@ -95,12 +112,13 @@ struct v_superblock struct device* dev; struct v_dnode* root; struct filesystem* fs; - uint32_t iobuf_size; struct hbucket* i_cache; + void* data; + size_t blksize; struct { - uint32_t (*read_capacity)(struct v_superblock* vsb); - uint32_t (*read_usage)(struct v_superblock* vsb); + u32_t (*read_capacity)(struct v_superblock* vsb); + u32_t (*read_usage)(struct v_superblock* vsb); void (*init_inode)(struct v_superblock* vsb, struct v_inode* inode); } ops; }; @@ -119,6 +137,16 @@ struct v_file_ops { int (*write)(struct v_inode* inode, void* buffer, size_t len, size_t fpos); int (*read)(struct v_inode* inode, void* buffer, size_t len, size_t fpos); + + // for operatiosn {write|read}_page, following are true: + // + `len` always equals to PG_SIZE + // + `fpos` always PG_SIZE aligned. + // These additional operations allow underlying fs to use more specialized + // and optimized code. + + int (*write_page)(struct v_inode* inode, void* pg, size_t len, size_t fpos); + int (*read_page)(struct v_inode* inode, void* pg, size_t len, size_t fpos); + int (*readdir)(struct v_file* file, struct dir_context* dctx); int (*seek)(struct v_inode* inode, size_t offset); // optional int (*close)(struct v_file* file); @@ -161,7 +189,7 @@ struct v_file struct v_inode* inode; struct v_dnode* dnode; struct llist_header* f_list; - uint32_t f_pos; + u32_t f_pos; atomic_ulong ref_count; struct v_file_ops* ops; // for caching }; @@ -172,7 +200,8 @@ struct v_fd int flags; }; -// FIXME how do we invalidate corresponding v_dnodes given the v_inode? +// [v_inode::aka_nodes] +// how do we invalidate corresponding v_dnodes given the v_inode? /* Consider taskfs, which is Lunaix's speak of Linux's procfs, that allow info of every process being accessible via file system. Each process's @@ -188,15 +217,15 @@ struct v_inode { inode_t id; mutex_t lock; - uint32_t itype; + u32_t itype; time_t ctime; time_t mtime; time_t atime; lba_t lb_addr; - uint32_t open_count; - uint32_t link_count; - uint32_t lb_usage; - uint32_t fsize; + u32_t open_count; + u32_t link_count; + u32_t lb_usage; + u32_t fsize; void* data; // 允许底层FS绑定他的一些专有数据 struct llist_header aka_dnodes; struct llist_header xattrs; @@ -206,6 +235,8 @@ struct v_inode struct pcache* pg_cache; struct v_inode_ops* ops; struct v_file_ops* default_fops; + + void (*destruct)(struct v_inode* inode); }; struct v_mount @@ -217,7 +248,7 @@ struct v_mount struct v_mount* parent; struct v_dnode* mnt_point; struct v_superblock* super_block; - uint32_t busy_counter; + u32_t busy_counter; int flags; }; @@ -250,8 +281,8 @@ struct pcache struct btrie tree; struct llist_header pages; struct llist_header dirty; - uint32_t n_dirty; - uint32_t n_pages; + u32_t n_dirty; + u32_t n_pages; }; struct pcache_pg @@ -261,8 +292,9 @@ struct pcache_pg struct lru_node lru; struct pcache* holder; void* pg; - uint32_t flags; - uint32_t fpos; + u32_t flags; + u32_t fpos; + u32_t len; }; void @@ -341,6 +373,9 @@ vfs_pclose(struct v_file* file, pid_t pid); int vfs_close(struct v_file* file); +void +vfs_free_fd(struct v_fd* fd); + int vfs_fsync(struct v_file* file); @@ -360,7 +395,7 @@ void vfs_d_free(struct v_dnode* dnode); struct v_inode* -vfs_i_find(struct v_superblock* sb, uint32_t i_id); +vfs_i_find(struct v_superblock* sb, u32_t i_id); void vfs_i_addhash(struct v_inode* inode); @@ -383,6 +418,9 @@ vfs_get_dtype(int itype); void vfs_ref_dnode(struct v_dnode* dnode); +void +vfs_ref_file(struct v_file* file); + void vfs_unref_dnode(struct v_dnode* dnode); @@ -396,22 +434,22 @@ void pcache_release_page(struct pcache* pcache, struct pcache_pg* page); struct pcache_pg* -pcache_new_page(struct pcache* pcache, uint32_t index); +pcache_new_page(struct pcache* pcache, u32_t index); void pcache_set_dirty(struct pcache* pcache, struct pcache_pg* pg); int pcache_get_page(struct pcache* pcache, - uint32_t index, - uint32_t* offset, + u32_t index, + u32_t* offset, struct pcache_pg** page); int -pcache_write(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos); +pcache_write(struct v_inode* inode, void* data, u32_t len, u32_t fpos); int -pcache_read(struct v_inode* inode, void* data, uint32_t len, uint32_t fpos); +pcache_read(struct v_inode* inode, void* data, u32_t len, u32_t fpos); void pcache_release(struct pcache* pcache);