X-Git-Url: https://scm.lunaixsky.com/lunaix-os.git/blobdiff_plain/b3b42765712afed5a35c9be5c832f4a06bd85e7a..c043fa535514a76091be87a45ad472a505f9dd33:/lunaix-os/kernel/fs/ramfs/ramfs.c diff --git a/lunaix-os/kernel/fs/ramfs/ramfs.c b/lunaix-os/kernel/fs/ramfs/ramfs.c index 11ec846..0944088 100644 --- a/lunaix-os/kernel/fs/ramfs/ramfs.c +++ b/lunaix-os/kernel/fs/ramfs/ramfs.c @@ -8,9 +8,11 @@ * @copyright Copyright (c) 2022 * */ -#include +#include +#include #include #include +#include /* A RAM FS will play a role of being a root. @@ -22,7 +24,7 @@ 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 @@ -39,21 +41,66 @@ '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) { - dctx->read_complete_callback( - dctx, pos->name.value, pos->name.len, 0); + if (i++ >= file->f_pos) { + dctx->read_complete_callback(dctx, + pos->name.value, + pos->name.len, + vfs_get_dtype(pos->inode->itype)); return 1; } } @@ -63,33 +110,21 @@ ramfs_readdir(struct v_file* file, struct dir_context* dctx) 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 @@ -97,13 +132,13 @@ ramfs_mount(struct v_superblock* vsb, struct v_dnode* mount_point) { 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 @@ -112,15 +147,73 @@ ramfs_unmount(struct v_superblock* vsb) 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", 5); - 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, @@ -128,10 +221,16 @@ const struct v_inode_ops ramfs_inode_ops = { .mkdir = ramfs_mkdir, 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_page, .write = default_file_write, + .write_page = + default_file_write_page, .seek = default_file_seek }; \ No newline at end of file