diff options
author | Anton Kling <anton@kling.gg> | 2023-11-15 02:43:03 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2023-11-15 02:55:54 +0100 |
commit | 6747f9407a061684c2fba837541c254f48bfcff0 (patch) | |
tree | f4d323bb6569ce755ae6425488c211387849a2f7 /kernel | |
parent | 6fc8ef497409f83201aa92094d725407861881e7 (diff) |
VFS: Add stat
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/fs/ext2.c | 4 | ||||
-rw-r--r-- | kernel/fs/shm.c | 3 | ||||
-rw-r--r-- | kernel/fs/shm.h | 3 | ||||
-rw-r--r-- | kernel/fs/tmpfs.c | 4 | ||||
-rw-r--r-- | kernel/fs/vfs.c | 20 | ||||
-rw-r--r-- | kernel/fs/vfs.h | 22 | ||||
-rw-r--r-- | kernel/includes/signal.h | 2 | ||||
-rw-r--r-- | kernel/includes/sys/types.h | 13 | ||||
-rw-r--r-- | kernel/libc/include/time.h | 3 | ||||
-rw-r--r-- | kernel/scalls/shm.h | 2 | ||||
-rw-r--r-- | kernel/scalls/stat.c | 9 | ||||
-rw-r--r-- | kernel/scalls/stat.h | 24 | ||||
-rw-r--r-- | kernel/socket.c | 5 |
13 files changed, 58 insertions, 56 deletions
diff --git a/kernel/fs/ext2.c b/kernel/fs/ext2.c index 4398c8e..69de441 100644 --- a/kernel/fs/ext2.c +++ b/kernel/fs/ext2.c @@ -518,7 +518,9 @@ int ext2_stat(vfs_fd_t *fd, struct stat *buf) { u8 buffer[inode_size]; inode_t *inode = (inode_t *)buffer; ext2_get_inode_header(fd->inode->inode_num, inode); - if (DIRECTORY == inode->types_permissions) { + + buf->st_size = (u64)inode->low_32size | ((u64)inode->_upper_32size); + if (DIRECTORY & inode->types_permissions) { buf->st_mode = STAT_DIR; } else { buf->st_mode = STAT_REG; diff --git a/kernel/fs/shm.c b/kernel/fs/shm.c index 1bbe07f..a77702a 100644 --- a/kernel/fs/shm.c +++ b/kernel/fs/shm.c @@ -77,7 +77,8 @@ int shm_open(const char *name, int oflag, mode_t mode) { 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); + NULL /*create_directory*/, shm_get_vm_object, shm_ftruncate, + NULL /*stat*/); vfs_fd_t *fd_ptr; int fd = vfs_create_fd(oflag, mode, inode, &fd_ptr); diff --git a/kernel/fs/shm.h b/kernel/fs/shm.h index 977c18f..2a184dd 100644 --- a/kernel/fs/shm.h +++ b/kernel/fs/shm.h @@ -2,8 +2,7 @@ #define SHM_H #include <stddef.h> #include <typedefs.h> - -typedef int mode_t; +#include <sys/types.h> void shm_init(void); int shm_open(const char *name, int oflag, mode_t mode); diff --git a/kernel/fs/tmpfs.c b/kernel/fs/tmpfs.c index 0996507..0e82a16 100644 --- a/kernel/fs/tmpfs.c +++ b/kernel/fs/tmpfs.c @@ -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 /*truncate*/); + NULL /*get_vm_object*/, NULL /*truncate*/, NULL /*stat*/); assert(inode); vfs_fd_t *fd_ptr; @@ -78,7 +78,7 @@ void 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/*truncate*/); + NULL /*get_vm_object*/, NULL /*truncate*/, NULL/*stat*/); assert(inode); vfs_fd_t *fd_ptr; diff --git a/kernel/fs/vfs.c b/kernel/fs/vfs.c index 1353547..0911c95 100644 --- a/kernel/fs/vfs.c +++ b/kernel/fs/vfs.c @@ -23,17 +23,17 @@ vfs_fd_t *get_vfs_fd(int fd) { } vfs_inode_t *vfs_create_inode( - int inode_num, int type, u8 has_data, u8 can_write, - u8 is_open, void *internal_object, u64 file_size, + int inode_num, int type, u8 has_data, u8 can_write, u8 is_open, + void *internal_object, u64 file_size, vfs_inode_t *(*open)(const char *path), int (*create_file)(const char *path, int mode), int (*read)(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd), int (*write)(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd), void (*close)(vfs_fd_t *fd), int (*create_directory)(const char *path, int mode), - vfs_vm_object_t *(*get_vm_object)(u64 length, u64 offset, - vfs_fd_t *fd), - int (*truncate)(vfs_fd_t *fd, size_t length)) { + vfs_vm_object_t *(*get_vm_object)(u64 length, u64 offset, vfs_fd_t *fd), + int (*truncate)(vfs_fd_t *fd, size_t length), + int (*stat)(vfs_fd_t *fd, struct stat *buf)) { vfs_inode_t *r = kmalloc(sizeof(inode_t)); r->inode_num = inode_num; r->type = type; @@ -50,6 +50,7 @@ vfs_inode_t *vfs_create_inode( r->create_directory = create_directory; r->get_vm_object = get_vm_object; r->truncate = truncate; + r->stat = stat; return r; } @@ -96,7 +97,6 @@ int vfs_create_file(const char *file) { } // ext2_create_file("/etc/oscreated", 0); assert(file_mount->local_root->create_file); - kprintf("Creating a file\n"); return file_mount->local_root->create_file(file, 0); } @@ -160,6 +160,14 @@ char *vfs_resolve_path(const char *file, char *resolved_path) { return final; } +int vfs_fstat(int fd, struct stat *buf) { + vfs_fd_t *fd_ptr = get_vfs_fd(fd); + if (!fd_ptr) + return -EBADF; + assert(fd_ptr->inode->stat); + return fd_ptr->inode->stat(fd_ptr, buf); +} + int vfs_mkdir(const char *path, int mode) { vfs_mounts_t *file_mount = 0; int length = 0; diff --git a/kernel/fs/vfs.h b/kernel/fs/vfs.h index 949d175..3e3e1ff 100644 --- a/kernel/fs/vfs.h +++ b/kernel/fs/vfs.h @@ -8,6 +8,7 @@ typedef struct vfs_mounts vfs_mounts_t; #include <sched/scheduler.h> #include <socket.h> #include <stddef.h> +#include <sys/stat.h> #include <typedefs.h> // FIXME: Is there some standard value for this? @@ -66,9 +67,9 @@ struct vfs_inode { int (*write)(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd); void (*close)(vfs_fd_t *fd); int (*create_directory)(const char *path, int mode); - vfs_vm_object_t *(*get_vm_object)(u64 length, u64 offset, - vfs_fd_t *fd); + vfs_vm_object_t *(*get_vm_object)(u64 length, u64 offset, vfs_fd_t *fd); int (*truncate)(vfs_fd_t *fd, size_t length); + int (*stat)(vfs_fd_t *fd, struct stat *buf); }; int vfs_close(int fd); @@ -76,26 +77,27 @@ vfs_fd_t *get_vfs_fd(int fd); int vfs_open(const char *file, int flags, int mode); void vfs_mount(char *path, vfs_inode_t *local_root); int vfs_pwrite(int fd, void *buf, u64 count, u64 offset); -int raw_vfs_pwrite(vfs_fd_t *vfs_fd, void *buf, u64 count, - u64 offset); +int raw_vfs_pwrite(vfs_fd_t *vfs_fd, void *buf, u64 count, u64 offset); int raw_vfs_pread(vfs_fd_t *vfs_fd, void *buf, u64 count, u64 offset); -int vfs_pread(int fd, void *buf, u64 count, u64 offset); +int vfs_pread(int fd, void *buf, u32 count, u32 offset); vfs_vm_object_t *vfs_get_vm_object(int fd, u64 length, u64 offset); 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); +int vfs_chdir(const char *path); +int vfs_fstat(int fd, struct stat *buf); vfs_inode_t *vfs_create_inode( - int inode_num, int type, u8 has_data, u8 can_write, - u8 is_open, void *internal_object, u64 file_size, + int inode_num, int type, u8 has_data, u8 can_write, u8 is_open, + void *internal_object, u64 file_size, vfs_inode_t *(*open)(const char *path), int (*create_file)(const char *path, int mode), int (*read)(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd), int (*write)(u8 *buffer, u64 offset, u64 len, vfs_fd_t *fd), void (*close)(vfs_fd_t *fd), int (*create_directory)(const char *path, int mode), - vfs_vm_object_t *(*get_vm_object)(u64 length, u64 offset, - vfs_fd_t *fd), - int (*truncate)(vfs_fd_t *fd, size_t length)); + vfs_vm_object_t *(*get_vm_object)(u64 length, u64 offset, vfs_fd_t *fd), + int (*truncate)(vfs_fd_t *fd, size_t length), + int (*stat)(vfs_fd_t *fd, struct stat *buf)); #endif diff --git a/kernel/includes/signal.h b/kernel/includes/signal.h index 3de9998..7e9dd9c 100644 --- a/kernel/includes/signal.h +++ b/kernel/includes/signal.h @@ -6,8 +6,6 @@ #define SIGWINCH 2 #define SIGQUIT 3 #define SIG_IGN 4 -typedef int pid_t; -typedef int uid_t; typedef int sigset_t; union sigval { diff --git a/kernel/includes/sys/types.h b/kernel/includes/sys/types.h index 1ccbf63..f82eff7 100644 --- a/kernel/includes/sys/types.h +++ b/kernel/includes/sys/types.h @@ -1,2 +1,15 @@ +#ifndef TYPES_H +#define TYPES_H +#include <typedefs.h> typedef int time_t; typedef int pid_t; +typedef u16 dev_t; +typedef u16 uid_t; +typedef u16 ino_t; +typedef u16 mode_t; +typedef u16 nlink_t; +typedef i32 gid_t; +typedef u64 off_t; +typedef i64 blksize_t; +typedef i64 blkcnt_t; +#endif diff --git a/kernel/libc/include/time.h b/kernel/libc/include/time.h index 4e356d1..044e70f 100644 --- a/kernel/libc/include/time.h +++ b/kernel/libc/include/time.h @@ -1,6 +1,9 @@ +#ifndef TIME_H +#define TIME_H #include <types.h> struct timespec { time_t tv_sec; // Seconds. long tv_nsec; // Nanoseconds. }; +#endif diff --git a/kernel/scalls/shm.h b/kernel/scalls/shm.h index 61a30b0..a247cfd 100644 --- a/kernel/scalls/shm.h +++ b/kernel/scalls/shm.h @@ -2,7 +2,7 @@ #define SYS_SHM_H #include <stddef.h> #include <typedefs.h> -typedef int mode_t; +#include <sys/types.h> typedef struct SYS_SHM_OPEN_PARAMS { const char *name; diff --git a/kernel/scalls/stat.c b/kernel/scalls/stat.c index 0850151..9fc115b 100644 --- a/kernel/scalls/stat.c +++ b/kernel/scalls/stat.c @@ -5,9 +5,8 @@ int syscall_stat(SYS_STAT_PARAMS *args) { const char *pathname = copy_and_allocate_user_string(args->pathname); struct stat *statbuf = args->statbuf; - vfs_inode_t *i = vfs_internal_open(pathname); - if (!i) - return -ENOENT; - statbuf->st_size = i->file_size; - return 0; + int fd = vfs_open(pathname, O_READ, 0); + int rc = vfs_fstat(fd, statbuf); + vfs_close(fd); + return rc; } diff --git a/kernel/scalls/stat.h b/kernel/scalls/stat.h index 78e8c45..24c5d7c 100644 --- a/kernel/scalls/stat.h +++ b/kernel/scalls/stat.h @@ -6,28 +6,4 @@ typedef struct SYS_STAT_PARAMS { struct stat *statbuf; } __attribute__((packed)) SYS_STAT_PARAMS; -struct stat { - dev_t st_dev; // Device ID of device containing file. - ino_t st_ino; // File serial number. - mode_t st_mode; // Mode of file (see below). - nlink_t st_nlink; // Number of hard links to the file. - uid_t st_uid; // User ID of file. - gid_t st_gid; // Group ID of file. - dev_t st_rdev; // Device ID (if file is character or block special). - off_t st_size; // For regular files, the file size in bytes. - // For symbolic links, the length in bytes of the - // pathname contained in the symbolic link. - // For a shared memory object, the length in bytes. - // For a typed memory object, the length in bytes. - // For other file types, the use of this field is - // unspecified. - struct timespec st_atim; // Last data access timestamp. - struct timespec st_mtim; // Last data modification timestamp. - struct timespec st_ctim; // Last file status change timestamp. - blksize_t st_blksize; // A file system-specific preferred I/O block size - // for this object. In some file system types, this - // may vary from file to file. - blkcnt_t st_blocks; // Number of blocks allocated for this object. -}; - int syscall_stat(SYS_STAT_PARAMS *args); diff --git a/kernel/socket.c b/kernel/socket.c index 65ba771..ebc83a9 100644 --- a/kernel/socket.c +++ b/kernel/socket.c @@ -86,7 +86,8 @@ handle_incoming_tcp_connection(u8 ip[4], u16 n_port, 0 /*inode_num*/, FS_TYPE_UNIX_SOCKET, 0 /*has_data*/, 1 /*can_write*/, 1 /*is_open*/, &tcp_connections[i], 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/, tcp_socket_read, tcp_socket_write, tcp_socket_close, - NULL /*create_directory*/, NULL /*get_vm_object*/, NULL /*truncate*/); + NULL /*create_directory*/, NULL /*get_vm_object*/, NULL /*truncate*/, + NULL /*stat*/); vfs_fd_t *fd; int n = vfs_create_fd(O_RDWR | O_NONBLOCK, 0, inode, &fd); @@ -278,7 +279,7 @@ int socket(int domain, int type, int protocol) { 1 /*is_open*/, new_socket /*internal_object*/, 0 /*file_size*/, NULL /*open*/, NULL /*create_file*/, socket_read, socket_write, socket_close, NULL /*create_directory*/, NULL /*get_vm_object*/, - NULL /*truncate*/); + NULL /*truncate*/, NULL /*stat*/); vfs_fd_t *fd; int n = vfs_create_fd(O_RDWR | O_NONBLOCK, 0, inode, &fd); |