return 0;
}
+static const struct file_operations initrd_file_ops = {
+ .read = initrd_read_impl,
+};
+
+static const struct file_operations initrd_dir_ops = {
+ .finddir = initrd_finddir,
+};
+
static void initrd_finalize_nodes(void) {
for (int i = 0; i < entry_count; i++) {
fs_node_t* n = &nodes[i];
n->length = e->length;
n->flags = e->flags;
- n->read = (e->flags & FS_FILE) ? &initrd_read_impl : 0;
- n->write = 0;
- n->open = 0;
- n->close = 0;
- n->finddir = (e->flags & FS_DIRECTORY) ? &initrd_finddir : 0;
+ if (e->flags & FS_FILE) {
+ n->f_ops = &initrd_file_ops;
+ n->read = &initrd_read_impl;
+ } else if (e->flags & FS_DIRECTORY) {
+ n->f_ops = &initrd_dir_ops;
+ n->finddir = &initrd_finddir;
+ }
}
}
return -ENOENT;
} else if ((flags & 0x200U) != 0U && node->flags == FS_FILE) {
/* O_TRUNC on existing file */
- if (node->truncate) {
- node->truncate(node, 0);
+ if ((node->f_ops && node->f_ops->truncate) || node->truncate) {
+ if (node->f_ops && node->f_ops->truncate)
+ node->f_ops->truncate(node, 0);
+ else
+ node->truncate(node, 0);
node->length = 0;
}
}
return (int)total;
}
- if (!f->node->read) return -ESPIPE;
+ if (!(f->node->f_ops && f->node->f_ops->read) && !f->node->read) return -ESPIPE;
uint8_t kbuf[256];
uint32_t total = 0;
}
fs_node_t* dir = vfs_lookup(parent);
- if (!dir || !dir->finddir) return -ENOENT;
+ if (!dir) return -ENOENT;
+ fs_node_t* (*fn_finddir)(fs_node_t*, const char*) = NULL;
+ if (dir->f_ops && dir->f_ops->finddir) fn_finddir = dir->f_ops->finddir;
+ else if (dir->finddir) fn_finddir = dir->finddir;
+ if (!fn_finddir) return -ENOENT;
- fs_node_t* node = dir->finddir(dir, leaf);
+ fs_node_t* node = fn_finddir(dir, leaf);
if (!node) return -ENOENT;
if (node->flags != FS_SYMLINK) return -EINVAL;
uint32_t offset = sc_arg3(regs);
struct file* f = fd_get(fd);
if (!f || !f->node) { sc_ret(regs) = (uint32_t)-EBADF; return; }
- if (!f->node->read) { sc_ret(regs) = (uint32_t)-ESPIPE; return; }
+ if (!(f->node->f_ops && f->node->f_ops->read) && !f->node->read) { sc_ret(regs) = (uint32_t)-ESPIPE; return; }
if (count > 1024 * 1024) { sc_ret(regs) = (uint32_t)-EINVAL; return; }
uint8_t kbuf[256];
uint32_t total = 0;
uint32_t offset = sc_arg3(regs);
struct file* f = fd_get(fd);
if (!f || !f->node) { sc_ret(regs) = (uint32_t)-EBADF; return; }
- if (!f->node->write) { sc_ret(regs) = (uint32_t)-ESPIPE; return; }
+ if (!(f->node->f_ops && f->node->f_ops->write) && !f->node->write) { sc_ret(regs) = (uint32_t)-ESPIPE; return; }
if (count > 1024 * 1024) { sc_ret(regs) = (uint32_t)-EINVAL; return; }
uint8_t kbuf[256];
uint32_t total = 0;