fs: open: pass create mode parameter

Pass the `mode` parameter to the open VFS call, specifying the
permissions of the file when O_CREAT is specified.
This commit is contained in:
Matthew Leach
2025-12-17 22:15:10 +00:00
committed by Ashwin Naren
parent 236dd3aa84
commit 8bc271c266
4 changed files with 15 additions and 15 deletions

View File

@@ -25,7 +25,7 @@ use crate::{
};
use alloc::{boxed::Box, string::String, sync::Arc};
use async_trait::async_trait;
use attr::FileAttr;
use attr::{FileAttr, FilePermissions};
bitflags::bitflags! {
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
@@ -198,7 +198,7 @@ pub trait Inode: Send + Sync {
&self,
_name: &str,
_file_type: FileType,
_permissions: u16,
_permissions: FilePermissions,
) -> Result<Arc<dyn Inode>> {
Err(KernelError::NotSupported)
}

View File

@@ -4,6 +4,7 @@ use async_trait::async_trait;
use core::sync::atomic::{AtomicU64, Ordering};
use dir::DirFile;
use libkernel::error::{FsError, KernelError, Result};
use libkernel::fs::attr::FilePermissions;
use libkernel::fs::path::Path;
use libkernel::fs::{BlockDevice, FS_ID_START, FileType, Filesystem, Inode, InodeId, OpenFlags};
use open_file::OpenFile;
@@ -216,6 +217,7 @@ impl VFS {
path: &Path,
flags: OpenFlags,
root: Arc<dyn Inode>,
mode: FilePermissions,
) -> Result<Arc<OpenFile>> {
// Attempt to resolve the full path first.
let resolve_result = self.resolve_path(path, root.clone()).await;
@@ -238,7 +240,7 @@ impl VFS {
if flags.contains(OpenFlags::O_CREAT) {
// Resolve its parent directory.
let parent_path = path.parent().ok_or(FsError::InvalidInput)?;
let _file_name = path.file_name().ok_or(FsError::InvalidInput)?;
let file_name = path.file_name().ok_or(FsError::InvalidInput)?;
let parent_inode = self.resolve_path(parent_path, root).await?;
@@ -248,9 +250,7 @@ impl VFS {
return Err(FsError::NotADirectory.into());
}
// TODO: Check for write permissions on parent_inode before creating.
// let _mode = ...; get mode from syscall arguments
todo!("File creation logic");
parent_inode.create(file_name, FileType::File, mode).await?
} else {
// O_CREAT was not specified, so NotFound is the correct error.
return Err(FsError::NotFound.into());

View File

@@ -2,25 +2,21 @@ use crate::{fs::VFS, memory::uaccess::cstr::UserCStr, process::fd_table::Fd, sch
use core::ffi::c_char;
use libkernel::{
error::Result,
fs::{OpenFlags, path::Path},
fs::{OpenFlags, attr::FilePermissions, path::Path},
memory::address::TUA,
};
use super::resolve_at_start_node;
pub async fn sys_openat(
dirfd: Fd,
path: TUA<c_char>,
flags: u32,
_mode: u16, // Permissions for file creation
) -> Result<usize> {
pub async fn sys_openat(dirfd: Fd, path: TUA<c_char>, flags: u32, mode: u16) -> Result<usize> {
let mut buf = [0; 1024];
let flags = OpenFlags::from_bits_truncate(flags);
let path = Path::new(UserCStr::from_ptr(path).copy_from_user(&mut buf).await?);
let start_node = resolve_at_start_node(dirfd, path).await?;
let mode = FilePermissions::from_bits_retain(mode);
let file = VFS.open(path, flags, start_node).await?;
let file = VFS.open(path, flags, start_node, mode).await?;
let fd = current_task().fd_table.lock_save_irq().insert(file)?;

View File

@@ -15,7 +15,10 @@ use fs::VFS;
use getargs::{Opt, Options};
use libkernel::{
CpuOps, VirtualMemory,
fs::{BlockDevice, OpenFlags, blk::ramdisk::RamdiskBlkDev, path::Path, pathbuf::PathBuf},
fs::{
BlockDevice, OpenFlags, attr::FilePermissions, blk::ramdisk::RamdiskBlkDev, path::Path,
pathbuf::PathBuf,
},
memory::{
address::{PA, VA},
region::PhysMemoryRegion,
@@ -132,6 +135,7 @@ async fn launch_init(opts: KOptions) {
Path::new("/dev/console"),
OpenFlags::O_RDWR,
VFS.root_inode(),
FilePermissions::empty(),
)
.await
.expect("Could not open console for init process");