* @copyright Copyright (c) 2022
*
*/
-#include <lunaix/fs.h>
+#include <klibc/string.h>
+#include <lunaix/fs/api.h>
#include <lunaix/fs/ramfs.h>
#include <lunaix/mm/valloc.h>
+#include <lunaix/spike.h>
/*
A RAM FS will play a role of being a root.
case, our rootfs will be something like ext2.
RamFS vs. TwiFS: Indeed, they are both fs that lives in RAM so
- there is no foundmentally differences. However, TwiFS is designed
+ there is no foundmental differences. However, TwiFS is designed
to be a 'virtual FIlesystem for KERnel space' (FIKER), so other
kernel sub-modules can just create node and attach their own
implementation of read/write, without brothering to create a
'mountibility' for other fs.
*/
-volatile static inode_t ino = 0;
+static volatile inode_t ino = 0;
extern const struct v_inode_ops ramfs_inode_ops;
extern const struct v_file_ops ramfs_file_ops;
+static int
+__ramfs_mknod(struct v_dnode* dnode, struct v_inode** nod_out, u32_t flags)
+{
+ struct v_inode* inode = vfs_i_alloc(dnode->super_block);
+
+ if (!inode) {
+ return ENOMEM;
+ }
+
+ struct ram_inode* rinode = valloc(sizeof(struct ram_inode));
+
+ if (!rinode) {
+ vfs_i_free(inode);
+ return ENOMEM;
+ }
+
+ rinode->flags = flags;
+ inode->data = rinode;
+ inode->itype = VFS_IFFILE;
+
+ if ((flags & RAMF_DIR)) {
+ inode->itype |= VFS_IFDIR;
+ }
+
+ if ((flags & RAMF_SYMLINK)) {
+ inode->itype |= VFS_IFSYMLINK;
+ }
+
+ if (nod_out) {
+ *nod_out = inode;
+ }
+
+ vfs_i_addhash(inode);
+ vfs_assign_inode(dnode, inode);
+
+ return 0;
+}
+
int
ramfs_readdir(struct v_file* file, struct dir_context* dctx)
{
- int i = 0;
+ unsigned int i = 2;
struct v_dnode *pos, *n;
+
+ if (fsapi_handle_pseudo_dirent(file, dctx)) {
+ return 1;
+ }
+
llist_for_each(pos, n, &file->dnode->children, siblings)
{
- if (i++ >= dctx->index) {
+ if (i++ >= file->f_pos) {
dctx->read_complete_callback(dctx,
pos->name.value,
pos->name.len,
int
ramfs_mkdir(struct v_inode* this, struct v_dnode* dnode)
{
- struct v_inode* inode = vfs_i_alloc(dnode->super_block);
- inode->itype = VFS_IFDIR;
-
- vfs_i_addhash(inode);
- vfs_assign_inode(dnode, inode);
-
- return 0;
+ return __ramfs_mknod(dnode, NULL, RAMF_DIR);
}
int
-ramfs_create(struct v_inode* this, struct v_dnode* dnode)
+ramfs_create(struct v_inode* this, struct v_dnode* dnode, unsigned int itype)
{
- struct v_inode* inode = vfs_i_alloc(dnode->super_block);
- inode->itype = VFS_IFFILE;
-
- vfs_i_addhash(inode);
- vfs_assign_inode(dnode, inode);
-
- return 0;
+ return __ramfs_mknod(dnode, NULL, RAMF_FILE);
}
void
ramfs_inode_init(struct v_superblock* vsb, struct v_inode* inode)
{
inode->id = ino++;
- inode->ops = &ramfs_inode_ops;
- inode->default_fops = &ramfs_file_ops;
+ inode->ops = (struct v_inode_ops*)&ramfs_inode_ops;
+ inode->default_fops = (struct v_file_ops*)&ramfs_file_ops;
}
int
{
vsb->ops.init_inode = ramfs_inode_init;
- struct v_inode* inode = vfs_i_alloc(vsb);
- inode->itype = VFS_IFDIR;
+ int errno = __ramfs_mknod(mount_point, NULL, RAMF_DIR);
- vfs_i_addhash(inode);
- vfs_assign_inode(mount_point, inode);
+ if (!errno) {
+ fsapi_inode_setaccess(mount_point->inode, FSACL_DEFAULT);
+ }
- return 0;
+ return errno;
}
int
return 0;
}
-void
-ramfs_init()
+int
+ramfs_mksymlink(struct v_inode* this, const char* target)
+{
+ struct ram_inode* rinode = RAM_INODE(this->data);
+
+ assert(!(rinode->flags & RAMF_SYMLINK));
+
+ size_t len = strlen(target) + 1;
+ char* symlink = valloc(len);
+
+ if (!symlink) {
+ return ENOMEM;
+ }
+
+ memcpy(symlink, target, len);
+
+ this->itype = VFS_IFSYMLINK;
+ rinode->flags |= RAMF_SYMLINK;
+ rinode->symlink = symlink;
+ rinode->size = len;
+
+ return 0;
+}
+
+int
+ramfs_read_symlink(struct v_inode* this, const char** path_out)
{
- struct filesystem* ramfs = fsm_new_fs("ramfs", -1);
- ramfs->mount = ramfs_mount;
- ramfs->unmount = ramfs_unmount;
+ struct ram_inode* rinode = RAM_INODE(this->data);
- fsm_register(ramfs);
+ if (!(rinode->flags & RAMF_SYMLINK)) {
+ return EINVAL;
+ }
+
+ *path_out = rinode->symlink;
+
+ return rinode->size;
+}
+
+int
+ramfs_unlink(struct v_inode* this, struct v_dnode* name)
+{
+ struct ram_inode* rinode = RAM_INODE(this->data);
+
+ if ((rinode->flags & RAMF_SYMLINK)) {
+ rinode->flags &= ~RAMF_SYMLINK;
+ this->itype &= ~F_SYMLINK;
+
+ vfree(rinode->symlink);
+
+ return 0;
+ }
+
+ // TODO
+
+ return 0;
+}
+
+static void
+ramfs_init()
+{
+ struct filesystem* fs;
+ fs = fsapi_fs_declare("ramfs", FSTYPE_PSEUDO);
+
+ fsapi_fs_set_mntops(fs, ramfs_mount, ramfs_unmount);
+ fsapi_fs_finalise(fs);
}
+EXPORT_FILE_SYSTEM(ramfs, ramfs_init);
const struct v_inode_ops ramfs_inode_ops = { .mkdir = ramfs_mkdir,
.rmdir = default_inode_rmdir,
default_inode_dirlookup,
.create = ramfs_create,
.open = default_inode_open,
+ .unlink = ramfs_unlink,
+ .set_symlink = ramfs_mksymlink,
+ .read_symlink = ramfs_read_symlink,
.rename = default_inode_rename };
const struct v_file_ops ramfs_file_ops = { .readdir = ramfs_readdir,
.close = default_file_close,
.read = default_file_read,
- .read_page = default_file_read,
+ .read_page = default_file_read_page,
.write = default_file_write,
- .write_page = default_file_write,
+ .write_page =
+ default_file_write_page,
.seek = default_file_seek };
\ No newline at end of file