fix: separate any i/o to sequential device from caching layer
authorMinep <zelong56@gmail.com>
Sun, 7 Aug 2022 16:23:20 +0000 (17:23 +0100)
committerMinep <zelong56@gmail.com>
Sun, 7 Aug 2022 16:23:20 +0000 (17:23 +0100)
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.

14 files changed:
lunaix-os/includes/lunaix/device.h
lunaix-os/includes/lunaix/fs.h
lunaix-os/includes/lunaix/fs/twifs.h
lunaix-os/includes/lunaix/tty/console.h
lunaix-os/includes/lunaix/types.h
lunaix-os/kernel/block.c
lunaix-os/kernel/demos/iotest.c
lunaix-os/kernel/device.c
lunaix-os/kernel/ds/btrie.c
lunaix-os/kernel/fs/pcache.c
lunaix-os/kernel/fs/twifs/twifs.c
lunaix-os/kernel/fs/vfs.c
lunaix-os/kernel/lxconsole.c
lunaix-os/kernel/sched.c

index dde14a3f391d6eb31fdd1e0300ca1105935d1399..08d25c4a2776ee399e450951ce82efd582823485 100644 (file)
@@ -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);
index 2d405eec00eeba31bd0e1e1af63641c77d5892e1..87f259af83dfbc57f2833a6743d3c7c4f2a49df9 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <hal/ahci/hba.h>
 #include <lunaix/block.h>
+#include <lunaix/clock.h>
 #include <lunaix/ds/btrie.h>
 #include <lunaix/ds/hashtable.h>
 #include <lunaix/ds/hstr.h>
 #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);
index 31875ef24fab16856de08bd40bf250ae22d709f8..f2d6b15bf2197eae356b7165c81f93bbb1e30bc9 100644 (file)
@@ -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);
index 9eb4ea08192f98db5035608d8c800ed20b4ab79b..dee64a278540ce91e527360bc98a565d5198e14d 100644 (file)
@@ -1,7 +1,7 @@
 #ifndef __LUNAIX_CONSOLE_H
 #define __LUNAIX_CONSOLE_H
 
-#include <lunaix/ds/fifobuf.h>
+#include <lunaix/ds/fifo.h>
 #include <lunaix/timer.h>
 
 struct console
index 4a1f275d290037ce1732b2120eac36009ace6c13..3069a833bdb9b78d9eb20889fa012a8ffcbf17b7 100644 (file)
@@ -21,5 +21,6 @@
 // TODO: WTERMSIG
 
 typedef int32_t pid_t;
+typedef int64_t lba_t;
 
 #endif /* __LUNAIX_TYPES_H */
index d88017da73198d73a9be3a49035c73c4521dad59..97e9bd69d83d286e2705a943d3366109414d250c 100644 (file)
@@ -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;
 
index 0cf7cba2e92a80dc37c221b7bdec6437eaf43369..99300bdb4783daa2b9e4503825f909c7d7e7de35 100644 (file)
@@ -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);
 
index f114431169142f1ed54f092ef7b146544409c4ea..2471a9cc8aac18d3cb897f5ecb3678033d5d086d 100644 (file)
@@ -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;
 }
index 92f034bebce60979324d3bf992da019c16e090b4..fd173b9455c701b99ff60b12ed9ae7a3acb7b01c 100644 (file)
@@ -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;
 }
 
index a1632a1a6c71a3792056dc0bc75b329398b3c3cb..3db75718592896c96b0968c73c70b84dd2760240 100644 (file)
@@ -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;
index e3abe4b4c2a682577effbfd965c06ea15f318a91..f53508418ed4bea89d23c2cafac0bf793e53438e 100644 (file)
@@ -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;
index f09a701ef1cebee15bdf4a880a88fd8477107072..53d21d8b026baa7f07ce38bc34a12cda78c0ee90 100644 (file)
@@ -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) {
index 894a1b8e9837d636bbca6bf1a65355000b5316c4..e43ebc5883e11b496a3826f1ade11af34ba3f485 100644 (file)
@@ -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;
 
index 37c02d1c705988dc5d53b0e738bbaaa83370ce37..be9952519fe282993a29154123c89a90f8d7b249 100644 (file)
@@ -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);