From: Tulio A M Mendes Date: Fri, 13 Feb 2026 21:23:05 +0000 (-0300) Subject: refactor: migrate all filesystems to struct file_operations X-Git-Url: https://projects.tadryanom.me/sitemap.xml?a=commitdiff_plain;h=95aa2ddc1e14cbd8ab8271b080c2811a8615dcf9;p=AdrOS.git refactor: migrate all filesystems to struct file_operations Every filesystem and device driver now defines static const file_operations tables and assigns f_ops on every node: - tmpfs: tmpfs_file_ops, tmpfs_dir_ops - devfs: devfs_dir_ops, dev_null_ops, dev_zero_ops, dev_random_ops - ext2: ext2_file_fops, ext2_dir_fops - fat: fat_file_fops, fat_dir_fops - diskfs: diskfs_file_fops, diskfs_dir_fops - overlayfs: overlay_file_ops, overlay_dir_ops - tty: tty_fops (console + tty) - pipe: pipe_read_fops, pipe_write_fops - socket: sock_fops - vbe: fb0_fops - keyboard: kbd_fops VFS dispatch (fs.c + syscall.c) checks f_ops first, falls back to legacy per-node pointers. Legacy pointers are still set (dual assignment) for callers that access them directly (e.g. overlayfs layer delegation). Phase B3 will remove legacy pointers after all direct accesses are eliminated. 20/20 smoke tests pass, cppcheck clean. --- diff --git a/src/drivers/keyboard.c b/src/drivers/keyboard.c index 439e0f4..f3fd89b 100644 --- a/src/drivers/keyboard.c +++ b/src/drivers/keyboard.c @@ -113,10 +113,16 @@ void keyboard_init(void) { } void keyboard_register_devfs(void) { + static const struct file_operations kbd_fops = { + .read = kbd_dev_read, + .poll = kbd_dev_poll, + }; + memset(&g_dev_kbd_node, 0, sizeof(g_dev_kbd_node)); strcpy(g_dev_kbd_node.name, "kbd"); g_dev_kbd_node.flags = FS_CHARDEVICE; g_dev_kbd_node.inode = 21; + g_dev_kbd_node.f_ops = &kbd_fops; g_dev_kbd_node.read = &kbd_dev_read; g_dev_kbd_node.poll = &kbd_dev_poll; devfs_register_device(&g_dev_kbd_node); diff --git a/src/drivers/vbe.c b/src/drivers/vbe.c index 38d8cea..dbbb81d 100644 --- a/src/drivers/vbe.c +++ b/src/drivers/vbe.c @@ -180,11 +180,19 @@ static uintptr_t fb0_mmap(fs_node_t* node, uintptr_t addr, uint32_t length, uint void vbe_register_devfs(void) { if (!g_vbe_ready) return; + static const struct file_operations fb0_fops = { + .read = fb0_read, + .write = fb0_write, + .ioctl = fb0_ioctl, + .mmap = fb0_mmap, + }; + memset(&g_dev_fb0_node, 0, sizeof(g_dev_fb0_node)); strcpy(g_dev_fb0_node.name, "fb0"); g_dev_fb0_node.flags = FS_CHARDEVICE; g_dev_fb0_node.inode = 20; g_dev_fb0_node.length = g_vbe.size; + g_dev_fb0_node.f_ops = &fb0_fops; g_dev_fb0_node.read = &fb0_read; g_dev_fb0_node.write = &fb0_write; g_dev_fb0_node.ioctl = &fb0_ioctl; diff --git a/src/kernel/devfs.c b/src/kernel/devfs.c index bbb3a4a..38d51e5 100644 --- a/src/kernel/devfs.c +++ b/src/kernel/devfs.c @@ -16,6 +16,40 @@ static fs_node_t g_dev_random; static fs_node_t g_dev_urandom; static uint32_t g_devfs_inited = 0; +static struct fs_node* devfs_finddir_impl(struct fs_node* node, const char* name); +static int devfs_readdir_impl(struct fs_node* node, uint32_t* inout_index, void* buf, uint32_t buf_len); +static uint32_t dev_null_read(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer); +static uint32_t dev_null_write(fs_node_t* node, uint32_t offset, uint32_t size, const uint8_t* buffer); +static uint32_t dev_zero_read(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer); +static uint32_t dev_zero_write(fs_node_t* node, uint32_t offset, uint32_t size, const uint8_t* buffer); +static uint32_t dev_random_read(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer); +static uint32_t dev_random_write(fs_node_t* node, uint32_t offset, uint32_t size, const uint8_t* buffer); +static int dev_null_poll(fs_node_t* node, int events); +static int dev_always_ready_poll(fs_node_t* node, int events); + +static const struct file_operations devfs_dir_ops = { + .finddir = devfs_finddir_impl, + .readdir = devfs_readdir_impl, +}; + +static const struct file_operations dev_null_ops = { + .read = dev_null_read, + .write = dev_null_write, + .poll = dev_null_poll, +}; + +static const struct file_operations dev_zero_ops = { + .read = dev_zero_read, + .write = dev_zero_write, + .poll = dev_always_ready_poll, +}; + +static const struct file_operations dev_random_ops = { + .read = dev_random_read, + .write = dev_random_write, + .poll = dev_always_ready_poll, +}; + /* --- Device registry --- */ static fs_node_t* g_registered[DEVFS_MAX_DEVICES]; static int g_registered_count = 0; @@ -189,48 +223,45 @@ static void devfs_init_once(void) { g_dev_root.vfs.flags = FS_DIRECTORY; g_dev_root.vfs.inode = 1; g_dev_root.vfs.length = 0; - g_dev_root.vfs.read = 0; - g_dev_root.vfs.write = 0; - g_dev_root.vfs.open = 0; - g_dev_root.vfs.close = 0; - g_dev_root.vfs.finddir = &devfs_finddir_impl; - g_dev_root.vfs.readdir = &devfs_readdir_impl; + g_dev_root.vfs.f_ops = &devfs_dir_ops; + g_dev_root.vfs.finddir = devfs_finddir_impl; + g_dev_root.vfs.readdir = devfs_readdir_impl; memset(&g_dev_null, 0, sizeof(g_dev_null)); strcpy(g_dev_null.name, "null"); g_dev_null.flags = FS_CHARDEVICE; g_dev_null.inode = 2; - g_dev_null.length = 0; - g_dev_null.read = &dev_null_read; - g_dev_null.write = &dev_null_write; - g_dev_null.poll = &dev_null_poll; - g_dev_null.open = 0; - g_dev_null.close = 0; - g_dev_null.finddir = 0; + g_dev_null.f_ops = &dev_null_ops; + g_dev_null.read = dev_null_read; + g_dev_null.write = dev_null_write; + g_dev_null.poll = dev_null_poll; memset(&g_dev_zero, 0, sizeof(g_dev_zero)); strcpy(g_dev_zero.name, "zero"); g_dev_zero.flags = FS_CHARDEVICE; g_dev_zero.inode = 7; - g_dev_zero.read = &dev_zero_read; - g_dev_zero.write = &dev_zero_write; - g_dev_zero.poll = &dev_always_ready_poll; + g_dev_zero.f_ops = &dev_zero_ops; + g_dev_zero.read = dev_zero_read; + g_dev_zero.write = dev_zero_write; + g_dev_zero.poll = dev_always_ready_poll; memset(&g_dev_random, 0, sizeof(g_dev_random)); strcpy(g_dev_random.name, "random"); g_dev_random.flags = FS_CHARDEVICE; g_dev_random.inode = 8; - g_dev_random.read = &dev_random_read; - g_dev_random.write = &dev_random_write; - g_dev_random.poll = &dev_always_ready_poll; + g_dev_random.f_ops = &dev_random_ops; + g_dev_random.read = dev_random_read; + g_dev_random.write = dev_random_write; + g_dev_random.poll = dev_always_ready_poll; memset(&g_dev_urandom, 0, sizeof(g_dev_urandom)); strcpy(g_dev_urandom.name, "urandom"); g_dev_urandom.flags = FS_CHARDEVICE; g_dev_urandom.inode = 9; - g_dev_urandom.read = &dev_random_read; - g_dev_urandom.write = &dev_random_write; - g_dev_urandom.poll = &dev_always_ready_poll; + g_dev_urandom.f_ops = &dev_random_ops; + g_dev_urandom.read = dev_random_read; + g_dev_urandom.write = dev_random_write; + g_dev_urandom.poll = dev_always_ready_poll; } fs_node_t* devfs_create_root(void) { diff --git a/src/kernel/diskfs.c b/src/kernel/diskfs.c index 15a506f..fede86b 100644 --- a/src/kernel/diskfs.c +++ b/src/kernel/diskfs.c @@ -461,6 +461,33 @@ static int diskfs_readdir_impl(struct fs_node* node, uint32_t* inout_index, void static void diskfs_set_dir_ops(fs_node_t* vfs); static int diskfs_vfs_truncate(struct fs_node* node, uint32_t length); +static struct fs_node* diskfs_root_finddir(struct fs_node* node, const char* name); +static int diskfs_vfs_create(struct fs_node* dir, const char* name, uint32_t flags, struct fs_node** out); +static int diskfs_vfs_mkdir(struct fs_node* dir, const char* name); +static int diskfs_vfs_unlink(struct fs_node* dir, const char* name); +static int diskfs_vfs_rmdir(struct fs_node* dir, const char* name); +static int diskfs_vfs_rename(struct fs_node* old_dir, const char* old_name, + struct fs_node* new_dir, const char* new_name); +static int diskfs_vfs_link(struct fs_node* dir, const char* name, struct fs_node* target); + +static const struct file_operations diskfs_file_fops = { + .read = diskfs_read_impl, + .write = diskfs_write_impl, + .close = diskfs_close_impl, + .truncate = diskfs_vfs_truncate, +}; + +static const struct file_operations diskfs_dir_fops = { + .close = diskfs_close_impl, + .finddir = diskfs_root_finddir, + .readdir = diskfs_readdir_impl, + .create = diskfs_vfs_create, + .mkdir = diskfs_vfs_mkdir, + .unlink = diskfs_vfs_unlink, + .rmdir = diskfs_vfs_rmdir, + .rename = diskfs_vfs_rename, + .link = diskfs_vfs_link, +}; static struct fs_node* diskfs_root_finddir(struct fs_node* node, const char* name) { struct diskfs_node* parent = (struct diskfs_node*)node; @@ -492,18 +519,17 @@ static struct fs_node* diskfs_root_finddir(struct fs_node* node, const char* nam if (sb.inodes[cino].type == DISKFS_INODE_DIR) { dn->vfs.flags = FS_DIRECTORY; dn->vfs.length = 0; - dn->vfs.read = 0; - dn->vfs.write = 0; + dn->vfs.f_ops = &diskfs_dir_fops; dn->vfs.finddir = &diskfs_root_finddir; dn->vfs.readdir = &diskfs_readdir_impl; diskfs_set_dir_ops(&dn->vfs); } else { dn->vfs.flags = FS_FILE; dn->vfs.length = sb.inodes[cino].size_bytes; + dn->vfs.f_ops = &diskfs_file_fops; dn->vfs.read = &diskfs_read_impl; dn->vfs.write = &diskfs_write_impl; dn->vfs.truncate = &diskfs_vfs_truncate; - dn->vfs.finddir = 0; } return &dn->vfs; @@ -557,11 +583,10 @@ int diskfs_open_file(const char* rel_path, uint32_t flags, fs_node_t** out_node) dn->vfs.flags = FS_FILE; dn->vfs.inode = 100 + (uint32_t)ino; dn->vfs.length = sb.inodes[ino].size_bytes; + dn->vfs.f_ops = &diskfs_file_fops; dn->vfs.read = &diskfs_read_impl; dn->vfs.write = &diskfs_write_impl; - dn->vfs.open = 0; dn->vfs.close = &diskfs_close_impl; - dn->vfs.finddir = 0; dn->ino = ino; *out_node = &dn->vfs; @@ -1068,10 +1093,7 @@ fs_node_t* diskfs_create_root(int drive) { g_root.vfs.flags = FS_DIRECTORY; g_root.vfs.inode = 100; g_root.vfs.length = 0; - g_root.vfs.read = 0; - g_root.vfs.write = 0; - g_root.vfs.open = 0; - g_root.vfs.close = 0; + g_root.vfs.f_ops = &diskfs_dir_fops; g_root.vfs.finddir = &diskfs_root_finddir; g_root.vfs.readdir = &diskfs_readdir_impl; diskfs_set_dir_ops(&g_root.vfs); diff --git a/src/kernel/ext2.c b/src/kernel/ext2.c index f9f942e..dea111a 100644 --- a/src/kernel/ext2.c +++ b/src/kernel/ext2.c @@ -530,6 +530,26 @@ static int ext2_rename_impl(struct fs_node* old_dir, const char* old_name, struct fs_node* new_dir, const char* new_name); static int ext2_truncate_impl(struct fs_node* node, uint32_t length); static int ext2_link_impl(struct fs_node* dir, const char* name, struct fs_node* target); +static void ext2_close_impl(fs_node_t* node); + +static const struct file_operations ext2_file_fops = { + .read = ext2_file_read, + .write = ext2_file_write, + .close = ext2_close_impl, + .truncate = ext2_truncate_impl, +}; + +static const struct file_operations ext2_dir_fops = { + .close = ext2_close_impl, + .finddir = ext2_finddir, + .readdir = ext2_readdir_impl, + .create = ext2_create_impl, + .mkdir = ext2_mkdir_impl, + .unlink = ext2_unlink_impl, + .rmdir = ext2_rmdir_impl, + .rename = ext2_rename_impl, + .link = ext2_link_impl, +}; static void ext2_close_impl(fs_node_t* node) { if (!node) return; @@ -569,6 +589,7 @@ static struct ext2_node* ext2_make_node(uint32_t ino, const struct ext2_inode* i if ((inode->i_mode & 0xF000) == EXT2_S_IFDIR) { en->vfs.flags = FS_DIRECTORY; en->vfs.length = inode->i_size; + en->vfs.f_ops = &ext2_dir_fops; ext2_set_dir_ops(&en->vfs); } else if ((inode->i_mode & 0xF000) == EXT2_S_IFLNK) { en->vfs.flags = FS_SYMLINK; @@ -581,6 +602,7 @@ static struct ext2_node* ext2_make_node(uint32_t ino, const struct ext2_inode* i } else { en->vfs.flags = FS_FILE; en->vfs.length = inode->i_size; + en->vfs.f_ops = &ext2_file_fops; en->vfs.read = &ext2_file_read; en->vfs.write = &ext2_file_write; en->vfs.truncate = &ext2_truncate_impl; diff --git a/src/kernel/fat.c b/src/kernel/fat.c index 46f8af2..e7fa6b3 100644 --- a/src/kernel/fat.c +++ b/src/kernel/fat.c @@ -481,6 +481,25 @@ static int fat_rmdir_impl(struct fs_node* dir, const char* name); static int fat_rename_impl(struct fs_node* old_dir, const char* old_name, struct fs_node* new_dir, const char* new_name); static int fat_truncate_impl(struct fs_node* node, uint32_t length); +static void fat_close_impl(fs_node_t* node); + +static const struct file_operations fat_file_fops = { + .read = fat_file_read, + .write = fat_file_write, + .close = fat_close_impl, + .truncate = fat_truncate_impl, +}; + +static const struct file_operations fat_dir_fops = { + .close = fat_close_impl, + .finddir = fat_finddir, + .readdir = fat_readdir_impl, + .create = fat_create_impl, + .mkdir = fat_mkdir_impl, + .unlink = fat_unlink_impl, + .rmdir = fat_rmdir_impl, + .rename = fat_rename_impl, +}; static void fat_close_impl(fs_node_t* node) { if (!node) return; @@ -513,11 +532,13 @@ static struct fat_node* fat_make_node(const struct fat_dirent* de, uint32_t pare fn->vfs.flags = FS_DIRECTORY; fn->vfs.length = 0; fn->vfs.inode = fn->first_cluster; + fn->vfs.f_ops = &fat_dir_fops; fat_set_dir_ops(&fn->vfs); } else { fn->vfs.flags = FS_FILE; fn->vfs.length = de->file_size; fn->vfs.inode = fn->first_cluster; + fn->vfs.f_ops = &fat_file_fops; fn->vfs.read = &fat_file_read; fn->vfs.write = &fat_file_write; fn->vfs.truncate = &fat_truncate_impl; diff --git a/src/kernel/overlayfs.c b/src/kernel/overlayfs.c index d441a56..d10f037 100644 --- a/src/kernel/overlayfs.c +++ b/src/kernel/overlayfs.c @@ -87,6 +87,17 @@ static uint32_t overlay_write_impl(fs_node_t* node, uint32_t offset, uint32_t si return wr; } +static const struct file_operations overlay_file_ops = { + .read = overlay_read_impl, + .write = overlay_write_impl, +}; + +static const struct file_operations overlay_dir_ops = { + .read = overlay_read_impl, + .finddir = overlay_finddir_impl, + .readdir = overlay_readdir_impl, +}; + static fs_node_t* overlay_wrap_child(struct overlay_node* parent, const char* name, fs_node_t* lower_child, fs_node_t* upper_child) { if (!parent || !parent->ofs || !name) return NULL; if (!lower_child && !upper_child) return NULL; @@ -110,10 +121,13 @@ static fs_node_t* overlay_wrap_child(struct overlay_node* parent, const char* na c->vfs.length = lower_child->length; } + if (c->vfs.flags == FS_DIRECTORY) { + c->vfs.f_ops = &overlay_dir_ops; + } else { + c->vfs.f_ops = &overlay_file_ops; + } c->vfs.read = &overlay_read_impl; c->vfs.write = (c->vfs.flags == FS_FILE) ? &overlay_write_impl : 0; - c->vfs.open = 0; - c->vfs.close = 0; c->vfs.finddir = (c->vfs.flags == FS_DIRECTORY) ? &overlay_finddir_impl : 0; c->vfs.readdir = (c->vfs.flags == FS_DIRECTORY) ? &overlay_readdir_impl : 0; @@ -153,8 +167,12 @@ static int overlay_readdir_impl(struct fs_node* node, uint32_t* inout_index, voi // Prefer upper layer readdir; fall back to lower. fs_node_t* src = dir->upper ? dir->upper : dir->lower; - if (!src || !src->readdir) return 0; - return src->readdir(src, inout_index, buf, buf_len); + if (!src) return 0; + if (src->f_ops && src->f_ops->readdir) + return src->f_ops->readdir(src, inout_index, buf, buf_len); + if (src->readdir) + return src->readdir(src, inout_index, buf, buf_len); + return 0; } static struct fs_node* overlay_finddir_impl(struct fs_node* node, const char* name) { @@ -166,11 +184,17 @@ static struct fs_node* overlay_finddir_impl(struct fs_node* node, const char* na fs_node_t* upper_child = NULL; fs_node_t* lower_child = NULL; - if (dir->upper && dir->upper->finddir) { - upper_child = dir->upper->finddir(dir->upper, name); + if (dir->upper) { + if (dir->upper->f_ops && dir->upper->f_ops->finddir) + upper_child = dir->upper->f_ops->finddir(dir->upper, name); + else if (dir->upper->finddir) + upper_child = dir->upper->finddir(dir->upper, name); } - if (dir->lower && dir->lower->finddir) { - lower_child = dir->lower->finddir(dir->lower, name); + if (dir->lower) { + if (dir->lower->f_ops && dir->lower->f_ops->finddir) + lower_child = dir->lower->f_ops->finddir(dir->lower, name); + else if (dir->lower->finddir) + lower_child = dir->lower->finddir(dir->lower, name); } if (!upper_child && !lower_child) return 0; @@ -200,10 +224,7 @@ fs_node_t* overlayfs_create_root(fs_node_t* lower_root, fs_node_t* upper_root) { root->vfs.flags = FS_DIRECTORY; root->vfs.inode = upper_root->inode; root->vfs.length = 0; - root->vfs.read = 0; - root->vfs.write = 0; - root->vfs.open = 0; - root->vfs.close = 0; + root->vfs.f_ops = &overlay_dir_ops; root->vfs.finddir = &overlay_finddir_impl; root->vfs.readdir = &overlay_readdir_impl; diff --git a/src/kernel/syscall.c b/src/kernel/syscall.c index 8a6f4ef..45a6307 100644 --- a/src/kernel/syscall.c +++ b/src/kernel/syscall.c @@ -399,6 +399,18 @@ static int pipe_poll(fs_node_t* n, int events) { return revents; } +static const struct file_operations pipe_read_fops = { + .read = pipe_read, + .close = pipe_close, + .poll = pipe_poll, +}; + +static const struct file_operations pipe_write_fops = { + .write = pipe_write, + .close = pipe_close, + .poll = pipe_poll, +}; + static int pipe_node_create(struct pipe_state* ps, int is_read_end, fs_node_t** out_node) { if (!ps || !out_node) return -EINVAL; struct pipe_node* pn = (struct pipe_node*)kmalloc(sizeof(*pn)); @@ -409,18 +421,16 @@ static int pipe_node_create(struct pipe_state* ps, int is_read_end, fs_node_t** pn->is_read_end = is_read_end ? 1U : 0U; pn->node.flags = FS_FILE; pn->node.length = 0; - pn->node.open = NULL; - pn->node.finddir = NULL; pn->node.close = pipe_close; pn->node.poll = pipe_poll; if (pn->is_read_end) { strcpy(pn->node.name, "pipe:r"); + pn->node.f_ops = &pipe_read_fops; pn->node.read = pipe_read; - pn->node.write = NULL; ps->readers++; } else { strcpy(pn->node.name, "pipe:w"); - pn->node.read = NULL; + pn->node.f_ops = &pipe_write_fops; pn->node.write = pipe_write; ps->writers++; } @@ -2625,6 +2635,12 @@ static void sock_node_close(fs_node_t* node) { kfree(node); } +static const struct file_operations sock_fops = { + .read = sock_node_read, + .write = sock_node_write, + .close = sock_node_close, +}; + static fs_node_t* sock_node_create(int sid) { fs_node_t* n = (fs_node_t*)kmalloc(sizeof(fs_node_t)); if (!n) return NULL; @@ -2632,6 +2648,7 @@ static fs_node_t* sock_node_create(int sid) { strcpy(n->name, "socket"); n->flags = FS_SOCKET; n->inode = (uint32_t)sid; + n->f_ops = &sock_fops; n->read = sock_node_read; n->write = sock_node_write; n->close = sock_node_close; diff --git a/src/kernel/tmpfs.c b/src/kernel/tmpfs.c index a1fd840..d62c3c7 100644 --- a/src/kernel/tmpfs.c +++ b/src/kernel/tmpfs.c @@ -18,8 +18,19 @@ static uint32_t g_tmpfs_next_inode = 1; static struct fs_node* tmpfs_finddir_impl(struct fs_node* node, const char* name); static int tmpfs_readdir_impl(struct fs_node* node, uint32_t* inout_index, void* buf, uint32_t buf_len); +static uint32_t tmpfs_read_impl(fs_node_t* node, uint32_t offset, uint32_t size, uint8_t* buffer); static uint32_t tmpfs_write_impl(fs_node_t* node, uint32_t offset, uint32_t size, const uint8_t* buffer); +static const struct file_operations tmpfs_file_ops = { + .read = tmpfs_read_impl, + .write = tmpfs_write_impl, +}; + +static const struct file_operations tmpfs_dir_ops = { + .finddir = tmpfs_finddir_impl, + .readdir = tmpfs_readdir_impl, +}; + static struct tmpfs_node* tmpfs_node_alloc(const char* name, uint32_t flags) { struct tmpfs_node* n = (struct tmpfs_node*)kmalloc(sizeof(*n)); if (!n) return NULL; @@ -64,12 +75,9 @@ static struct tmpfs_node* tmpfs_child_ensure_dir(struct tmpfs_node* dir, const c struct tmpfs_node* nd = tmpfs_node_alloc(name, FS_DIRECTORY); if (!nd) return NULL; - nd->vfs.read = 0; - nd->vfs.write = 0; - nd->vfs.open = 0; - nd->vfs.close = 0; - nd->vfs.finddir = &tmpfs_finddir_impl; - nd->vfs.readdir = &tmpfs_readdir_impl; + nd->vfs.f_ops = &tmpfs_dir_ops; + nd->vfs.finddir = tmpfs_finddir_impl; + nd->vfs.readdir = tmpfs_readdir_impl; tmpfs_child_add(dir, nd); return nd; } @@ -197,12 +205,9 @@ fs_node_t* tmpfs_create_root(void) { struct tmpfs_node* root = tmpfs_node_alloc("", FS_DIRECTORY); if (!root) return NULL; - root->vfs.read = 0; - root->vfs.write = 0; - root->vfs.open = 0; - root->vfs.close = 0; - root->vfs.finddir = &tmpfs_finddir_impl; - root->vfs.readdir = &tmpfs_readdir_impl; + root->vfs.f_ops = &tmpfs_dir_ops; + root->vfs.finddir = tmpfs_finddir_impl; + root->vfs.readdir = tmpfs_readdir_impl; return &root->vfs; } @@ -217,11 +222,9 @@ int tmpfs_add_file(fs_node_t* root_dir, const char* name, const uint8_t* data, u struct tmpfs_node* f = tmpfs_node_alloc(name, FS_FILE); if (!f) return -ENOMEM; - f->vfs.read = &tmpfs_read_impl; - f->vfs.write = &tmpfs_write_impl; - f->vfs.open = 0; - f->vfs.close = 0; - f->vfs.finddir = 0; + f->vfs.f_ops = &tmpfs_file_ops; + f->vfs.read = tmpfs_read_impl; + f->vfs.write = tmpfs_write_impl; if (len) { f->data = (uint8_t*)kmalloc(len); @@ -293,11 +296,9 @@ fs_node_t* tmpfs_create_file(fs_node_t* root_dir, const char* path, const uint8_ struct tmpfs_node* f = tmpfs_node_alloc(leaf, FS_FILE); if (!f) return NULL; - f->vfs.read = &tmpfs_read_impl; - f->vfs.write = &tmpfs_write_impl; - f->vfs.open = 0; - f->vfs.close = 0; - f->vfs.finddir = 0; + f->vfs.f_ops = &tmpfs_file_ops; + f->vfs.read = tmpfs_read_impl; + f->vfs.write = tmpfs_write_impl; if (len && data) { f->data = (uint8_t*)kmalloc(len); @@ -342,10 +343,7 @@ int tmpfs_create_symlink(fs_node_t* root_dir, const char* link_path, const char* strcpy(ln->vfs.symlink_target, target); ln->vfs.length = (uint32_t)strlen(target); - ln->vfs.read = 0; - ln->vfs.write = 0; - ln->vfs.finddir = 0; - ln->vfs.readdir = 0; + /* symlinks have no f_ops */ tmpfs_child_add(cur, ln); return 0; diff --git a/src/kernel/tty.c b/src/kernel/tty.c index 009452d..91da6f7 100644 --- a/src/kernel/tty.c +++ b/src/kernel/tty.c @@ -429,11 +429,19 @@ void tty_init(void) { keyboard_set_callback(tty_keyboard_cb); + static const struct file_operations tty_fops = { + .read = tty_devfs_read, + .write = tty_devfs_write, + .ioctl = tty_devfs_ioctl, + .poll = tty_devfs_poll, + }; + /* Register /dev/console */ memset(&g_dev_console_node, 0, sizeof(g_dev_console_node)); strcpy(g_dev_console_node.name, "console"); g_dev_console_node.flags = FS_CHARDEVICE; g_dev_console_node.inode = 10; + g_dev_console_node.f_ops = &tty_fops; g_dev_console_node.read = &tty_devfs_read; g_dev_console_node.write = &tty_devfs_write; g_dev_console_node.ioctl = &tty_devfs_ioctl; @@ -445,6 +453,7 @@ void tty_init(void) { strcpy(g_dev_tty_node.name, "tty"); g_dev_tty_node.flags = FS_CHARDEVICE; g_dev_tty_node.inode = 3; + g_dev_tty_node.f_ops = &tty_fops; g_dev_tty_node.read = &tty_devfs_read; g_dev_tty_node.write = &tty_devfs_write; g_dev_tty_node.ioctl = &tty_devfs_ioctl;