X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/bb7ce16533fb6c1384775dea6e1150e74c229daf..09aa85cf875db1e6fd1317cd2b9947b9d3675d6c:/lunaix-os/includes/lunaix/fs.h diff --git a/lunaix-os/includes/lunaix/fs.h b/lunaix-os/includes/lunaix/fs.h index b497954..4b28881 100644 --- a/lunaix-os/includes/lunaix/fs.h +++ b/lunaix-os/includes/lunaix/fs.h @@ -9,7 +9,6 @@ #include #include #include -#include #include #include @@ -36,9 +35,6 @@ #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 VFS_VALID_CHAR(chr) \ @@ -60,7 +56,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 +79,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 +91,12 @@ struct v_superblock struct device* dev; struct v_dnode* root; struct filesystem* fs; - uint32_t iobuf_size; struct hbucket* i_cache; + void* data; 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 +115,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 +167,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,27 +178,43 @@ struct v_fd int flags; }; +// [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 + creation will result a creation of a directory under the root of task fs + with it's pid as name. But that dir must delete when process is killed, and + such deletion does not mediated by vfs itself, so there is a need of cache + syncing. + And this is also the case of all ramfs where argumentation to file tree is + performed by third party. +*/ + 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; struct v_superblock* sb; struct hlist_node hash_list; struct lru_node lru; struct pcache* pg_cache; - void* data; // 允许底层FS绑定他的一些专有数据 struct v_inode_ops* ops; struct v_file_ops* default_fops; + + void (*destruct)(struct v_inode* inode); }; struct v_mount @@ -204,7 +226,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; }; @@ -216,6 +238,7 @@ struct v_dnode struct v_inode* inode; struct v_dnode* parent; struct hlist_node hash_list; + struct llist_header aka_list; struct llist_header children; struct llist_header siblings; struct v_superblock* super_block; @@ -236,8 +259,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 @@ -247,10 +270,11 @@ 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; }; -/* --- file system manager --- */ + void fsm_init(); @@ -269,6 +293,9 @@ fsm_get(const char* fs_name); void vfs_init(); +void +vfs_export_attributes(); + struct v_dnode* vfs_dcache_lookup(struct v_dnode* parent, struct hstr* str); @@ -318,9 +345,15 @@ vfs_mkdir(const char* path, struct v_dnode** dentry); int vfs_open(struct v_dnode* dnode, struct v_file** file); +int +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); @@ -340,7 +373,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); @@ -357,6 +390,21 @@ vfs_dup_fd(struct v_fd* old, struct v_fd** new); int vfs_getfd(int fd, struct v_fd** fd_s); +int +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); + +int +vfs_get_path(struct v_dnode* dnode, char* buf, size_t size, int depth); + void pcache_init(struct pcache* pcache); @@ -364,22 +412,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);