Add support for chmod, fchmod, fchmodat

This commit is contained in:
LI Qing
2023-07-03 16:14:40 +08:00
committed by Tate, Hongliang Tian
parent 743344e3fc
commit 3600a3a439
14 changed files with 160 additions and 26 deletions

View File

@ -109,7 +109,7 @@ impl FsResolver {
return_errno_with_message!(Errno::EISDIR, "path refers to a directory");
}
if !dir_dentry.vnode().inode_mode().is_writable() {
return_errno_with_message!(Errno::EPERM, "file cannot be created");
return_errno_with_message!(Errno::EACCES, "file cannot be created");
}
let new_dentry = dir_dentry.create(&file_name, InodeType::File, inode_mode)?;
new_dentry

View File

@ -55,26 +55,34 @@ impl<D: DirOps> ProcDir<D> {
impl<D: DirOps + 'static> Inode for ProcDir<D> {
fn len(&self) -> usize {
self.info.metadata().size
self.info.size()
}
fn resize(&self, _new_size: usize) {}
fn metadata(&self) -> Metadata {
self.info.metadata().clone()
self.info.metadata()
}
fn atime(&self) -> Duration {
self.info.metadata().atime
self.info.atime()
}
fn set_atime(&self, _time: Duration) {}
fn set_atime(&self, time: Duration) {
self.info.set_atime(time)
}
fn mtime(&self) -> Duration {
self.info.metadata().mtime
self.info.mtime()
}
fn set_mtime(&self, _time: Duration) {}
fn set_mtime(&self, time: Duration) {
self.info.set_mtime(time)
}
fn set_mode(&self, mode: InodeMode) {
self.info.set_mode(mode)
}
fn create(&self, _name: &str, _type_: InodeType, _mode: InodeMode) -> Result<Arc<dyn Inode>> {
Err(Error::new(Errno::EPERM))

View File

@ -28,26 +28,34 @@ impl<F: FileOps> ProcFile<F> {
impl<F: FileOps + 'static> Inode for ProcFile<F> {
fn len(&self) -> usize {
self.info.metadata().size
self.info.size()
}
fn resize(&self, _new_size: usize) {}
fn metadata(&self) -> Metadata {
self.info.metadata().clone()
self.info.metadata()
}
fn atime(&self) -> Duration {
self.info.metadata().atime
self.info.atime()
}
fn set_atime(&self, _time: Duration) {}
fn set_atime(&self, time: Duration) {
self.info.set_atime(time)
}
fn mtime(&self) -> Duration {
self.info.metadata().mtime
self.info.mtime()
}
fn set_mtime(&self, _time: Duration) {}
fn set_mtime(&self, time: Duration) {
self.info.set_mtime(time)
}
fn set_mode(&self, mode: InodeMode) {
self.info.set_mode(mode)
}
fn read_page(&self, _idx: usize, _frame: &VmFrame) -> Result<()> {
unreachable!()

View File

@ -1,4 +1,6 @@
use crate::fs::utils::{FileSystem, Metadata};
use core::time::Duration;
use crate::fs::utils::{FileSystem, InodeMode, Metadata};
use crate::prelude::*;
use super::ProcFS;
@ -14,7 +16,7 @@ mod file;
mod sym;
struct ProcInodeInfo {
metadata: Metadata,
metadata: RwLock<Metadata>,
fs: Weak<dyn FileSystem>,
is_volatile: bool,
}
@ -22,7 +24,7 @@ struct ProcInodeInfo {
impl ProcInodeInfo {
pub fn new(metadata: Metadata, fs: Weak<dyn FileSystem>, is_volatile: bool) -> Self {
Self {
metadata,
metadata: RwLock::new(metadata),
fs,
is_volatile,
}
@ -32,8 +34,32 @@ impl ProcInodeInfo {
&self.fs
}
pub fn metadata(&self) -> &Metadata {
&self.metadata
pub fn metadata(&self) -> Metadata {
self.metadata.read().clone()
}
pub fn size(&self) -> usize {
self.metadata.read().size
}
pub fn atime(&self) -> Duration {
self.metadata.read().atime
}
pub fn set_atime(&self, time: Duration) {
self.metadata.write().atime = time;
}
pub fn mtime(&self) -> Duration {
self.metadata.read().mtime
}
pub fn set_mtime(&self, time: Duration) {
self.metadata.write().mtime = time;
}
pub fn set_mode(&self, mode: InodeMode) {
self.metadata.write().mode = mode;
}
pub fn is_volatile(&self) -> bool {

View File

@ -28,26 +28,34 @@ impl<S: SymOps> ProcSym<S> {
impl<S: SymOps + 'static> Inode for ProcSym<S> {
fn len(&self) -> usize {
self.info.metadata().size
self.info.size()
}
fn resize(&self, _new_size: usize) {}
fn metadata(&self) -> Metadata {
self.info.metadata().clone()
self.info.metadata()
}
fn atime(&self) -> Duration {
self.info.metadata().atime
self.info.atime()
}
fn set_atime(&self, _time: Duration) {}
fn set_atime(&self, time: Duration) {
self.info.set_atime(time)
}
fn mtime(&self) -> Duration {
self.info.metadata().mtime
self.info.mtime()
}
fn set_mtime(&self, _time: Duration) {}
fn set_mtime(&self, time: Duration) {
self.info.set_mtime(time)
}
fn set_mode(&self, mode: InodeMode) {
self.info.set_mode(mode)
}
fn read_page(&self, _idx: usize, _frame: &VmFrame) -> Result<()> {
Err(Error::new(Errno::EPERM))

View File

@ -394,6 +394,10 @@ impl Inode for RamInode {
self.0.write().metadata.mtime = time;
}
fn set_mode(&self, mode: InodeMode) {
self.0.write().metadata.mode = mode;
}
fn mknod(
&self,
name: &str,

View File

@ -110,6 +110,9 @@ impl Dentry {
if self.vnode.inode_type() != InodeType::Dir {
return_errno!(Errno::ENOTDIR);
}
if !self.vnode.inode_mode().is_executable() {
return_errno!(Errno::EACCES);
}
if name.len() > NAME_MAX {
return_errno!(Errno::ENAMETOOLONG);
}
@ -253,6 +256,11 @@ impl Dentry {
self.vnode.inode_mode()
}
/// Set the inode permission mode
pub fn set_inode_mode(&self, mode: InodeMode) {
self.vnode.set_inode_mode(mode)
}
/// Get the inode length
pub fn inode_len(&self) -> usize {
self.vnode.len()

View File

@ -223,6 +223,8 @@ pub trait Inode: Any + Sync + Send {
fn set_mtime(&self, time: Duration);
fn set_mode(&self, mode: InodeMode);
fn read_page(&self, idx: usize, frame: &VmFrame) -> Result<()> {
Err(Error::new(Errno::EISDIR))
}

View File

@ -218,6 +218,10 @@ impl Vnode {
self.inner.read().inode.metadata().mode
}
pub fn set_inode_mode(&self, mode: InodeMode) {
self.inner.read().inode.set_mode(mode)
}
pub fn len(&self) -> usize {
self.inner.read().inode.len()
}