diff options
author | Anton Kling <anton@kling.gg> | 2023-10-24 14:10:07 +0200 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2023-10-24 14:10:07 +0200 |
commit | 2292b11e82a3d6d70e7bb932c512155dc13c5025 (patch) | |
tree | da7d90e778495bc9a67ee0e09b32813c11dc6fe5 /fs | |
parent | e93a49d1eadf4a4b36369e67f112f8c45a0d567e (diff) |
VFS/LibC: Create ftruncate function and corresponding syscall and libc implementation
Previously this function was only used for shared memory region created
by shm_open because I was lazy. Now exists for all files.
Diffstat (limited to 'fs')
-rw-r--r-- | fs/ext2.c | 4 | ||||
-rw-r--r-- | fs/shm.c | 40 | ||||
-rw-r--r-- | fs/tmpfs.c | 5 | ||||
-rw-r--r-- | fs/vfs.c | 19 | ||||
-rw-r--r-- | fs/vfs.h | 5 |
5 files changed, 45 insertions, 28 deletions
@@ -505,7 +505,7 @@ vfs_inode_t *ext2_open(const char *path) { 1 /*is_open*/, NULL /*internal_object*/, file_size, ext2_open, ext2_create_file, ext2_read, ext2_write, ext2_close, ext2_create_directory, - NULL /*get_vm_object*/); + NULL /*get_vm_object*/, NULL/*truncate*/); } uint64_t end_of_last_entry_position(int dir_inode, uint64_t *entry_offset, @@ -697,7 +697,7 @@ vfs_inode_t *ext2_mount(void) { 0 /*can_write*/, 0 /*is_open*/, NULL /*internal_object*/, 0 /*file_size*/, ext2_open, ext2_create_file, ext2_read, ext2_write, ext2_close, - ext2_create_directory, NULL /*get_vm_object*/); + ext2_create_directory, NULL /*get_vm_object*/, NULL/*truncate*/); } void parse_superblock(void) { @@ -47,6 +47,19 @@ vfs_vm_object_t *shm_get_vm_object(uint64_t length, uint64_t offset, return p; } +int shm_ftruncate(vfs_fd_t *fd, size_t length) { + vfs_vm_object_t *p = fd->inode->internal_object; + p->size = length; + p->virtual_object = ksbrk(length); + int n = (uintptr_t)align_page((void *)(uint32_t)length) / 0x1000; + p->object = kmalloc(sizeof(void *) * n); + for (int i = 0; i < n; i++) + p->object[i] = + (void *)(get_page(p->virtual_object + (i * 0x1000), NULL, 0, 0)->frame * + 0x1000); + return 0; +} + int shm_open(const char *name, int oflag, mode_t mode) { // Try to find or create a new shared memory object. vfs_vm_object_t *internal_object = @@ -60,11 +73,11 @@ int shm_open(const char *name, int oflag, mode_t mode) { hashmap_add_entry(shared_memory_objects, name, internal_object, NULL, 0); } - vfs_inode_t *inode = - vfs_create_inode(0 /*inode_num*/, 0 /*type*/, 1 /*has_data*/, - 1 /*can_write*/, 1 /*is_open*/, internal_object, - 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/, - shm_read, shm_write, NULL /*close*/, NULL/*create_directory*/, shm_get_vm_object); + vfs_inode_t *inode = vfs_create_inode( + 0 /*inode_num*/, 0 /*type*/, 1 /*has_data*/, 1 /*can_write*/, + 1 /*is_open*/, internal_object, 0 /*file_size*/, NULL /*open*/, + NULL /*create_file*/, shm_read, shm_write, NULL /*close*/, + NULL /*create_directory*/, shm_get_vm_object, shm_ftruncate); vfs_fd_t *fd_ptr; int fd = vfs_create_fd(oflag, mode, inode, &fd_ptr); @@ -79,20 +92,3 @@ int shm_unlink(const char *name) { (void)name; return 0; } - -int ftruncate(int fildes, uint64_t length) { - kprintf("ftruncate: %d\n", length); - vfs_fd_t *fd = get_current_task()->file_descriptors[fildes]; - if (!fd) - return -EBADF; - vfs_vm_object_t *p = fd->inode->internal_object; - p->size = length; - p->virtual_object = ksbrk(length); - int n = (uintptr_t)align_page((void *)(uint32_t)length) / 0x1000; - p->object = kmalloc(sizeof(void *) * n); - for (int i = 0; i < n; i++) - p->object[i] = - (void *)(get_page(p->virtual_object + (i * 0x1000), NULL, 0, 0)->frame * - 0x1000); - return 0; -} @@ -48,7 +48,7 @@ void dual_pipe(int fd[2]) { 0 /*inode_num*/, 0 /*type*/, has_data, can_write, is_open, internal_object, 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/, tmp_read, tmp_write, tmp_close, NULL /*create_directory*/, - NULL /*get_vm_object*/); + NULL /*get_vm_object*/, NULL /*truncate*/); assert(inode); vfs_fd_t *fd_ptr; @@ -77,7 +77,8 @@ void pipe(int fd[2]) { vfs_inode_t *inode = vfs_create_inode( 0 /*inode_num*/, 0 /*type*/, has_data, can_write, is_open, internal_object, 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/, - tmp_read, tmp_write, tmp_close, NULL/*create_directory*/, NULL /*get_vm_object*/); + tmp_read, tmp_write, tmp_close, NULL /*create_directory*/, + NULL /*get_vm_object*/, NULL/*truncate*/); assert(inode); vfs_fd_t *fd_ptr; @@ -32,7 +32,8 @@ vfs_inode_t *vfs_create_inode( void (*close)(vfs_fd_t *fd), int (*create_directory)(const char *path, int mode), vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset, - vfs_fd_t *fd)) { + vfs_fd_t *fd), + int (*truncate)(vfs_fd_t *fd, size_t length)) { vfs_inode_t *r = kmalloc(sizeof(inode_t)); r->inode_num = inode_num; r->type = type; @@ -48,6 +49,7 @@ vfs_inode_t *vfs_create_inode( r->close = close; r->create_directory = create_directory; r->get_vm_object = get_vm_object; + r->truncate = truncate; return r; } @@ -291,6 +293,21 @@ int vfs_dup2(int org_fd, int new_fd) { return 1; } +int vfs_ftruncate(int fd, size_t length) { + vfs_fd_t *fd_ptr = get_vfs_fd(fd); + if (!fd_ptr) + return -EBADF; + if (!(fd_ptr->flags & O_READ)) + return -EINVAL; + vfs_inode_t *inode = fd_ptr->inode; + if (!inode) + return -EINVAL; + if (!inode->truncate) + return -EINVAL; + + return inode->truncate(fd_ptr, length); +} + void vfs_mount(char *path, vfs_inode_t *local_root) { int len = strlen(path); mounts[num_mounts].path = kmalloc_eternal(len + 1); @@ -68,6 +68,7 @@ struct vfs_inode { int (*create_directory)(const char *path, int mode); vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset, vfs_fd_t *fd); + int (*truncate)(vfs_fd_t *fd, size_t length); }; int vfs_close(int fd); @@ -83,6 +84,7 @@ int vfs_dup2(int org_fd, int new_fd); vfs_inode_t *vfs_internal_open(const char *file); int vfs_mkdir(const char *path, int mode); int vfs_create_fd(int flags, int mode, vfs_inode_t *inode, vfs_fd_t **fd); +int vfs_ftruncate(int fd, size_t length); vfs_inode_t *vfs_create_inode( int inode_num, int type, uint8_t has_data, uint8_t can_write, uint8_t is_open, void *internal_object, uint64_t file_size, @@ -93,5 +95,6 @@ vfs_inode_t *vfs_create_inode( void (*close)(vfs_fd_t *fd), int (*create_directory)(const char *path, int mode), vfs_vm_object_t *(*get_vm_object)(uint64_t length, uint64_t offset, - vfs_fd_t *fd)); + vfs_fd_t *fd), + int (*truncate)(vfs_fd_t *fd, size_t length)); #endif |