Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions kernel/arch/riscv64/syscall_table.json
Original file line number Diff line number Diff line change
Expand Up @@ -3374,5 +3374,30 @@
],
"return_type": "int",
"abi": "c"
},
{
"name": "fadvise64",
"nr": 221,
"nr_args": 4,
"args": [
[
"int",
"fd"
],
[
"off_t",
"offset"
],
[
"size_t",
"len"
],
[
"int",
"advice"
]
],
"return_type": "int",
"abi": "c"
}
]
25 changes: 25 additions & 0 deletions kernel/arch/x86_64/syscall_table.json
Original file line number Diff line number Diff line change
Expand Up @@ -3440,5 +3440,30 @@
],
"return_type": "int",
"abi": "c"
},
{
"name": "fadvise64",
"nr": 221,
"nr_args": 4,
"args": [
[
"int",
"fd"
],
[
"off_t",
"offset"
],
[
"size_t",
"len"
],
[
"int",
"advice"
]
],
"return_type": "int",
"abi": "c"
}
]
4 changes: 3 additions & 1 deletion kernel/include/onyx/libfs.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,12 +85,14 @@ static inline int libfs_no_unlink(const char *name, int flags, struct dentry *di
return -EROFS;
}

struct writepages_info;

off_t libfs_put_dots(struct dirent *buf, off_t off, struct dentry *dent);
void put_dir(const char *name, off_t off, ino_t ino, unsigned int dtype, struct dirent *buf);

int default_stat(struct stat *buf, const struct path *path);
off_t generic_file_llseek(struct file *filp, off_t offset, int whence);

int noop_fsyncdata(struct inode *ino, struct writepages_info *wpinfo);
__END_CDECLS

#endif
4 changes: 4 additions & 0 deletions kernel/include/onyx/mount.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
#ifndef _ONYX_MOUNT_H
#define _ONYX_MOUNT_H

#include <sys/mount.h>

#include <onyx/list.h>
#include <onyx/rcupdate.h>
#include <onyx/seqlock_types.h>
Expand All @@ -16,6 +18,8 @@ struct dentry;
struct superblock;

#define MNT_READONLY (1U << 0)
#define MNT_NOSUID MS_NOSUID
#define MNT_NODEV MS_NODEV
#define MNT_STRICTATIME MS_STRICTATIME
#define MNT_NOATIME MS_NOATIME
#define MNT_NODIRATIME MS_NODIRATIME
Expand Down
4 changes: 3 additions & 1 deletion kernel/include/onyx/readahead.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2024 Pedro Falcato
* Copyright (c) 2024 - 2026 Pedro Falcato
* This file is part of Onyx, and is released under the terms of the GPLv2 License
* check LICENSE at the root directory for more information
*
Expand All @@ -9,6 +9,7 @@
#define _ONYX_READAHEAD_H

#include <onyx/compiler.h>
#include <onyx/file.h>

__BEGIN_CDECLS

