summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
authorAnton Kling <anton@kling.gg>2023-11-15 02:43:03 +0100
committerAnton Kling <anton@kling.gg>2023-11-15 02:55:54 +0100
commit6747f9407a061684c2fba837541c254f48bfcff0 (patch)
treef4d323bb6569ce755ae6425488c211387849a2f7 /kernel
parent6fc8ef497409f83201aa92094d725407861881e7 (diff)
VFS: Add stat
Diffstat (limited to 'kernel')
-rw-r--r--kernel/fs/ext2.c4
-rw-r--r--kernel/fs/shm.c3
-rw-r--r--kernel/fs/shm.h3
-rw-r--r--kernel/fs/tmpfs.c4
-rw-r--r--kernel/fs/vfs.c20
-rw-r--r--kernel/fs/vfs.h22
-rw-r--r--kernel/includes/signal.h2
-rw-r--r--kernel/includes/sys/types.h13
-rw-r--r--kernel/libc/include/time.h3
-rw-r--r--kernel/scalls/shm.h2
-rw-r--r--kernel/scalls/stat.c9
-rw-r--r--kernel/scalls/stat.h24
-rw-r--r--kernel/socket.c5
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);