From fac3bbf2b2634f4f15cb33ece3acfa39db1433df Mon Sep 17 00:00:00 2001 From: Minep Date: Sun, 7 Aug 2022 17:23:20 +0100 Subject: [PATCH] fix: separate any i/o to sequential device from caching layer fix: a corner case on index resulting lookup fail in radix tree fix: pass the incorrect argument to vfs_close when freeing up resources on destorying process refactor: attach default file ops to inode for more flexible choice of ops when opening file refactor: reduce the size of twifs_node. --- lunaix-os/includes/lunaix/device.h | 5 +- lunaix-os/includes/lunaix/fs.h | 22 ++++--- lunaix-os/includes/lunaix/fs/twifs.h | 21 ++++-- lunaix-os/includes/lunaix/tty/console.h | 2 +- lunaix-os/includes/lunaix/types.h | 1 + lunaix-os/kernel/block.c | 2 +- lunaix-os/kernel/demos/iotest.c | 19 ++++-- lunaix-os/kernel/device.c | 42 +++++++++--- lunaix-os/kernel/ds/btrie.c | 3 +- lunaix-os/kernel/fs/pcache.c | 18 +++--- lunaix-os/kernel/fs/twifs/twifs.c | 71 +++++++++++++++----- lunaix-os/kernel/fs/vfs.c | 86 +++++++++++++------------ lunaix-os/kernel/lxconsole.c | 11 +++- lunaix-os/kernel/sched.c | 2 +- 14 files changed, 208 insertions(+), 97 deletions(-) diff --git a/lunaix-os/includes/lunaix/device.h b/lunaix-os/includes/lunaix/device.h index dde14a3..08d25c4 100644 --- a/lunaix-os/includes/lunaix/device.h +++ b/lunaix-os/includes/lunaix/device.h @@ -28,7 +28,10 @@ void device_init(); struct device* -device_add(struct device* parent, void* underlay, char* name_fmt, ...); +device_addseq(struct device* parent, void* underlay, char* name_fmt, ...); + +struct device* +device_addvol(struct device* parent, void* underlay, char* name_fmt, ...); void device_remove(struct device* dev); diff --git a/lunaix-os/includes/lunaix/fs.h b/lunaix-os/includes/lunaix/fs.h index 2d405ee..87f259a 100644 --- a/lunaix-os/includes/lunaix/fs.h +++ b/lunaix-os/includes/lunaix/fs.h @@ -3,6 +3,7 @@ #include #include +#include #include #include #include @@ -12,10 +13,11 @@ #define VFS_NAME_MAXLEN 128 #define VFS_MAX_FD 32 -#define VFS_INODE_TYPE_DIR 0x1 -#define VFS_INODE_TYPE_FILE 0x2 -#define VFS_INODE_TYPE_DEVICE 0x4 -#define VFS_INODE_TYPE_SYMLINK 0x8 +#define VFS_IFDIR 0x1 +#define VFS_IFFILE 0x2 +#define VFS_IFSEQDEV 0x4 +#define VFS_IFVOLDEV 0x8 +#define VFS_IFSYMLINK 0x16 #define VFS_WALK_MKPARENT 0x1 #define VFS_WALK_FSRELATIVE 0x2 @@ -100,9 +102,10 @@ struct v_fd struct v_inode { uint32_t itype; - uint32_t ctime; - uint32_t mtime; - uint64_t lb_addr; + 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; @@ -122,6 +125,7 @@ struct v_inode int (*symlink)(struct v_inode* this, const char* target); int (*dir_lookup)(struct v_inode* this, struct v_dnode* dnode); } ops; + struct v_file_ops default_fops; }; struct v_dnode @@ -249,10 +253,10 @@ pcache_get_page(struct pcache* pcache, struct pcache_pg** page); int -pcache_write(struct v_file* file, void* data, uint32_t len); +pcache_write(struct v_file* file, void* data, uint32_t len, uint32_t fpos); int -pcache_read(struct v_file* file, void* data, uint32_t len); +pcache_read(struct v_file* file, void* data, uint32_t len, uint32_t fpos); void pcache_release(struct pcache* pcache); diff --git a/lunaix-os/includes/lunaix/fs/twifs.h b/lunaix-os/includes/lunaix/fs/twifs.h index 31875ef..f2d6b15 100644 --- a/lunaix-os/includes/lunaix/fs/twifs.h +++ b/lunaix-os/includes/lunaix/fs/twifs.h @@ -11,20 +11,33 @@ struct twifs_node uint32_t itype; struct llist_header children; struct llist_header siblings; - struct v_file_ops fops; + struct + { + int (*write)(struct v_file* file, + void* buffer, + size_t len, + size_t fpos); + int (*read)(struct v_file* file, void* buffer, size_t len, size_t fpos); + } ops; }; void twifs_init(); struct twifs_node* -twifs_file_node(struct twifs_node* parent, const char* name, int name_len); +twifs_file_node(struct twifs_node* parent, + const char* name, + int name_len, + uint32_t itype); struct twifs_node* -twifs_dir_node(struct twifs_node* parent, const char* name, int name_len); +twifs_dir_node(struct twifs_node* parent, + const char* name, + int name_len, + uint32_t itype); struct twifs_node* -twifs_toplevel_node(const char* name, int name_len); +twifs_toplevel_node(const char* name, int name_len, uint32_t itype); int twifs_rm_node(struct twifs_node* node); diff --git a/lunaix-os/includes/lunaix/tty/console.h b/lunaix-os/includes/lunaix/tty/console.h index 9eb4ea0..dee64a2 100644 --- a/lunaix-os/includes/lunaix/tty/console.h +++ b/lunaix-os/includes/lunaix/tty/console.h @@ -1,7 +1,7 @@ #ifndef __LUNAIX_CONSOLE_H #define __LUNAIX_CONSOLE_H -#include +#include #include struct console diff --git a/lunaix-os/includes/lunaix/types.h b/lunaix-os/includes/lunaix/types.h index 4a1f275..3069a83 100644 --- a/lunaix-os/includes/lunaix/types.h +++ b/lunaix-os/includes/lunaix/types.h @@ -21,5 +21,6 @@ // TODO: WTERMSIG typedef int32_t pid_t; +typedef int64_t lba_t; #endif /* __LUNAIX_TYPES_H */ diff --git a/lunaix-os/kernel/block.c b/lunaix-os/kernel/block.c index d88017d..97e9bd6 100644 --- a/lunaix-os/kernel/block.c +++ b/lunaix-os/kernel/block.c @@ -134,7 +134,7 @@ __block_register(struct block_dev* bdev) return 0; } - struct device* dev = device_add(NULL, bdev, "sd%c", 'a' + free_slot); + struct device* dev = device_addvol(NULL, bdev, "sd%c", 'a' + free_slot); dev->write = __block_write; dev->read = __block_read; diff --git a/lunaix-os/kernel/demos/iotest.c b/lunaix-os/kernel/demos/iotest.c index 0cf7cba..99300bd 100644 --- a/lunaix-os/kernel/demos/iotest.c +++ b/lunaix-os/kernel/demos/iotest.c @@ -13,10 +13,15 @@ _iotest_main() "There were two regal sisters who ruled together " "and created harmony for all the land."; - int fd = open("/dev/sda", 0); // sda 设备 - 硬盘 + // sda 设备 - 硬盘 + // sda设备属于容积设备(Volumetric Device), + // Lunaix会尽可能缓存任何对此设备的上层读写,并使用延迟写入策略。(FO_DIRECT可用于屏蔽该功能) + int fd = open("/dev/sda", 0); - // tty 设备 - 控制台,使用O_DIRECT打开,即所有IO绕过Lunaix内核的缓存机制 - int tty = open("/dev/tty", FO_DIRECT); + // tty 设备 - 控制台。 + // tty设备属于序列设备(Sequential Device),该类型设备的上层读写 + // 无须经过Lunaix的缓存层,而是直接下发到底层驱动。(不受FO_DIRECT的影响) + int tty = open("/dev/tty", 0); if (fd < 0 || tty < 0) { kprintf(KERROR "fail to open (%d)\n", geterrno()); @@ -25,7 +30,12 @@ _iotest_main() // 移动指针至512字节,在大多数情况下,这是第二个逻辑扇区的起始处 lseek(fd, 512, FSEEK_SET); - write(fd, test_sequence, sizeof(test_sequence)); + + // 总共写入 64 * 136 字节,会产生3个页作为缓存 + for (size_t i = 0; i < 64; i++) { + write(fd, test_sequence, sizeof(test_sequence)); + } + lseek(fd, 521, FSEEK_SET); write(fd, test_sequence, sizeof(test_sequence)); @@ -38,6 +48,7 @@ _iotest_main() write(tty, read_out, sizeof(read_out)); write(tty, "\n", 1); + // 关闭文件,这同时会将页缓存中的数据下发到底层驱动 close(fd); close(tty); diff --git a/lunaix-os/kernel/device.c b/lunaix-os/kernel/device.c index f114431..2471a9c 100644 --- a/lunaix-os/kernel/device.c +++ b/lunaix-os/kernel/device.c @@ -16,19 +16,20 @@ __dev_write(struct v_file* file, void* buffer, size_t len, size_t fpos); void device_init() { - dev_root = twifs_toplevel_node("dev", 3); + dev_root = twifs_toplevel_node("dev", 3, 0); llist_init_head(&dev_list); } struct device* -device_add(struct device* parent, void* underlay, char* name_fmt, ...) +__device_add(struct device* parent, + void* underlay, + char* name_fmt, + uint32_t type, + va_list args) { struct device* dev = vzalloc(sizeof(struct device)); - va_list args; - va_start(args, name_fmt); - size_t strlen = __sprintf_internal(dev->name_val, name_fmt, DEVICE_NAME_SIZE, args); @@ -40,13 +41,38 @@ device_add(struct device* parent, void* underlay, char* name_fmt, ...) llist_append(&dev_list, &dev->dev_list); struct twifs_node* dev_node = - twifs_file_node(dev_root, dev->name_val, strlen); + twifs_file_node(dev_root, dev->name_val, strlen, type); dev_node->data = dev; - dev_node->fops.read = __dev_read; - dev_node->fops.write = __dev_write; + dev_node->ops.read = __dev_read; + dev_node->ops.write = __dev_write; dev->fs_node = dev_node; + return dev; +} + +struct device* +device_addseq(struct device* parent, void* underlay, char* name_fmt, ...) +{ + va_list args; + va_start(args, name_fmt); + + struct device* dev = + __device_add(parent, underlay, name_fmt, VFS_IFSEQDEV, args); + + va_end(args); + return dev; +} + +struct device* +device_addvol(struct device* parent, void* underlay, char* name_fmt, ...) +{ + va_list args; + va_start(args, name_fmt); + + struct device* dev = + __device_add(parent, underlay, name_fmt, VFS_IFVOLDEV, args); + va_end(args); return dev; } diff --git a/lunaix-os/kernel/ds/btrie.c b/lunaix-os/kernel/ds/btrie.c index 92f034b..fd173b9 100644 --- a/lunaix-os/kernel/ds/btrie.c +++ b/lunaix-os/kernel/ds/btrie.c @@ -25,7 +25,7 @@ __btrie_traversal(struct btrie* root, uint32_t index, int options) struct btrie_node* tree = root->btrie_root; // Time complexity: O(log_2(log_2(N))) where N is the index to lookup - while (lz && tree) { + while (bitmask && tree) { i = (index & bitmask) >> lz; struct btrie_node *subtree = 0, *pos, *n; @@ -61,6 +61,7 @@ btrie_init(struct btrie* btrie, uint32_t trunc_bits) { btrie->btrie_root = vzalloc(sizeof(struct btrie_node)); llist_init_head(&btrie->btrie_root->nodes); + llist_init_head(&btrie->btrie_root->children); btrie->truncated = trunc_bits; } diff --git a/lunaix-os/kernel/fs/pcache.c b/lunaix-os/kernel/fs/pcache.c index a1632a1..3db7571 100644 --- a/lunaix-os/kernel/fs/pcache.c +++ b/lunaix-os/kernel/fs/pcache.c @@ -35,7 +35,7 @@ pcache_new_page(struct pcache* pcache, uint32_t index) { void* pg = pmm_alloc_page(KERNEL_PID, 0); void* pg_v = vmm_vmap(pg, PG_SIZE, PG_PREM_URW); - struct pcache_pg* ppg = valloc(sizeof(struct pcache_pg)); + struct pcache_pg* ppg = vzalloc(sizeof(struct pcache_pg)); ppg->pg = pg_v; llist_append(&pcache->pages, &ppg->pg_list); @@ -74,9 +74,9 @@ pcache_get_page(struct pcache* pcache, } int -pcache_write(struct v_file* file, void* data, uint32_t len) +pcache_write(struct v_file* file, void* data, uint32_t len, uint32_t fpos) { - uint32_t pg_off, buf_off = 0, fpos = file->f_pos; + uint32_t pg_off, buf_off = 0; struct pcache* pcache = file->inode->pg_cache; struct pcache_pg* pg; @@ -95,18 +95,19 @@ pcache_write(struct v_file* file, void* data, uint32_t len) } int -pcache_read(struct v_file* file, void* data, uint32_t len) +pcache_read(struct v_file* file, void* data, uint32_t len, uint32_t fpos) { - uint32_t pg_off, buf_off = 0, new_pg = 0, fpos = file->f_pos; + uint32_t pg_off, buf_off = 0, new_pg = 0; int errno = 0; struct pcache* pcache = file->inode->pg_cache; struct pcache_pg* pg; + struct v_inode* inode = file->inode; while (buf_off < len) { if (pcache_get_page(pcache, fpos, &pg_off, &pg)) { // Filling up the page - errno = file->ops.read(file, pg->pg, PG_SIZE, pg->fpos); - if (errno > 0 && errno < PG_SIZE) { + errno = inode->default_fops.read(file, pg->pg, PG_SIZE, pg->fpos); + if (errno >= 0 && errno < PG_SIZE) { // EOF len = buf_off + errno; } else if (errno < 0) { @@ -142,7 +143,8 @@ pcache_commit(struct v_file* file, struct pcache_pg* page) return; } - int errno = file->ops.write(file, page->pg, PG_SIZE, page->fpos); + struct v_inode* inode = file->inode; + int errno = inode->default_fops.write(file, page->pg, PG_SIZE, page->fpos); if (!errno) { page->flags &= ~PCACHE_DIRTY; diff --git a/lunaix-os/kernel/fs/twifs/twifs.c b/lunaix-os/kernel/fs/twifs/twifs.c index e3abe4b..f535084 100644 --- a/lunaix-os/kernel/fs/twifs/twifs.c +++ b/lunaix-os/kernel/fs/twifs/twifs.c @@ -43,6 +43,12 @@ __twifs_mkdir(struct v_inode* inode, struct v_dnode* dnode); int __twifs_rmstuff(struct v_inode* inode); +int +__twifs_fwrite(struct v_file* file, void* buffer, size_t len, size_t fpos); + +int +__twifs_fread(struct v_file* file, void* buffer, size_t len, size_t fpos); + void twifs_init() { @@ -55,16 +61,20 @@ twifs_init() fsm_register(twifs); - fs_root = twifs_dir_node(NULL, NULL, 0); + fs_root = twifs_dir_node(NULL, NULL, 0, 0); } struct twifs_node* -__twifs_new_node(struct twifs_node* parent, const char* name, int name_len) +__twifs_new_node(struct twifs_node* parent, + const char* name, + int name_len, + uint32_t itype) { struct twifs_node* node = cake_grab(twi_pile); memset(node, 0, sizeof(*node)); node->name = HSTR(name, name_len); + node->itype = itype; hstr_rehash(&node->name, HSTR_FULL_HASH); llist_init_head(&node->children); @@ -78,7 +88,7 @@ __twifs_new_node(struct twifs_node* parent, const char* name, int name_len) int twifs_rm_node(struct twifs_node* node) { - if ((node->itype & VFS_INODE_TYPE_DIR) && !llist_empty(&node->children)) { + if ((node->itype & VFS_IFDIR) && !llist_empty(&node->children)) { return ENOTEMPTY; } llist_delete(&node->siblings); @@ -88,10 +98,13 @@ twifs_rm_node(struct twifs_node* node) } struct twifs_node* -twifs_file_node(struct twifs_node* parent, const char* name, int name_len) +twifs_file_node(struct twifs_node* parent, + const char* name, + int name_len, + uint32_t itype) { - struct twifs_node* twi_node = __twifs_new_node(parent, name, name_len); - twi_node->itype = VFS_INODE_TYPE_FILE; + struct twifs_node* twi_node = + __twifs_new_node(parent, name, name_len, VFS_IFFILE | itype); struct v_inode* twi_inode = __twifs_create_inode(twi_node); twi_node->inode = twi_inode; @@ -100,7 +113,10 @@ twifs_file_node(struct twifs_node* parent, const char* name, int name_len) } struct twifs_node* -twifs_dir_node(struct twifs_node* parent, const char* name, int name_len) +twifs_dir_node(struct twifs_node* parent, + const char* name, + int name_len, + uint32_t itype) { struct hstr hname = HSTR(name, name_len); hstr_rehash(&hname, HSTR_FULL_HASH); @@ -109,31 +125,30 @@ twifs_dir_node(struct twifs_node* parent, const char* name, int name_len) return node; } - struct twifs_node* twi_node = __twifs_new_node(parent, name, name_len); - twi_node->itype = VFS_INODE_TYPE_DIR; + struct twifs_node* twi_node = + __twifs_new_node(parent, name, name_len, VFS_IFDIR | itype); struct v_inode* twi_inode = __twifs_create_inode(twi_node); - twi_node->fops.readdir = __twifs_iterate_dir; twi_node->inode = twi_inode; return twi_node; } struct twifs_node* -twifs_toplevel_node(const char* name, int name_len) +twifs_toplevel_node(const char* name, int name_len, uint32_t itype) { - return twifs_dir_node(fs_root, name, name_len); + return twifs_dir_node(fs_root, name, name_len, itype); } int __twifs_mkdir(struct v_inode* inode, struct v_dnode* dnode) { struct twifs_node* parent_node = (struct twifs_node*)inode->data; - if (!(parent_node->itype & VFS_INODE_TYPE_DIR)) { + if (!(parent_node->itype & VFS_IFDIR)) { return ENOTDIR; } struct twifs_node* new_node = - twifs_dir_node(parent_node, dnode->name.value, dnode->name.len); + twifs_dir_node(parent_node, dnode->name.value, dnode->name.len, 0); dnode->inode = new_node->inode; return 0; @@ -163,9 +178,33 @@ __twifs_create_inode(struct twifs_node* twi_node) inode->ops.rmdir = __twifs_rmstuff; inode->ops.open = __twifs_openfile; + inode->default_fops = (struct v_file_ops){ .read = __twifs_fread, + .write = __twifs_fwrite, + .readdir = __twifs_iterate_dir }; + return inode; } +int +__twifs_fwrite(struct v_file* file, void* buffer, size_t len, size_t fpos) +{ + struct twifs_node* twi_node = (struct twifs_node*)file->inode->data; + if (!twi_node || !twi_node->ops.write) { + return ENOTSUP; + } + return twi_node->ops.write(file, buffer, len, fpos); +} + +int +__twifs_fread(struct v_file* file, void* buffer, size_t len, size_t fpos) +{ + struct twifs_node* twi_node = (struct twifs_node*)file->inode->data; + if (!twi_node || !twi_node->ops.read) { + return ENOTSUP; + } + return twi_node->ops.read(file, buffer, len, fpos); +} + struct twifs_node* __twifs_get_node(struct twifs_node* parent, struct hstr* name) { @@ -194,7 +233,7 @@ __twifs_dirlookup(struct v_inode* inode, struct v_dnode* dnode) { struct twifs_node* twi_node = (struct twifs_node*)inode->data; - if (!(twi_node->itype & VFS_INODE_TYPE_DIR)) { + if (!(twi_node->itype & VFS_IFDIR)) { return ENOTDIR; } @@ -231,8 +270,6 @@ __twifs_openfile(struct v_inode* inode, struct v_file* file) { struct twifs_node* twi_node = (struct twifs_node*)inode->data; if (twi_node) { - file->inode = twi_node->inode; - file->ops = twi_node->fops; return 0; } return ENOTSUP; diff --git a/lunaix-os/kernel/fs/vfs.c b/lunaix-os/kernel/fs/vfs.c index f09a701..53d21d8 100644 --- a/lunaix-os/kernel/fs/vfs.c +++ b/lunaix-os/kernel/fs/vfs.c @@ -72,6 +72,7 @@ vfs_init() // 创建一个根superblock,用来蕴含我们的根目录。 root_sb = vfs_sb_alloc(); root_sb->root = vfs_d_alloc(); + root_sb->root->inode = vfs_i_alloc(); } inline struct hbucket* @@ -237,7 +238,7 @@ vfs_walk(struct v_dnode* start, errno = ELOOP; continue; } - if ((interim->inode->itype & VFS_INODE_TYPE_SYMLINK) && + if ((interim->inode->itype & VFS_IFSYMLINK) && !(options & VFS_WALK_NOFOLLOW) && interim->inode->ops.read_symlink) { errno = interim->inode->ops.read_symlink(interim->inode, &pathname); @@ -327,22 +328,23 @@ vfs_open(struct v_dnode* dnode, struct v_file** file) return ENOTSUP; } + struct v_inode* inode = dnode->inode; struct v_file* vfile = cake_grab(file_pile); memset(vfile, 0, sizeof(*vfile)); vfile->dnode = dnode; - vfile->inode = dnode->inode; + vfile->inode = inode; vfile->ref_count = 1; - dnode->inode->open_count++; + vfile->ops = inode->default_fops; + inode->open_count++; - if ((dnode->inode->itype & VFS_INODE_TYPE_FILE) && - !dnode->inode->pg_cache) { + if ((inode->itype & VFS_IFFILE) && !inode->pg_cache) { struct pcache* pcache = vzalloc(sizeof(struct pcache)); pcache_init(pcache); - dnode->inode->pg_cache = pcache; + inode->pg_cache = pcache; } - int errno = dnode->inode->ops.open(dnode->inode, vfile); + int errno = inode->ops.open(inode, vfile); if (errno) { cake_release(file_pile, vfile); } else { @@ -385,6 +387,7 @@ int vfs_fsync(struct v_file* file) { int errno = ENOTSUP; + pcache_commit_all(file); if (file->ops.sync) { errno = file->ops.sync(file); } @@ -459,6 +462,7 @@ vfs_i_free(struct v_inode* inode) #define FLOCATE_CREATE_EMPTY 1 #define DO_STATUS(errno) SYSCALL_ESTATUS(__current->k_status = errno) +#define DO_STATUS_OR_RETURN(errno) ({ errno < 0 ? DO_STATUS(errno) : errno; }) int __vfs_try_locate_file(const char* path, @@ -492,11 +496,17 @@ __vfs_try_locate_file(const char* path, } int -__vfs_do_open(struct v_file** file_out, const char* path, int options) +__file_cached_read(struct v_file* file, void* buf, size_t len, size_t fpos) { - int errno; + return pcache_read(file, buf, len, fpos); +} + +int +vfs_do_open(const char* path, int options) +{ + int errno, fd; struct v_dnode *dentry, *file; - struct v_file* opened_file = 0; + struct v_file* ofile = 0; errno = __vfs_try_locate_file(path, &dentry, &file, 0); @@ -504,31 +514,35 @@ __vfs_do_open(struct v_file** file_out, const char* path, int options) errno = dentry->inode->ops.create(dentry->inode); } - if (!errno) { - errno = vfs_open(file, &opened_file); + if (!errno && (errno = vfs_open(file, &ofile))) { + return errno; } - *file_out = opened_file; - return errno; -} - -__DEFINE_LXSYSCALL2(int, open, const char*, path, int, options) -{ - struct v_file* opened_file; - int errno = __vfs_do_open(&opened_file, path, options), fd; + struct v_inode* o_inode = ofile->inode; + if (!(o_inode->itype & VFS_IFSEQDEV) && !(options & FO_DIRECT)) { + // XXX Change here accordingly when signature of pcache_r/w changed. + ofile->ops.read = pcache_read; + ofile->ops.write = pcache_write; + } if (!errno && !(errno = vfs_alloc_fdslot(&fd))) { struct v_fd* fd_s = vzalloc(sizeof(*fd_s)); - opened_file->f_pos = - opened_file->inode->fsize & -((options & FO_APPEND) != 0); - fd_s->file = opened_file; + ofile->f_pos = ofile->inode->fsize & -((options & FO_APPEND) != 0); + fd_s->file = ofile; fd_s->flags = options; __current->fdtable->fds[fd] = fd_s; return fd; } - return DO_STATUS(errno); + return errno; +} + +__DEFINE_LXSYSCALL2(int, open, const char*, path, int, options) +{ + int errno = vfs_do_open(path, options); + return DO_STATUS_OR_RETURN(errno); } + #define TEST_FD(fd) (fd >= 0 && fd < VFS_MAX_FD) #define GET_FD(fd, fd_s) (TEST_FD(fd) && (fd_s = __current->fdtable->fds[fd])) @@ -572,7 +586,7 @@ __DEFINE_LXSYSCALL2(int, readdir, int, fd, struct dirent*, dent) int errno; if (!GET_FD(fd, fd_s)) { errno = EBADF; - } else if (!(fd_s->file->inode->itype & VFS_INODE_TYPE_DIR)) { + } else if (!(fd_s->file->inode->itype & VFS_IFDIR)) { errno = ENOTDIR; } else { struct dir_context dctx = @@ -611,7 +625,7 @@ __DEFINE_LXSYSCALL1(int, mkdir, const char*, path) errno = ENOTSUP; } else if (!parent->inode->ops.mkdir) { errno = ENOTSUP; - } else if (!(parent->inode->itype & VFS_INODE_TYPE_DIR)) { + } else if (!(parent->inode->itype & VFS_IFDIR)) { errno = ENOTDIR; } else { dir = vfs_d_alloc(); @@ -638,16 +652,12 @@ __DEFINE_LXSYSCALL3(int, read, int, fd, void*, buf, size_t, count) } struct v_file* file = fd_s->file; - if ((file->inode->itype & VFS_INODE_TYPE_DIR)) { + if ((file->inode->itype & VFS_IFDIR)) { errno = EISDIR; goto done; } - if ((fd_s->flags & FO_DIRECT)) { - errno = file->ops.read(file, buf, count, file->f_pos); - } else { - errno = pcache_read(file, buf, count); - } + errno = file->ops.read(file, buf, count, file->f_pos); if (errno > 0) { file->f_pos += errno; @@ -668,16 +678,12 @@ __DEFINE_LXSYSCALL3(int, write, int, fd, void*, buf, size_t, count) } struct v_file* file = fd_s->file; - if ((file->inode->itype & VFS_INODE_TYPE_DIR)) { + if ((file->inode->itype & VFS_IFDIR)) { errno = EISDIR; goto done; } - if ((fd_s->flags & FO_DIRECT)) { - errno = file->ops.write(file, buf, count, file->f_pos); - } else { - errno = pcache_write(file, buf, count); - } + errno = file->ops.write(file, buf, count, file->f_pos); if (errno > 0) { file->f_pos += errno; @@ -839,7 +845,7 @@ __DEFINE_LXSYSCALL1(int, rmdir, const char*, pathname) goto done; } - if ((dnode->inode->itype & VFS_INODE_TYPE_DIR)) { + if ((dnode->inode->itype & VFS_IFDIR)) { errno = dnode->inode->ops.rmdir(dnode->inode); } else { errno = ENOTDIR; @@ -855,7 +861,7 @@ __vfs_do_unlink(struct v_inode* inode) int errno; if (inode->open_count) { errno = EBUSY; - } else if (!(inode->itype & VFS_INODE_TYPE_DIR)) { + } else if (!(inode->itype & VFS_IFDIR)) { // TODO handle symbolic link and type other than regular file errno = inode->ops.unlink(inode); if (!errno) { diff --git a/lunaix-os/kernel/lxconsole.c b/lunaix-os/kernel/lxconsole.c index 894a1b8..e43ebc5 100644 --- a/lunaix-os/kernel/lxconsole.c +++ b/lunaix-os/kernel/lxconsole.c @@ -36,7 +36,7 @@ lxconsole_init() lx_console.flush_timer = NULL; - struct device* tty_dev = device_add(NULL, &lx_console, "tty"); + struct device* tty_dev = device_addseq(NULL, &lx_console, "tty"); tty_dev->write = __tty_write; } @@ -126,12 +126,19 @@ console_write(struct console* console, uint8_t* data, size_t size) char c; int lines = 0; + int j = 0; for (size_t i = 0; i < size; i++) { c = data[i]; - buffer[(ptr + i) % console->buffer.size] = c; + if (!c) { + continue; + } + buffer[(ptr + j) % console->buffer.size] = c; lines += (c == '\n'); + j++; } + size = j; + uintptr_t new_ptr = (ptr + size) % console->buffer.size; console->buffer.wr_pos = new_ptr; diff --git a/lunaix-os/kernel/sched.c b/lunaix-os/kernel/sched.c index 37c02d1..be99525 100644 --- a/lunaix-os/kernel/sched.c +++ b/lunaix-os/kernel/sched.c @@ -322,7 +322,7 @@ destroy_process(pid_t pid) for (size_t i = 0; i < VFS_MAX_FD; i++) { struct v_fd* fd = proc->fdtable->fds[i]; if (fd) - vfs_close(fd); + vfs_close(fd->file); } vfree(proc->fdtable); -- 2.27.0