From 722efc62cac52146ef6bba6a3e5f02008c376d75 Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Wed, 12 Nov 2025 17:41:48 +0800 Subject: [PATCH] Remove `inode_handle/static_cap.rs` --- kernel/src/fs/inode_handle/dyn_cap.rs | 62 ++++++++----- kernel/src/fs/inode_handle/mod.rs | 106 +++++++++-------------- kernel/src/fs/inode_handle/static_cap.rs | 27 ------ kernel/src/fs/utils/flock.rs | 11 +-- 4 files changed, 85 insertions(+), 121 deletions(-) delete mode 100644 kernel/src/fs/inode_handle/static_cap.rs diff --git a/kernel/src/fs/inode_handle/dyn_cap.rs b/kernel/src/fs/inode_handle/dyn_cap.rs index c42b775e3..28c26f136 100644 --- a/kernel/src/fs/inode_handle/dyn_cap.rs +++ b/kernel/src/fs/inode_handle/dyn_cap.rs @@ -1,12 +1,31 @@ // SPDX-License-Identifier: MPL-2.0 -use aster_rights::TRights; +use core::sync::atomic::AtomicU32; + +use aster_rights::Rights; use inherit_methods_macro::inherit_methods; -use super::*; -use crate::{fs::file_handle::Mappable, prelude::*, process::signal::Pollable}; +use super::HandleInner; +use crate::{ + events::IoEvents, + fs::{ + file_handle::{FileLike, Mappable}, + path::Path, + utils::{ + AccessMode, DirentVisitor, FallocMode, FlockItem, InodeMode, InodeType, IoctlCmd, + Metadata, RangeLockItem, RangeLockType, SeekFrom, StatusFlags, + }, + }, + prelude::*, + process::{ + signal::{PollHandle, Pollable}, + Gid, Uid, + }, +}; -impl InodeHandle { +pub struct InodeHandle(HandleInner, Rights); + +impl InodeHandle { pub fn new(path: Path, access_mode: AccessMode, status_flags: StatusFlags) -> Result { let inode = path.inode(); if !status_flags.contains(StatusFlags::O_PATH) { @@ -37,26 +56,16 @@ impl InodeHandle { (file_io, rights) }; - let inner = Arc::new(InodeHandle_ { + let inner = HandleInner { path, file_io, offset: Mutex::new(0), access_mode, status_flags: AtomicU32::new(status_flags.bits()), - }); + }; Ok(Self(inner, rights)) } - #[expect(dead_code)] - #[expect(clippy::wrong_self_convention)] - pub fn to_static(self) -> Result> { - let rights = Rights::from_bits(R1::BITS).ok_or(Error::new(Errno::EBADF))?; - if !self.1.contains(rights) { - return_errno_with_message!(Errno::EBADF, "check rights failed"); - } - Ok(InodeHandle(self.0.clone(), R1::new())) - } - pub fn readdir(&self, visitor: &mut dyn DirentVisitor) -> Result { if !self.1.contains(Rights::READ) { return_errno_with_message!(Errno::EBADF, "the file is not opened readable"); @@ -106,21 +115,23 @@ impl InodeHandle { self.0.unlock_flock(self); Ok(()) } -} -impl Clone for InodeHandle { - fn clone(&self) -> Self { - Self(self.0.clone(), self.1) + pub fn path(&self) -> &Path { + &self.0.path + } + + pub fn offset(&self) -> usize { + self.0.offset() } } #[inherit_methods(from = "self.0")] -impl Pollable for InodeHandle { +impl Pollable for InodeHandle { fn poll(&self, mask: IoEvents, poller: Option<&mut PollHandle>) -> IoEvents; } #[inherit_methods(from = "self.0")] -impl FileLike for InodeHandle { +impl FileLike for InodeHandle { fn status_flags(&self) -> StatusFlags; fn access_mode(&self) -> AccessMode; fn metadata(&self) -> Metadata; @@ -202,3 +213,10 @@ impl FileLike for InodeHandle { self.0.fallocate(mode, offset, len) } } + +impl Drop for InodeHandle { + fn drop(&mut self) { + self.0.release_range_locks(); + self.0.unlock_flock(self); + } +} diff --git a/kernel/src/fs/inode_handle/mod.rs b/kernel/src/fs/inode_handle/mod.rs index 04ad43a84..86c87a556 100644 --- a/kernel/src/fs/inode_handle/mod.rs +++ b/kernel/src/fs/inode_handle/mod.rs @@ -1,21 +1,18 @@ // SPDX-License-Identifier: MPL-2.0 -#![expect(unused_variables)] - //! Opened Inode-backed File Handle mod dyn_cap; -mod static_cap; use core::sync::atomic::{AtomicU32, Ordering}; -use aster_rights::Rights; +pub use dyn_cap::InodeHandle; use inherit_methods_macro::inherit_methods; use crate::{ events::IoEvents, fs::{ - file_handle::{FileLike, Mappable}, + file_handle::Mappable, path::Path, utils::{ AccessMode, DirentVisitor, FallocMode, FileRange, FlockItem, FlockList, Inode, @@ -30,10 +27,7 @@ use crate::{ }, }; -#[derive(Debug)] -pub struct InodeHandle(Arc, R); - -struct InodeHandle_ { +struct HandleInner { path: Path, /// `file_io` is Similar to `file_private` field in `file` structure in linux. If /// `file_io` is Some, typical file operations including `read`, `write`, `poll`, @@ -44,8 +38,8 @@ struct InodeHandle_ { status_flags: AtomicU32, } -impl InodeHandle_ { - pub fn read(&self, writer: &mut VmWriter) -> Result { +impl HandleInner { + pub(self) fn read(&self, writer: &mut VmWriter) -> Result { if let Some(ref file_io) = self.file_io { return file_io.read(writer, self.status_flags()); } @@ -62,7 +56,7 @@ impl InodeHandle_ { Ok(len) } - pub fn write(&self, reader: &mut VmReader) -> Result { + pub(self) fn write(&self, reader: &mut VmReader) -> Result { if let Some(ref file_io) = self.file_io { return file_io.write(reader, self.status_flags()); } @@ -83,8 +77,8 @@ impl InodeHandle_ { Ok(len) } - pub fn read_at(&self, offset: usize, writer: &mut VmWriter) -> Result { - if let Some(ref file_io) = self.file_io { + pub(self) fn read_at(&self, offset: usize, writer: &mut VmWriter) -> Result { + if let Some(ref _file_io) = self.file_io { todo!("support read_at for FileIo"); } @@ -95,8 +89,8 @@ impl InodeHandle_ { } } - pub fn write_at(&self, mut offset: usize, reader: &mut VmReader) -> Result { - if let Some(ref file_io) = self.file_io { + pub(self) fn write_at(&self, mut offset: usize, reader: &mut VmReader) -> Result { + if let Some(ref _file_io) = self.file_io { todo!("support write_at for FileIo"); } @@ -113,41 +107,41 @@ impl InodeHandle_ { } } - pub fn seek(&self, pos: SeekFrom) -> Result { + pub(self) fn seek(&self, pos: SeekFrom) -> Result { do_seek_util(self.path.inode().as_ref(), &self.offset, pos) } - pub fn offset(&self) -> usize { + pub(self) fn offset(&self) -> usize { let offset = self.offset.lock(); *offset } - pub fn resize(&self, new_size: usize) -> Result<()> { + pub(self) fn resize(&self, new_size: usize) -> Result<()> { do_resize_util(self.path.inode().as_ref(), self.status_flags(), new_size) } - pub fn access_mode(&self) -> AccessMode { + pub(self) fn access_mode(&self) -> AccessMode { self.access_mode } - pub fn status_flags(&self) -> StatusFlags { + pub(self) fn status_flags(&self) -> StatusFlags { let bits = self.status_flags.load(Ordering::Relaxed); StatusFlags::from_bits(bits).unwrap() } - pub fn set_status_flags(&self, new_status_flags: StatusFlags) { + pub(self) fn set_status_flags(&self, new_status_flags: StatusFlags) { self.status_flags .store(new_status_flags.bits(), Ordering::Relaxed); } - pub fn readdir(&self, visitor: &mut dyn DirentVisitor) -> Result { + pub(self) fn readdir(&self, visitor: &mut dyn DirentVisitor) -> Result { let mut offset = self.offset.lock(); let read_cnt = self.path.inode().readdir_at(*offset, visitor)?; *offset += read_cnt; Ok(read_cnt) } - fn poll(&self, mask: IoEvents, poller: Option<&mut PollHandle>) -> IoEvents { + pub(self) fn poll(&self, mask: IoEvents, poller: Option<&mut PollHandle>) -> IoEvents { if let Some(ref file_io) = self.file_io { return file_io.poll(mask, poller); } @@ -155,7 +149,7 @@ impl InodeHandle_ { self.path.inode().poll(mask, poller) } - fn fallocate(&self, mode: FallocMode, offset: usize, len: usize) -> Result<()> { + pub(self) fn fallocate(&self, mode: FallocMode, offset: usize, len: usize) -> Result<()> { do_fallocate_util( self.path.inode().as_ref(), self.status_flags(), @@ -165,7 +159,7 @@ impl InodeHandle_ { ) } - fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result { + pub(self) fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result { if let Some(ref file_io) = self.file_io { return file_io.ioctl(cmd, arg); } @@ -173,7 +167,7 @@ impl InodeHandle_ { self.path.inode().ioctl(cmd, arg) } - fn mappable(&self) -> Result { + pub(self) fn mappable(&self) -> Result { let inode = self.path.inode(); if inode.page_cache().is_some() { // If the inode has a page cache, it is a file-backed mapping and @@ -188,7 +182,7 @@ impl InodeHandle_ { } } - fn test_range_lock(&self, mut lock: RangeLockItem) -> Result { + pub(self) fn test_range_lock(&self, mut lock: RangeLockItem) -> Result { let Some(extension) = self.path.inode().extension() else { // Range locks are not supported. So nothing is locked. lock.set_type(RangeLockType::Unlock); @@ -205,7 +199,7 @@ impl InodeHandle_ { Ok(req_lock) } - fn set_range_lock(&self, lock: &RangeLockItem, is_nonblocking: bool) -> Result<()> { + pub(self) fn set_range_lock(&self, lock: &RangeLockItem, is_nonblocking: bool) -> Result<()> { if RangeLockType::Unlock == lock.type_() { self.unlock_range_lock(lock); return Ok(()); @@ -224,7 +218,7 @@ impl InodeHandle_ { range_lock_list.set_lock(lock, is_nonblocking) } - fn release_range_locks(&self) { + pub(self) fn release_range_locks(&self) { if self.path.inode().extension().is_none() { return; } @@ -236,7 +230,7 @@ impl InodeHandle_ { self.unlock_range_lock(&range_lock); } - fn unlock_range_lock(&self, lock: &RangeLockItem) { + pub(self) fn unlock_range_lock(&self, lock: &RangeLockItem) { if let Some(extension) = self.path.inode().extension() && let Some(range_lock_list) = extension.get::() { @@ -244,7 +238,7 @@ impl InodeHandle_ { } } - fn set_flock(&self, lock: FlockItem, is_nonblocking: bool) -> Result<()> { + pub(self) fn set_flock(&self, lock: FlockItem, is_nonblocking: bool) -> Result<()> { let Some(extension) = self.path.inode().extension() else { // TODO: Figure out whether flocks are supported on all inodes. warn!("the inode does not have support for flocks; this operation will fail"); @@ -258,7 +252,7 @@ impl InodeHandle_ { flock_list.set_lock(lock, is_nonblocking) } - fn unlock_flock(&self, req_owner: &InodeHandle) { + pub(self) fn unlock_flock(&self, req_owner: &InodeHandle) { if let Some(extension) = self.path.inode().extension() && let Some(flock_list) = extension.get::() { @@ -268,20 +262,20 @@ impl InodeHandle_ { } #[inherit_methods(from = "self.path")] -impl InodeHandle_ { - pub fn size(&self) -> usize; - pub fn metadata(&self) -> Metadata; - pub fn mode(&self) -> Result; - pub fn set_mode(&self, mode: InodeMode) -> Result<()>; - pub fn owner(&self) -> Result; - pub fn set_owner(&self, uid: Uid) -> Result<()>; - pub fn group(&self) -> Result; - pub fn set_group(&self, gid: Gid) -> Result<()>; +impl HandleInner { + pub(self) fn size(&self) -> usize; + pub(self) fn metadata(&self) -> Metadata; + pub(self) fn mode(&self) -> Result; + pub(self) fn set_mode(&self, mode: InodeMode) -> Result<()>; + pub(self) fn owner(&self) -> Result; + pub(self) fn set_owner(&self, uid: Uid) -> Result<()>; + pub(self) fn group(&self) -> Result; + pub(self) fn set_group(&self, gid: Gid) -> Result<()>; } -impl Debug for InodeHandle_ { +impl Debug for HandleInner { fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result { - f.debug_struct("InodeHandle_") + f.debug_struct("HandleInner") .field("path", &self.path) .field("offset", &self.offset()) .field("access_mode", &self.access_mode()) @@ -290,24 +284,6 @@ impl Debug for InodeHandle_ { } } -/// Methods for both dyn and static -impl InodeHandle { - pub fn path(&self) -> &Path { - &self.0.path - } - - pub fn offset(&self) -> usize { - self.0.offset() - } -} - -impl Drop for InodeHandle { - fn drop(&mut self) { - self.0.release_range_locks(); - self.0.unlock_flock(self); - } -} - /// A trait for file-like objects that provide custom I/O operations. /// /// This trait is typically implemented for special files like devices or @@ -315,7 +291,7 @@ impl Drop for InodeHandle { // // TODO: The `status_flags` parameter in `read` and `write` may need to be stored directly // in the `FileIo`. We need further refactoring to find an appropriate way to enable `FileIo` -// to utilize the information in the `InodeHandle_`. +// to utilize the information in the `HandleInner`. pub trait FileIo: Pollable + Send + Sync + 'static { /// Reads data from the file into the given `VmWriter`. fn read(&self, writer: &mut VmWriter, status_flags: StatusFlags) -> Result; @@ -323,12 +299,12 @@ pub trait FileIo: Pollable + Send + Sync + 'static { /// Writes data from the given `VmReader` into the file. fn write(&self, reader: &mut VmReader, status_flags: StatusFlags) -> Result; - /// See [`FileLike::mappable`]. + // See `FileLike::mappable`. fn mappable(&self) -> Result { return_errno_with_message!(Errno::EINVAL, "the file is not mappable"); } - fn ioctl(&self, cmd: IoctlCmd, arg: usize) -> Result { + fn ioctl(&self, _cmd: IoctlCmd, _arg: usize) -> Result { return_errno_with_message!(Errno::ENOTTY, "ioctl is not supported"); } } diff --git a/kernel/src/fs/inode_handle/static_cap.rs b/kernel/src/fs/inode_handle/static_cap.rs deleted file mode 100644 index ba6c2f947..000000000 --- a/kernel/src/fs/inode_handle/static_cap.rs +++ /dev/null @@ -1,27 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 - -use aster_rights::{Read, TRightSet, TRights, Write}; -use aster_rights_proc::require; - -use super::*; -use crate::prelude::*; - -impl InodeHandle> { - #[expect(dead_code)] - #[require(R > Read)] - pub fn read(&self, writer: &mut VmWriter) -> Result { - self.0.read(writer) - } - - #[expect(dead_code)] - #[require(R > Write)] - pub fn write(&self, reader: &mut VmReader) -> Result { - self.0.write(reader) - } - - #[expect(dead_code)] - #[require(R > Read)] - pub fn readdir(&self, visitor: &mut dyn DirentVisitor) -> Result { - self.0.readdir(visitor) - } -} diff --git a/kernel/src/fs/utils/flock.rs b/kernel/src/fs/utils/flock.rs index 9526dbce3..5aa4bfd30 100644 --- a/kernel/src/fs/utils/flock.rs +++ b/kernel/src/fs/utils/flock.rs @@ -163,17 +163,14 @@ impl FlockList { /// If the owner is valid, the lock is removed from the list and all threads waiting for the lock are woken. /// The function does nothing if the owner is not found in the list. /// The function is called when the file is closed or the lock is released. - pub fn unlock(&self, req_owner: &InodeHandle) { - debug!( - "unlock with owner: {:?}", - req_owner as *const InodeHandle - ); + pub fn unlock(&self, req_owner: &InodeHandle) { + debug!("unlock with owner: {:?}", req_owner as *const InodeHandle); let mut list = self.inner.lock(); list.retain(|lock| { if let Some(owner) = lock.owner() { if ptr::eq( - Arc::as_ptr(&owner) as *const InodeHandle, - req_owner as *const InodeHandle, + Arc::as_ptr(&owner) as *const InodeHandle, + req_owner as *const InodeHandle, ) { lock.wake_all(); // Wake all threads waiting for this lock. false // Remove lock from the list.