Remove inode-specific methods from `FileLike`

This commit is contained in:
Wang Siyuan 2025-11-05 15:51:57 +00:00 committed by Tate, Hongliang Tian
parent 4d7958c18e
commit 805e2a7c89
18 changed files with 45 additions and 272 deletions

View File

@ -16,7 +16,7 @@ use crate::{
file_handle::FileLike,
file_table::{get_file_fast, FileDesc},
pseudofs::anon_inodefs_shared_inode,
utils::{mkmod, Inode, IoctlCmd, Metadata},
utils::{Inode, IoctlCmd},
},
prelude::*,
process::{
@ -267,12 +267,6 @@ impl FileLike for EpollFile {
return_errno_with_message!(Errno::EINVAL, "epoll files do not support ioctl");
}
fn metadata(&self) -> Metadata {
// This is a dummy implementation.
// TODO: Add "anonymous inode fs" and link `EpollFile` to it.
Metadata::new_file(0, mkmod!(u+rw), aster_block::BLOCK_SIZE)
}
fn inode(&self) -> &Arc<dyn Inode> {
anon_inodefs_shared_inode()
}

View File

@ -8,12 +8,10 @@ use ostd::io::IoMem;
use super::inode_handle::InodeHandle;
use crate::{
fs::utils::{
AccessMode, FallocMode, Inode, InodeMode, IoctlCmd, Metadata, SeekFrom, StatusFlags,
},
fs::utils::{AccessMode, FallocMode, Inode, IoctlCmd, SeekFrom, StatusFlags},
net::socket::Socket,
prelude::*,
process::{signal::Pollable, Gid, Uid},
process::signal::Pollable,
};
/// The basic operations defined on a file
@ -69,36 +67,6 @@ pub trait FileLike: Pollable + Send + Sync + Any {
return_errno_with_message!(Errno::EINVAL, "resize is not supported");
}
/// Get the metadata that describes this file.
fn metadata(&self) -> Metadata;
#[expect(dead_code)]
fn mode(&self) -> Result<InodeMode> {
return_errno_with_message!(Errno::EINVAL, "mode is not supported");
}
fn set_mode(&self, mode: InodeMode) -> Result<()> {
return_errno_with_message!(Errno::EINVAL, "set_mode is not supported");
}
#[expect(dead_code)]
fn owner(&self) -> Result<Uid> {
return_errno_with_message!(Errno::EPERM, "owner is not supported");
}
fn set_owner(&self, uid: Uid) -> Result<()> {
return_errno_with_message!(Errno::EPERM, "set_owner is not supported");
}
#[expect(dead_code)]
fn group(&self) -> Result<Gid> {
return_errno_with_message!(Errno::EPERM, "group is not supported");
}
fn set_group(&self, gid: Gid) -> Result<()> {
return_errno_with_message!(Errno::EPERM, "set_group is not supported");
}
fn status_flags(&self) -> StatusFlags {
StatusFlags::empty()
}

View File

@ -12,15 +12,12 @@ use crate::{
file_handle::{FileLike, Mappable},
path::Path,
utils::{
AccessMode, DirentVisitor, FallocMode, FlockItem, Inode, InodeMode, InodeType,
IoctlCmd, Metadata, RangeLockItem, RangeLockType, SeekFrom, StatusFlags,
AccessMode, DirentVisitor, FallocMode, FlockItem, Inode, InodeType, IoctlCmd,
RangeLockItem, RangeLockType, SeekFrom, StatusFlags,
},
},
prelude::*,
process::{
signal::{PollHandle, Pollable},
Gid, Uid,
},
process::signal::{PollHandle, Pollable},
};
pub struct InodeHandle(HandleInner, Rights);
@ -130,13 +127,6 @@ impl Pollable for InodeHandle {
#[inherit_methods(from = "self.0")]
impl FileLike for InodeHandle {
fn status_flags(&self) -> StatusFlags;
fn metadata(&self) -> Metadata;
fn mode(&self) -> Result<InodeMode>;
fn set_mode(&self, mode: InodeMode) -> Result<()>;
fn owner(&self) -> Result<Uid>;
fn set_owner(&self, uid: Uid) -> Result<()>;
fn group(&self) -> Result<Gid>;
fn set_group(&self, gid: Gid) -> Result<()>;
fn read(&self, writer: &mut VmWriter) -> Result<usize> {
if !self.1.contains(Rights::READ) {

View File

@ -15,16 +15,12 @@ use crate::{
file_handle::Mappable,
path::Path,
utils::{
DirentVisitor, FallocMode, FileRange, FlockItem, FlockList, Inode, InodeMode,
InodeType, IoctlCmd, Metadata, RangeLockItem, RangeLockList, RangeLockType, SeekFrom,
StatusFlags, OFFSET_MAX,
DirentVisitor, FallocMode, FileRange, FlockItem, FlockList, Inode, InodeType, IoctlCmd,
RangeLockItem, RangeLockList, RangeLockType, SeekFrom, StatusFlags, OFFSET_MAX,
},
},
prelude::*,
process::{
signal::{PollHandle, Pollable},
Gid, Uid,
},
process::signal::{PollHandle, Pollable},
};
struct HandleInner {
@ -259,13 +255,6 @@ impl HandleInner {
#[inherit_methods(from = "self.path")]
impl HandleInner {
pub(self) fn size(&self) -> usize;
pub(self) fn metadata(&self) -> Metadata;
pub(self) fn mode(&self) -> Result<InodeMode>;
pub(self) fn set_mode(&self, mode: InodeMode) -> Result<()>;
pub(self) fn owner(&self) -> Result<Uid>;
pub(self) fn set_owner(&self, uid: Uid) -> Result<()>;
pub(self) fn group(&self) -> Result<Gid>;
pub(self) fn set_group(&self, gid: Gid) -> Result<()>;
pub(self) fn inode(&self) -> &Arc<dyn Inode>;
}

View File

@ -8,14 +8,13 @@ use crate::{
file_handle::FileLike,
pipe::common::{PipeReader, PipeWriter},
pseudofs::{pipefs_singleton, PseudoInode},
utils::{mkmod, AccessMode, Inode, InodeType, Metadata, StatusFlags},
utils::{mkmod, AccessMode, Inode, InodeType, StatusFlags},
},
prelude::*,
process::{
signal::{PollHandle, Pollable},
Gid, Uid,
},
time::clocks::RealTimeCoarseClock,
};
const DEFAULT_PIPE_BUF_SIZE: usize = 65536;
@ -107,28 +106,6 @@ impl FileLike for PipeReaderFile {
AccessMode::O_RDONLY
}
fn metadata(&self) -> Metadata {
// This is a dummy implementation.
// TODO: Add "PipeFS" and link `PipeReader` to it.
let now = RealTimeCoarseClock::get().read_time();
Metadata {
dev: 0,
ino: 0,
size: 0,
blk_size: 0,
blocks: 0,
atime: now,
mtime: now,
ctime: now,
type_: InodeType::NamedPipe,
mode: mkmod!(u+r),
nlinks: 1,
uid: Uid::new_root(),
gid: Gid::new_root(),
rdev: 0,
}
}
fn inode(&self) -> &Arc<dyn Inode> {
&self.pseudo_inode
}
@ -199,28 +176,6 @@ impl FileLike for PipeWriterFile {
AccessMode::O_WRONLY
}
fn metadata(&self) -> Metadata {
// This is a dummy implementation.
// TODO: Add "PipeFS" and link `PipeWriter` to it.
let now = RealTimeCoarseClock::get().read_time();
Metadata {
dev: 0,
ino: 0,
size: 0,
blk_size: 0,
blocks: 0,
atime: now,
mtime: now,
ctime: now,
type_: InodeType::NamedPipe,
mode: mkmod!(u+w),
nlinks: 1,
uid: Uid::new_root(),
gid: Gid::new_root(),
rdev: 0,
}
}
fn inode(&self) -> &Arc<dyn Inode> {
&self.pseudo_inode
}

View File

@ -308,13 +308,6 @@ impl Pollable for MemfdFile {
impl FileLike for MemfdFile {
fn read_at(&self, offset: usize, writer: &mut VmWriter) -> Result<usize>;
fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result<i32>;
fn metadata(&self) -> Metadata;
fn mode(&self) -> Result<InodeMode>;
fn set_mode(&self, mode: InodeMode) -> Result<()>;
fn owner(&self) -> Result<Uid>;
fn set_owner(&self, uid: Uid) -> Result<()>;
fn group(&self) -> Result<Gid>;
fn set_group(&self, gid: Gid) -> Result<()>;
fn read(&self, writer: &mut VmWriter) -> Result<usize> {
let mut offset = self.offset.lock();

View File

@ -213,26 +213,6 @@ impl Metadata {
rdev: device.id().as_encoded_u64(),
}
}
pub fn new_socket(ino: u64, mode: InodeMode, blk_size: usize) -> Metadata {
let now = RealTimeCoarseClock::get().read_time();
Self {
dev: 0,
ino,
size: 0,
blk_size,
blocks: 0,
atime: now,
mtime: now,
ctime: now,
type_: InodeType::Socket,
mode,
nlinks: 1,
uid: Uid::new_root(),
gid: Gid::new_root(),
rdev: 0,
}
}
}
pub enum MknodType {

View File

@ -7,7 +7,7 @@ use crate::{
fs::{
file_handle::FileLike,
pseudofs::{sockfs_singleton, PseudoInode},
utils::{mkmod, Inode, InodeType, Metadata, StatusFlags},
utils::{mkmod, Inode, InodeType, StatusFlags},
},
prelude::*,
process::{Gid, Uid},
@ -172,12 +172,6 @@ impl<T: Socket + 'static> FileLike for T {
Some(self)
}
fn metadata(&self) -> Metadata {
// This is a dummy implementation.
// TODO: Add "SockFS" and link `Socket` to it.
Metadata::new_socket(0, mkmod!(a+rwx), aster_block::BLOCK_SIZE)
}
fn inode(&self) -> &Arc<dyn Inode> {
self.pseudo_inode()
}

View File

@ -7,14 +7,13 @@ use crate::{
fs::{
file_handle::FileLike,
pseudofs::anon_inodefs_shared_inode,
utils::{mkmod, Inode, InodeType, Metadata, StatusFlags},
utils::{Inode, StatusFlags},
},
prelude::*,
process::{
signal::{PollHandle, Pollable},
Gid, Process, Uid,
Process,
},
time::clocks::RealTimeClock,
};
pub struct PidFile {
@ -72,27 +71,6 @@ impl FileLike for PidFile {
return_errno_with_message!(Errno::EINVAL, "PID file cannot be written");
}
fn metadata(&self) -> Metadata {
let now = RealTimeClock::get().read_time();
Metadata {
dev: 0,
ino: 0,
size: 0,
blk_size: 4096,
blocks: 0,
atime: now,
mtime: now,
ctime: now,
type_: InodeType::Unknown,
mode: mkmod!(u+rw),
nlinks: 1,
// FIXME: Should we use the process's UID and GID here?
uid: Uid::new_root(),
gid: Gid::new_root(),
rdev: 0,
}
}
fn set_status_flags(&self, new_flags: StatusFlags) -> Result<()> {
if new_flags.contains(StatusFlags::O_NONBLOCK) {
self.is_nonblocking.store(true, Ordering::Relaxed);

View File

@ -81,7 +81,7 @@ pub fn do_faccessat(
dirfd, path_name, mode, flags
);
let path = {
let path_or_inode = {
let path_name = path_name.to_string_lossy();
let fs_path = if flags.contains(FaccessatFlags::AT_EMPTY_PATH) && path_name.is_empty() {
FsPath::from_fd(dirfd)?
@ -92,9 +92,9 @@ pub fn do_faccessat(
let fs_ref = ctx.thread_local.borrow_fs();
let fs = fs_ref.resolver().read();
if flags.contains(FaccessatFlags::AT_SYMLINK_NOFOLLOW) {
fs.lookup_no_follow(&fs_path)?
fs.lookup_inode_no_follow(&fs_path)?
} else {
fs.lookup(&fs_path)?
fs.lookup_inode(&fs_path)?
}
};
@ -103,7 +103,7 @@ pub fn do_faccessat(
return Ok(SyscallReturn::Return(0));
}
let inode = path.inode();
let inode = path_or_inode.inode();
// FIXME: The current implementation is dummy
if mode.contains(AccessMode::R_OK) {

View File

@ -15,7 +15,7 @@ pub fn sys_fchmod(fd: FileDesc, mode: u16, ctx: &Context) -> Result<SyscallRetur
let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd);
file.set_mode(InodeMode::from_bits_truncate(mode))?;
file.inode().set_mode(InodeMode::from_bits_truncate(mode))?;
Ok(SyscallReturn::Return(0))
}
@ -37,16 +37,18 @@ pub fn sys_fchmodat(
dirfd, path_name, mode,
);
let path = {
let path_or_inode = {
let path_name = path_name.to_string_lossy();
let fs_path = FsPath::from_fd_and_path(dirfd, &path_name)?;
ctx.thread_local
.borrow_fs()
.resolver()
.read()
.lookup(&fs_path)?
.lookup_inode(&fs_path)?
};
path.set_mode(InodeMode::from_bits_truncate(mode))?;
path_or_inode
.inode()
.set_mode(InodeMode::from_bits_truncate(mode))?;
Ok(SyscallReturn::Return(0))
}

View File

@ -23,10 +23,10 @@ pub fn sys_fchown(fd: FileDesc, uid: i32, gid: i32, ctx: &Context) -> Result<Sys
let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd);
if let Some(uid) = uid {
file.set_owner(uid)?;
file.inode().set_owner(uid)?;
}
if let Some(gid) = gid {
file.set_group(gid)?;
file.inode().set_group(gid)?;
}
Ok(SyscallReturn::Return(0))
}
@ -72,24 +72,26 @@ pub fn sys_fchownat(
return Ok(SyscallReturn::Return(0));
}
let path = {
let path_or_inode = {
let path_name = path_name.to_string_lossy();
let fs_path = FsPath::from_fd_and_path(dirfd, &path_name)?;
let fs_ref = ctx.thread_local.borrow_fs();
let fs = fs_ref.resolver().read();
if flags.contains(ChownFlags::AT_SYMLINK_NOFOLLOW) {
fs.lookup_no_follow(&fs_path)?
fs.lookup_inode_no_follow(&fs_path)?
} else {
fs.lookup(&fs_path)?
fs.lookup_inode(&fs_path)?
}
};
let inode = path_or_inode.inode();
if let Some(uid) = uid {
path.set_owner(uid)?;
inode.set_owner(uid)?;
}
if let Some(gid) = gid {
path.set_group(gid)?;
inode.set_group(gid)?;
}
Ok(SyscallReturn::Return(0))
}

View File

@ -23,14 +23,10 @@ use crate::{
file_handle::FileLike,
file_table::{FdFlags, FileDesc},
pseudofs::anon_inodefs_shared_inode,
utils::{mkmod, CreationFlags, Inode, InodeType, Metadata, StatusFlags},
utils::{CreationFlags, Inode, StatusFlags},
},
prelude::*,
process::{
signal::{PollHandle, Pollable, Pollee},
Gid, Uid,
},
time::clocks::RealTimeClock,
process::signal::{PollHandle, Pollable, Pollee},
};
pub fn sys_eventfd(init_val: u64, ctx: &Context) -> Result<SyscallReturn> {
@ -235,28 +231,6 @@ impl FileLike for EventFile {
Ok(())
}
fn metadata(&self) -> Metadata {
// This is a dummy implementation.
// TODO: Add "anonymous inode fs" and link `EventFile` to it.
let now = RealTimeClock::get().read_time();
Metadata {
dev: 0,
ino: 0,
size: 0,
blk_size: 0,
blocks: 0,
atime: now,
mtime: now,
ctime: now,
type_: InodeType::NamedPipe,
mode: mkmod!(u+w),
nlinks: 1,
uid: Uid::new_root(),
gid: Gid::new_root(),
rdev: 0,
}
}
fn inode(&self) -> &Arc<dyn Inode> {
anon_inodefs_shared_inode()
}

View File

@ -263,7 +263,7 @@ fn from_c_flock_and_file(lock: &c_flock, file: &dyn FileLike) -> Result<FileRang
.checked_add(lock.l_start)
.ok_or(Error::with_message(Errno::EOVERFLOW, "start overflow"))?,
RangeLockWhence::SEEK_END => (file.metadata().size as off_t)
RangeLockWhence::SEEK_END => (file.inode().metadata().size as off_t)
.checked_add(lock.l_start)
.ok_or(Error::with_message(Errno::EOVERFLOW, "start overflow"))?,
}

View File

@ -17,7 +17,7 @@ use crate::{
file_handle::FileLike,
file_table::{get_file_fast, FdFlags, FileDesc},
pseudofs::anon_inodefs_shared_inode,
utils::{mkmod, CreationFlags, Inode, InodeType, Metadata, StatusFlags},
utils::{CreationFlags, Inode, StatusFlags},
},
prelude::*,
process::{
@ -28,9 +28,7 @@ use crate::{
signals::Signal,
HandlePendingSignal, PollHandle, Pollable, Poller,
},
Gid, Uid,
},
time::clocks::RealTimeClock,
};
/// Creates a new signalfd or updates an existing one according to the given mask
@ -260,26 +258,6 @@ impl FileLike for SignalFile {
Ok(())
}
fn metadata(&self) -> Metadata {
let now = RealTimeClock::get().read_time();
Metadata {
dev: 0,
ino: 0,
size: 0,
blk_size: 0,
blocks: 0,
atime: now,
mtime: now,
ctime: now,
type_: InodeType::NamedPipe,
mode: mkmod!(u+r),
nlinks: 1,
uid: Uid::new_root(),
gid: Gid::new_root(),
rdev: 0,
}
}
fn inode(&self) -> &Arc<dyn Inode> {
anon_inodefs_shared_inode()
}

View File

@ -18,7 +18,7 @@ pub fn sys_fstat(fd: FileDesc, stat_buf_ptr: Vaddr, ctx: &Context) -> Result<Sys
let mut file_table = ctx.thread_local.borrow_file_table_mut();
let file = get_file_fast!(&mut file_table, fd);
let stat = Stat::from(file.metadata());
let stat = Stat::from(file.inode().metadata());
ctx.user_space().write_val(stat_buf_ptr, &stat)?;
Ok(SyscallReturn::Return(0))
@ -58,20 +58,20 @@ pub fn sys_fstatat(
return self::sys_fstat(dirfd, stat_buf_ptr, ctx);
}
let path = {
let path_or_inode = {
let filename = filename.to_string_lossy();
let fs_path = FsPath::from_fd_and_path(dirfd, &filename)?;
let fs_ref = ctx.thread_local.borrow_fs();
let fs = fs_ref.resolver().read();
if flags.contains(StatFlags::AT_SYMLINK_NOFOLLOW) {
fs.lookup_no_follow(&fs_path)?
fs.lookup_inode_no_follow(&fs_path)?
} else {
fs.lookup(&fs_path)?
fs.lookup_inode(&fs_path)?
}
};
let stat = Stat::from(path.metadata());
let stat = Stat::from(path_or_inode.inode().metadata());
user_space.write_val(stat_buf_ptr, &stat)?;
Ok(SyscallReturn::Return(0))
}

View File

@ -8,15 +8,12 @@ use crate::{
fs::{
file_handle::FileLike,
pseudofs::anon_inodefs_shared_inode,
utils::{mkmod, CreationFlags, Inode, InodeType, Metadata, StatusFlags},
utils::{CreationFlags, Inode, StatusFlags},
},
prelude::*,
process::{
signal::{PollHandle, Pollable, Pollee},
Gid, Uid,
},
process::signal::{PollHandle, Pollable, Pollee},
syscall::create_timer,
time::{clocks::RealTimeClock, Timer},
time::Timer,
};
/// A file-like object representing a timer that can be used with file descriptors.
@ -153,28 +150,6 @@ impl FileLike for TimerfdFile {
Ok(())
}
fn metadata(&self) -> Metadata {
// This is a dummy implementation.
// TODO: Add "anonymous inode fs" and link the file to it.
let now = RealTimeClock::get().read_time();
Metadata {
dev: 0,
ino: 0,
size: 0,
blk_size: 0,
blocks: 0,
atime: now,
mtime: now,
ctime: now,
type_: InodeType::NamedPipe,
mode: mkmod!(u+w),
nlinks: 1,
uid: Uid::new_root(),
gid: Gid::new_root(),
rdev: 0,
}
}
fn inode(&self) -> &Arc<dyn Inode> {
anon_inodefs_shared_inode()
}

View File

@ -1,6 +1,7 @@
# TODO: Support `fstatfs` syscall for pipe files.
PipeTest.StatFS
# TODO: Support opening pipe files via `/proc/self/fd` path.
Pipes/PipeTest.OpenViaProcSelfFD/pipe
Pipes/PipeTest.OpenViaProcSelfFDWithWrites/pipe
# TODO: Deal with more flags in `pipe2` syscall.
Pipe2Test.*