From f57a54aa0dce4905b70023077a68a0b32cd6ab04 Mon Sep 17 00:00:00 2001 From: Ruihan Li Date: Wed, 12 Nov 2025 17:47:28 +0800 Subject: [PATCH] Remove `AccessMode` from `InodeHandle` --- kernel/src/fs/inode_handle/dyn_cap.rs | 10 +++++----- kernel/src/fs/inode_handle/mod.rs | 18 ++++++------------ kernel/src/fs/utils/access_mode.rs | 16 ++++++++++++++++ 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/kernel/src/fs/inode_handle/dyn_cap.rs b/kernel/src/fs/inode_handle/dyn_cap.rs index 28c26f136..d41070464 100644 --- a/kernel/src/fs/inode_handle/dyn_cap.rs +++ b/kernel/src/fs/inode_handle/dyn_cap.rs @@ -40,13 +40,11 @@ impl InodeHandle { pub fn new_unchecked_access( path: Path, - mut access_mode: AccessMode, + access_mode: AccessMode, status_flags: StatusFlags, ) -> Result { let inode = path.inode(); let (file_io, rights) = if status_flags.contains(StatusFlags::O_PATH) { - // We follow Linux to report O_RDONLY later (e.g., in `/proc/[pid]/fdinfo/[n]`). - access_mode = AccessMode::O_RDONLY; (None, Rights::empty()) } else if inode.type_() == InodeType::Dir && access_mode.is_writable() { return_errno_with_message!(Errno::EISDIR, "a directory cannot be opened writable"); @@ -60,7 +58,6 @@ impl InodeHandle { path, file_io, offset: Mutex::new(0), - access_mode, status_flags: AtomicU32::new(status_flags.bits()), }; Ok(Self(inner, rights)) @@ -133,7 +130,6 @@ impl Pollable for InodeHandle { #[inherit_methods(from = "self.0")] impl FileLike for InodeHandle { fn status_flags(&self) -> StatusFlags; - fn access_mode(&self) -> AccessMode; fn metadata(&self) -> Metadata; fn mode(&self) -> Result; fn set_mode(&self, mode: InodeMode) -> Result<()>; @@ -199,6 +195,10 @@ impl FileLike for InodeHandle { Ok(()) } + fn access_mode(&self) -> AccessMode { + self.1.into() + } + fn seek(&self, seek_from: SeekFrom) -> Result { if self.1.is_empty() { return_errno_with_message!(Errno::EBADF, "the file is opened as a path"); diff --git a/kernel/src/fs/inode_handle/mod.rs b/kernel/src/fs/inode_handle/mod.rs index 86c87a556..305cd2d85 100644 --- a/kernel/src/fs/inode_handle/mod.rs +++ b/kernel/src/fs/inode_handle/mod.rs @@ -15,9 +15,9 @@ use crate::{ file_handle::Mappable, path::Path, utils::{ - AccessMode, DirentVisitor, FallocMode, FileRange, FlockItem, FlockList, Inode, - InodeMode, InodeType, IoctlCmd, Metadata, RangeLockItem, RangeLockList, RangeLockType, - SeekFrom, StatusFlags, OFFSET_MAX, + DirentVisitor, FallocMode, FileRange, FlockItem, FlockList, Inode, InodeMode, + InodeType, IoctlCmd, Metadata, RangeLockItem, RangeLockList, RangeLockType, SeekFrom, + StatusFlags, OFFSET_MAX, }, }, prelude::*, @@ -29,12 +29,11 @@ use crate::{ 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`, - /// `ioctl` will be provided by `file_io`, instead of `path`. + /// `file_io` is similar to the `file_private` field in Linux's `file` structure. If `file_io` + /// is `Some(_)`, typical file operations including `read`, `write`, `poll`, and `ioctl` will + /// be provided by `file_io`, instead of `path`. file_io: Option>, offset: Mutex, - access_mode: AccessMode, status_flags: AtomicU32, } @@ -120,10 +119,6 @@ impl HandleInner { do_resize_util(self.path.inode().as_ref(), self.status_flags(), new_size) } - pub(self) fn access_mode(&self) -> AccessMode { - self.access_mode - } - pub(self) fn status_flags(&self) -> StatusFlags { let bits = self.status_flags.load(Ordering::Relaxed); StatusFlags::from_bits(bits).unwrap() @@ -278,7 +273,6 @@ impl Debug for HandleInner { f.debug_struct("HandleInner") .field("path", &self.path) .field("offset", &self.offset()) - .field("access_mode", &self.access_mode()) .field("status_flags", &self.status_flags()) .finish_non_exhaustive() } diff --git a/kernel/src/fs/utils/access_mode.rs b/kernel/src/fs/utils/access_mode.rs index 82342f603..6404e16c1 100644 --- a/kernel/src/fs/utils/access_mode.rs +++ b/kernel/src/fs/utils/access_mode.rs @@ -38,6 +38,22 @@ impl AccessMode { } } +impl From for AccessMode { + fn from(rights: Rights) -> Self { + match ( + rights.contains(Rights::READ), + rights.contains(Rights::WRITE), + ) { + (true, true) => AccessMode::O_RDWR, + (true, false) => AccessMode::O_RDONLY, + (false, true) => AccessMode::O_WRONLY, + // The file is opened with `O_PATH`. We follow Linux to report `O_RDONLY` here (e.g., + // in `/proc/[pid]/fdinfo/[n]`). + (false, false) => AccessMode::O_RDONLY, + } + } +} + impl From for Rights { fn from(access_mode: AccessMode) -> Rights { match access_mode {