Expand All @@ -17,6 +18,7 @@ int filemap_do_readahead_async(struct inode *inode, struct readahead_state *ra_s

int filemap_do_readahead_sync(struct inode *inode, struct readahead_state *ra_state,
unsigned long pgoff);
void do_force_readahead(struct inode *inode, off_t offset, size_t len);

__END_CDECLS
#endif
2 changes: 1 addition & 1 deletion kernel/kernel/fs/Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
fs-y:= anon_inode.o dentry.o dev.o file.o null.o partition.o pipe.o poll.o pseudo.o \
superblock.o sysfs.o tmpfs.o vfs.o zero.o buffer.o inode.o namei.o filemap.o writeback.o readahead.o \
flock.o mount.o d_path.o libfs.o seq_file.o coredump.o eventfd.o xattr.o
flock.o mount.o d_path.o libfs.o seq_file.o coredump.o eventfd.o xattr.o fadvise.o

include kernel/fs/ext2/Makefile
include kernel/fs/proc/Makefile
Expand Down
1 change: 1 addition & 0 deletions kernel/kernel/fs/ext2/ext2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,7 @@ struct superblock *ext2_mount_partition(struct vfs_mount_info *info)
error:
if (b)
block_buf_put(b);
shrinker_unregister(&sb->s_shrinker);
delete sb;

return (struct superblock *) ERR_PTR(err);
Expand Down
45 changes: 45 additions & 0 deletions kernel/kernel/fs/fadvise.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2026 Pedro Falcato
* This file is part of Onyx, and is released under the terms of the GPLv2 License
* check LICENSE at the root directory for more information
*
* SPDX-License-Identifier: GPL-2.0-only
*/
#include <stdio.h>

#include <onyx/file.h>
#include <onyx/readahead.h>
#include <onyx/types.h>

int sys_fadvise64(int fd, off_t offset, size_t len, int advice)
{
struct file *file;
int err;

file = get_file_description(fd);
if (!file)
return -EBADF;

err = -ESPIPE;
if (S_ISFIFO(file->f_ino->i_mode))
goto out;

err = -EINVAL;
if (!file->f_mapping)
goto out;

err = 0;
switch (advice)
{
case POSIX_FADV_WILLNEED:
do_force_readahead(file->f_mapping->ino, offset, len);
break;
default:
err = -EINVAL;
break;
}

out:
fd_put(file);
return err;
}
2 changes: 2 additions & 0 deletions kernel/kernel/fs/inode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ static int dev_do_open(struct file *filp)
struct inode *ino = filp->f_ino;
gendev *dev;

if (filp->f_path.mount->mnt_flags & MNT_NODEV)
return -EACCES;
dev = S_ISBLK(ino->i_mode) ? (gendev *) dev_find_block(ino->i_rdev)
: (gendev *) dev_find_chr(ino->i_rdev);
if (!dev)
Expand Down
5 changes: 5 additions & 0 deletions kernel/kernel/fs/libfs.c
Original file line number Diff line number Diff line change
Expand Up @@ -47,3 +47,8 @@ void put_dir(const char *name, off_t off, ino_t ino, unsigned int dtype, struct
buf->d_type = dtype;
buf->d_reclen = sizeof(struct dirent) - (256 - (len + 1));
}

int noop_fsyncdata(struct inode *ino, struct writepages_info *wpinfo)
{
return 0;
}
41 changes: 29 additions & 12 deletions kernel/kernel/fs/mount.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* Copyright (c) 2024 - 2025 Pedro Falcato
* Copyright (c) 2024 - 2026 Pedro Falcato
* This file is part of Onyx, and is released under the terms of the GPLv2 License
* check LICENSE at the root directory for more information
*
Expand Down Expand Up @@ -441,11 +441,13 @@ static struct mount *do_remount(const char *target, unsigned int sb_flags, unsig
return err ? ERR_PTR(err) : mnt;
}

#define VALID_MOUNT_FLAGS \
(MS_RDONLY | MS_SILENT | MS_RELATIME | MS_REMOUNT | MS_BIND | MS_STRICTATIME | MS_NOATIME)
#define VALID_MOUNT_FLAGS \
(MS_RDONLY | MS_NODEV | MS_NOSUID | MS_SILENT | MS_RELATIME | MS_REMOUNT | MS_BIND | \
MS_STRICTATIME | MS_NOATIME)

/* These flags have the same bits internally as in the argument */
#define SAME_FLAGS_MASK (MNT_STRICTATIME | MNT_NOATIME | MNT_NODIRATIME | MNT_READONLY)
#define SAME_FLAGS_MASK \
(MNT_STRICTATIME | MNT_NOATIME | MNT_NODIRATIME | MNT_READONLY | MNT_NODEV | MNT_NOSUID)

static unsigned long translate_mount_flags(unsigned long flags)
{
Expand All @@ -457,26 +459,33 @@ static unsigned long translate_mount_flags(unsigned long flags)
int do_mount(const char *source, const char *target, const char *fstype, unsigned long flags,
const void *data)
{
struct fs_mount *fs;
struct fs_mount *fs = NULL;
struct mount *mnt;
unsigned long mnt_flags;
unsigned int sb_flags;

/* Find the fstype's handler */
fs = fs_mount_get(fstype);
if (!fs)
return -ENODEV;
if (fstype)
fs = fs_mount_get(fstype);

if (flags & ~VALID_MOUNT_FLAGS)
{
pr_warn_once("mount: unknown flags %lx mounting %s (%s)\n", flags & ~VALID_MOUNT_FLAGS,
source, fstype);
return -EINVAL;
}

mnt_flags = translate_mount_flags(flags);
sb_flags = flags & (SB_RDONLY | SB_SILENT);

if ((flags & (MS_REMOUNT | MS_BIND)) == MS_REMOUNT)
mnt = do_remount(target, sb_flags, mnt_flags, data);
else
{
if (!fs)
return -ENODEV;
mnt = do_mount_internal(source, target, fs, mnt_flags, sb_flags, data);
}
if (IS_ERR(mnt))
return PTR_ERR(mnt);
return 0;
Expand Down Expand Up @@ -507,11 +516,14 @@ int sys_mount(const char *usource, const char *utarget, const char *ufilesystemt
goto out;
}

filesystemtype = strcpy_from_user(ufilesystemtype);
if (!filesystemtype)
if (ufilesystemtype != NULL)
{
ret = -errno;
goto out;
filesystemtype = strcpy_from_user(ufilesystemtype);
if (!filesystemtype)
{
ret = -errno;
goto out;
}
}

ret = do_mount(source, target, filesystemtype, mountflags, data);
Expand Down Expand Up @@ -647,6 +659,8 @@ static void mounts_print_flags(struct seq_file *m, struct mount *mnt)
{
unsigned int flags = READ_ONCE(mnt->mnt_flags);
unsigned int i;

// clang-format off
static const struct
{
unsigned int flag;
Expand All @@ -655,7 +669,10 @@ static void mounts_print_flags(struct seq_file *m, struct mount *mnt)
{MNT_NOATIME, "noatime"},
{MNT_STRICTATIME, "strictatime"},
{MNT_NODIRATIME, "nodiratime"},
{MNT_NODEV, "nodev"},
{MNT_NOSUID, "nosuid"},
};
// clang-format on

seq_puts(m, mnt_rdonly(mnt) ? "ro" : "rw");

Expand Down
11 changes: 10 additions & 1 deletion kernel/kernel/fs/pipe.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ struct pipe : public refcountable
struct list_head pipe_buffers;
size_t curr_len{0};
mutex pipe_lock{1};
unsigned long wr_seq;

wait_queue write_queue;
wait_queue read_queue;
Expand Down Expand Up @@ -180,6 +181,7 @@ pipe::pipe() : refcountable(1)
init_wait_queue_head(&read_queue);
INIT_LIST_HEAD(&pipe_buffers);
mutex_init(&pipe_lock);
wr_seq = 0;
}

pipe::~pipe()
Expand Down Expand Up @@ -367,6 +369,7 @@ void pipe::close_write_end()
{
wake_all(&read_queue);
}
wr_seq++;
}

void pipe::close_read_end()
Expand Down Expand Up @@ -394,7 +397,7 @@ short pipe::poll(struct file *filp, void *poll_file, short events)
revents |= (events & (POLLIN | POLLRDNORM));
}

if (writer_count == 0)
if (writer_count == 0 && (unsigned long) filp->private_data != wr_seq)
revents |= POLLHUP;
}

Expand Down Expand Up @@ -927,6 +930,7 @@ int pipe::open_named(struct file *filp)
else if ((filp->f_flags & O_RDWRMASK) == O_WRONLY)
{
writer_count++;
wr_seq++;
wake_all(&read_queue);
COMPILER_BARRIER();
// Use a lambda to go around the multiple wait_for_event problem
Expand All @@ -941,6 +945,7 @@ int pipe::open_named(struct file *filp)
// POSIX leaves this undefined, we peer with ourselves.
writer_count++;
reader_count++;
wr_seq++;
st = 0;
}
else
Expand All @@ -952,11 +957,15 @@ int pipe::open_named(struct file *filp)
{
// Remove ourselves from the count if we got a signal
if (filp->f_flags & O_WRONLY)
{
writer_count--;
wr_seq++;
}
else
reader_count--;
}

filp->private_data = (void *) wr_seq;
return st;
}

Expand Down
Loading
Loading